From 88aab0e2fc9273cd663be8525912c70fb218b3ba Mon Sep 17 00:00:00 2001 From: Srimaniteja Date: Thu, 21 Aug 2025 10:37:31 +0530 Subject: [PATCH 01/22] Cypress spec for wf with datasource (#13539) * added cypress spec for WF with DS * added cypress spec for WF with DS * updated with latest main * added cypress spec for WF with DS * updated data-cy * updated data-cy * updated data-cy * updated data cy * updated data cy * updated spec with review comments * updated data-cy * update spec with layest data-cy changes * update spec with layest data-cy change * updated spec with harperdb * Updated spec based on review comments * Updated spec based on review comments * Updated spec based on review comments * added cypress spec for WF with DS * updated spec with latest data-cy * resolved conflicts * added cypress spec for WF with DS --- .../cypress/constants/selectors/common.js | 4 + .../cypress/constants/selectors/workflows.js | 30 ++ .../cypress/constants/texts/workflows.js | 11 + .../workflows/WorkflowWithDataSource.cy.js | 284 ++++++++++++++++++ .../cypress/support/utils/dataSource.js | 12 +- .../cypress/support/utils/workFlows.js | 147 +++++++++ frontend/ee | 2 +- .../CodeEditor/SingleLineCodeEditor.jsx | 2 +- .../QueryEditors/Restapi/Tabs.jsx | 8 +- .../QueryEditors/Restapi/index.jsx | 12 +- frontend/src/HomePage/BlankPage.jsx | 2 +- frontend/src/HomePage/Folders.jsx | 2 +- frontend/src/HomePage/HomePage.jsx | 8 +- frontend/src/_components/AppModal.jsx | 13 +- frontend/src/_ui/Header/index.jsx | 6 +- .../BaseLeftNavSideBar/BaseLeftNavSideBar.jsx | 3 +- .../modules/common/helpers/cypressHelpers.js | 4 +- 17 files changed, 530 insertions(+), 20 deletions(-) create mode 100644 cypress-tests/cypress/constants/selectors/workflows.js create mode 100644 cypress-tests/cypress/constants/texts/workflows.js create mode 100644 cypress-tests/cypress/e2e/happyPath/workflows/WorkflowWithDataSource.cy.js create mode 100644 cypress-tests/cypress/support/utils/workFlows.js diff --git a/cypress-tests/cypress/constants/selectors/common.js b/cypress-tests/cypress/constants/selectors/common.js index 464d0c3cf1..5cd176186d 100644 --- a/cypress-tests/cypress/constants/selectors/common.js +++ b/cypress-tests/cypress/constants/selectors/common.js @@ -3,6 +3,10 @@ export const cyParamName = (paramName = "") => { }; export const commonSelectors = { + deleteWorkFlowOption: "[data-cy=delete-workflow-card-option]", + globalWorkFlowsIcon: '[data-cy="icon-workflows"]', + createWorkFlowsButton: '[data-cy="+-create-workflow"]', + workFlowNameInputField: '[data-cy="app-name-input"]', toastMessage: ".go3958317564", oldToastMessage: ".go318386747", appSlugAccept: '[data-cy="app-slug-accepted-label"]', diff --git a/cypress-tests/cypress/constants/selectors/workflows.js b/cypress-tests/cypress/constants/selectors/workflows.js new file mode 100644 index 0000000000..8fe2157403 --- /dev/null +++ b/cypress-tests/cypress/constants/selectors/workflows.js @@ -0,0 +1,30 @@ +export const cyParamName = (paramName = "") => { + return String(paramName).toLowerCase().replace(/\s+/g, "-"); +}; + +export const workflowSelector = { + deleteWorkFlowOption: "[data-cy=delete-workflow-card-option]", + globalWorkFlowsIcon: '[data-cy="icon-workflows"]', + createWorkFlowsButton: '[data-cy="create-workflow"]', + workflowsCreateButton: "[data-cy='create-new-workflows-button']", + workflowRunButton: '[data-cy="workflow-run-button"]', + workflowLogs: '[data-cy="Logs"] .text span', + startNode: '[data-cy="start-node"]', + startNodeHandleRight: '[data-cy="start-node-handle-right"]', + optionsColumn: '[data-cy="options-column"]', + runjsInputField: + '[data-cy="runjs-input-field"] .cm-content[contenteditable="true"]', + pgsqlQueryInputField: '[data-cy="query-input-field"]', + parametersInputField: '[data-cy="parameters-input-field"]', + restapiUrlInputField: '[data-cy="url-input-field"]', + workFlowNameInputField: '[data-cy="workflow-name-input"]', + responseNodeOutput: '[data-cy="response1-node-name"]', + + nodeName: (nodeName) => `[data-cy="${cyParamName(nodeName)}-node"]`, + + inputField: (fieldName) => + `[data-cy="${cyParamName(fieldName)}"] .cm-content[contenteditable="true"]`, + + simpleInputField: (fieldName) => `[data-cy="${cyParamName(fieldName)}"]`, + nodeHandleRight: (node) => `[data-cy="${node}-node-handle-right"]`, +}; diff --git a/cypress-tests/cypress/constants/texts/workflows.js b/cypress-tests/cypress/constants/texts/workflows.js new file mode 100644 index 0000000000..335c81cb79 --- /dev/null +++ b/cypress-tests/cypress/constants/texts/workflows.js @@ -0,0 +1,11 @@ +export const workflowsText = { + runjs: "runjs1", + postgresql: "postgresql1", + restapi: "restapi1", + harperdb: "harperdb1", + runjsInputField: "runjs-input-field", + pgsqlQueryInputField: "query-input-field", + harperdbInputField: "sql_query-input-field", + restapiUrlInputField: "url-input-field", + workflowNameInputField: "workflow-name-input", +}; diff --git a/cypress-tests/cypress/e2e/happyPath/workflows/WorkflowWithDataSource.cy.js b/cypress-tests/cypress/e2e/happyPath/workflows/WorkflowWithDataSource.cy.js new file mode 100644 index 0000000000..2cb3649dd9 --- /dev/null +++ b/cypress-tests/cypress/e2e/happyPath/workflows/WorkflowWithDataSource.cy.js @@ -0,0 +1,284 @@ +import { fake } from "Fixtures/fake"; +import { commonSelectors } from "Selectors/common"; +import { postgreSqlSelector } from "Selectors/postgreSql"; +import { postgreSqlText } from "Texts/postgreSql"; +import { deleteWorkflowAndDS } from "Support/utils/dataSource"; +import { dataSourceSelector } from "Selectors/dataSource"; +import { harperDbText } from "Texts/harperDb"; +import { workflowsText } from "Texts/workflows"; +import { workflowSelector } from "Selectors/workflows"; +import { + fillDataSourceTextField, + selectAndAddDataSource, +} from "Support/utils/postgreSql"; + +import { + dataSourceNode, + verifyTextInResponseOutput, + connectNodeToResponse, + createWorkflowApp, + fillStartNodeInput, + deleteWorkflow, + backToWorkFlows, +} from "Support/utils/workFlows"; + +const data = {}; + +describe("Workflows with Datasource", () => { + beforeEach(() => { + cy.apiLogin(); + cy.visit("/"); + data.wfName = fake.lastName.toLowerCase().replaceAll("[^A-Za-z]", ""); + data.dataSourceName = fake.lastName + .toLowerCase() + .replaceAll("[^A-Za-z]", ""); + }); + + it("Creating workflows with runjs and validating execution", () => { + cy.createWorkflowApp(data.wfName); + cy.fillStartNodeInput(); + cy.dataSourceNode("Run JavaScript code"); + + cy.get(workflowSelector.nodeName(workflowsText.runjs)).click({ + force: true, + }); + + cy.get(workflowSelector.inputField(workflowsText.runjsInputField)) + .click({ force: true }) + .realType("return startTrigger.params", { delay: 50 }); + + cy.get("body").click(50, 50); + cy.wait(500); + + cy.connectNodeToResponse(workflowsText.runjs, "return runjs1.data"); + cy.verifyTextInResponseOutput("your value"); + cy.deleteWorkflow(data.wfName); + }); + + it("Creating workflows with postgres and validating execution", () => { + cy.get(commonSelectors.globalDataSourceIcon).click(); + cy.apiCreateGDS( + `${Cypress.env("server_host")}/api/data-sources`, + `cypress-${data.dataSourceName}-manual-pgsql`, + "postgresql", + [ + { key: "connection_type", value: "manual", encrypted: false }, + { key: "host", value: `${Cypress.env("pg_host")}`, encrypted: false }, + { key: "port", value: 5432, encrypted: false }, + { key: "ssl_enabled", value: false, encrypted: false }, + { key: "database", value: "postgres", encrypted: false }, + { key: "ssl_certificate", value: "none", encrypted: false }, + { + key: "username", + value: `${Cypress.env("pg_user")}`, + encrypted: false, + }, + { + key: "password", + value: `${Cypress.env("pg_password")}`, + encrypted: false, + }, + { key: "ca_cert", value: null, encrypted: true }, + { key: "client_key", value: null, encrypted: true }, + { key: "client_cert", value: null, encrypted: true }, + { key: "root_cert", value: null, encrypted: true }, + { key: "connection_string", value: null, encrypted: true }, + ] + ); + cy.get( + dataSourceSelector.dataSourceNameButton( + `cypress-${data.dataSourceName}-manual-pgsql` + ) + ) + .should("be.visible") + .click(); + cy.get(postgreSqlSelector.buttonTestConnection).click(); + cy.get(postgreSqlSelector.textConnectionVerified, { + timeout: 10000, + }).should("have.text", postgreSqlText.labelConnectionVerified); + cy.reload(); + + cy.createWorkflowApp(data.wfName); + cy.fillStartNodeInput(); + cy.dataSourceNode(`cypress-${data.dataSourceName}-manual-pgsql`); + cy.get(workflowSelector.nodeName(workflowsText.postgresql)).click({ + force: true, + }); + + cy.get(workflowSelector.inputField(workflowsText.pgsqlQueryInputField)) + .click({ force: true }) + .clearAndTypeOnCodeMirror("") + .realType( + `SELECT table_name +FROM information_schema.tables +WHERE table_schema = 'public' +AND table_type = 'BASE TABLE';`, + { delay: 50 } + ); + + cy.get("body").click(50, 50); + cy.wait(500); + + cy.connectNodeToResponse( + workflowsText.postgresql, + "return postgresql1.data" + ); + cy.verifyTextInResponseOutput("employees"); + + deleteWorkflowAndDS( + data.wfName, + `cypress-${data.dataSourceName}-manual-pgsql` + ); + }); + + it("Creating workflows with rest-api and validating execution", () => { + cy.get(commonSelectors.globalDataSourceIcon).click(); + cy.apiCreateGDS( + `${Cypress.env("server_host")}/api/data-sources`, + `cypress-${data.dataSourceName}-restapi`, + "restapi", + [ + { key: "url", value: "https://httpbin.org" }, + { key: "auth_type", value: "basic" }, + { key: "grant_type", value: "authorization_code" }, + { key: "add_token_to", value: "header" }, + { key: "header_prefix", value: "Bearer " }, + { key: "access_token_url", value: "" }, + { key: "client_id", value: "" }, + { + key: "client_secret", + encrypted: true, + credential_id: "b044a293-82b4-4381-84fd-d173c86a6a0c", + }, + { key: "audience", value: "" }, + { key: "scopes", value: "read, write" }, + { key: "username", value: "user", encrypted: false }, + { key: "password", value: "pass", encrypted: true }, + { + key: "bearer_token", + encrypted: true, + credential_id: "21caf3cb-dbde-43c7-9f42-77feffb63062", + }, + { key: "auth_url", value: "" }, + { key: "client_auth", value: "header" }, + { key: "headers", value: [["", ""]] }, + { key: "custom_query_params", value: [["", ""]], encrypted: false }, + { key: "custom_auth_params", value: [["", ""]] }, + { + key: "access_token_custom_headers", + value: [["", ""]], + encrypted: false, + }, + { key: "multiple_auth_enabled", value: false, encrypted: false }, + { key: "ssl_certificate", value: "none", encrypted: false }, + { key: "retry_network_errors", value: true, encrypted: false }, + { key: "url_parameters", value: [["", ""]], encrypted: false }, + { key: "tokenData", encrypted: false }, + ] + ); + + cy.createWorkflowApp(data.wfName); + cy.fillStartNodeInput(); + cy.dataSourceNode(`cypress-${data.dataSourceName}-restapi`); + cy.get(workflowSelector.nodeName(workflowsText.restapi)).click({ + force: true, + }); + + cy.get(workflowSelector.inputField(workflowsText.restapiUrlInputField)) + .eq(0) + .click({ force: true }) + .clearAndTypeOnCodeMirror("") + .realType(`http://9.234.17.31:8000/delay/10s`, { delay: 50 }); + + cy.get("body").click(50, 50); + cy.wait(500); + + cy.connectNodeToResponse(workflowsText.restapi, "return restapi1.data"); + cy.verifyTextInResponseOutput(""); + deleteWorkflowAndDS(data.wfName, `cypress-${data.dataSourceName}-restapi`); + }); + + it("Creating workflows with harperdb and validating execution", () => { + const Host = Cypress.env("harperdb_host"); + const Port = Cypress.env("harperdb_port"); + const Username = Cypress.env("harperdb_username"); + const Password = Cypress.env("harperdb_password"); + + cy.get(commonSelectors.globalDataSourceIcon).click(); + cy.installMarketplacePlugin("HarperDB"); + + selectAndAddDataSource( + "databases", + harperDbText.harperDb, + data.dataSourceName + ); + + fillDataSourceTextField( + harperDbText.hostLabel, + harperDbText.hostInputPlaceholder, + Host + ); + + fillDataSourceTextField( + harperDbText.portLabel, + harperDbText.portPlaceholder, + Port + ); + + fillDataSourceTextField( + harperDbText.userNameLabel, + harperDbText.userNamePlaceholder, + Username + ); + + fillDataSourceTextField( + harperDbText.passwordlabel, + harperDbText.passwordPlaceholder, + Password + ); + + cy.get(postgreSqlSelector.buttonTestConnection).click(); + cy.get(postgreSqlSelector.textConnectionVerified, { + timeout: 10000, + }).should("have.text", postgreSqlText.labelConnectionVerified); + + cy.get(postgreSqlSelector.buttonSave) + .verifyVisibleElement("have.text", postgreSqlText.buttonTextSave) + .click(); + + cy.verifyToastMessage( + commonSelectors.toastMessage, + postgreSqlText.toastDSSaved + ); + + cy.createWorkflowApp(data.wfName); + cy.fillStartNodeInput(); + cy.dataSourceNode(`cypress-${data.dataSourceName}-harperdb`); + cy.get(workflowSelector.nodeName(workflowsText.harperdb)).click({ + force: true, + }); + + cy.get('[data-cy$="-select-dropdown"]').click(); + + cy.get(".react-select__menu") + .should("be.visible") + .within(() => { + cy.contains(/sql/i).click(); + }); + + cy.get(workflowSelector.inputField(workflowsText.harperdbInputField)) + .click({ force: true }) + + .click() + .clearAndTypeOnCodeMirror("") + .realType(`SELECT * FROM tooljet_harper.tooljet_table;`, { delay: 50 }); + + cy.get("body").click(50, 50); + cy.wait(500); + + cy.connectNodeToResponse(workflowsText.harperdb, "return harperdb1.data"); + cy.verifyTextInResponseOutput("Test Record 3"); + + deleteWorkflowAndDS(data.wfName, `cypress-${data.dataSourceName}-harperdb`); + }); +}); diff --git a/cypress-tests/cypress/support/utils/dataSource.js b/cypress-tests/cypress/support/utils/dataSource.js index e480fce14d..b4b8af862a 100644 --- a/cypress-tests/cypress/support/utils/dataSource.js +++ b/cypress-tests/cypress/support/utils/dataSource.js @@ -71,6 +71,11 @@ export const deleteAppandDatasourceAfterExecution = ( deleteDatasource(datasourceName); }; +export const deleteWorkflowAndDS = (appName, datasourceName) => { + cy.deleteWorkflow(appName); + deleteDatasource(datasourceName); +}; + export const closeDSModal = () => { cy.get("body").then(($body) => { cy.wait(500); @@ -280,7 +285,12 @@ export const createRestAPIQuery = ( cy.request({ method: "POST", - url: `${Cypress.env("server_host")}/api/data-queries/data-sources/${data_source_id}/versions/${editingVersionId}`, + url: `${Cypress.env( + "server_host" + )}/api/data-queries/data-sources/${data_source_id}/versions/${editingVersionId}`, + url: `${Cypress.env( + "server_host" + )}/api/data-queries/data-sources/${data_source_id}/versions/${editingVersionId}`, headers: headers, body: requestBody, }).then((response) => { diff --git a/cypress-tests/cypress/support/utils/workFlows.js b/cypress-tests/cypress/support/utils/workFlows.js new file mode 100644 index 0000000000..6d02a7e762 --- /dev/null +++ b/cypress-tests/cypress/support/utils/workFlows.js @@ -0,0 +1,147 @@ +import { commonSelectors } from "Selectors/common"; +import { commonText } from "Texts/common"; +import { workflowsText } from "Texts/workflows"; +import { workflowSelector } from "Selectors/workflows"; +import { deleteDatasource } from "Support/utils/dataSource"; + +Cypress.Commands.add("createWorkflowApp", (wfName) => { + cy.get(workflowSelector.globalWorkFlowsIcon).click(); + cy.get(workflowSelector.workflowsCreateButton).click(); + cy.get(workflowSelector.workFlowNameInputField).type(wfName); + cy.get(workflowSelector.createWorkFlowsButton).click(); +}); + +Cypress.Commands.add("fillStartNodeInput", () => { + cy.get(workflowSelector.startNode).click({ force: true }); + + cy.get(workflowSelector.parametersInputField) + .click() + .realType("{") + .realType('"') + .realType("key") + .realType('"') + .realType(":") + .realType('"') + .realType("your value") + .realType('"') + .realType("}"); + + cy.wait(500); + cy.get("body").click(50, 50); + cy.wait(500); +}); + +Cypress.Commands.add("dataSourceNode", (nodeType) => { + cy.get(workflowSelector.startNodeHandleRight).trigger("mousedown", { + button: 0, + force: true, + }); + + cy.get(".react-flow__pane") + .trigger("mousemove", { + clientX: 600, + clientY: 300, + force: true, + }) + .wait(500) + .trigger("mouseup", { force: true }); + + cy.contains(nodeType, { timeout: 5000 }) + .scrollIntoView() + .click({ force: true }); +}); + +Cypress.Commands.add("verifyTextInResponseOutput", (expectedText) => { + cy.get(workflowSelector.workflowRunButton).click(); + cy.get(workflowSelector.workflowLogs).should( + "have.text", + "A few seconds ago" + ); + + cy.get(workflowSelector.responseNodeOutput).click(); + cy.wait(500); + cy.get(workflowSelector.optionsColumn).contains("Output").click(); + + cy.wait(500); + cy.get("body").then(($body) => { + if ( + $body.find("span.node-key").filter((_, el) => el.innerText === "data") + .length + ) { + cy.contains("span.node-key", "data", { timeout: 3000 }) + .click({ force: true }) + .wait(300); + } + }); + + cy.get("body").then(($body) => { + const icons = $body.find("span.json-tree-node-icon"); + if (icons.length > 0) { + cy.wrap(icons).each(($el) => { + if ($el[0].style.transform === "rotate(0deg)") { + cy.wrap($el).click({ force: true }).wait(200); + } + }); + } + }); + + cy.get(".json-tree-valuetype", { timeout: 3000 }).then(($vals) => { + const texts = [...$vals].map((el) => el.innerText.trim()); + const match = texts.some((txt) => txt.includes(expectedText)); + expect( + match, + `Expected some value to include "${expectedText}", but got:\n\n${texts.join("\n")}` + ).to.be.true; + }); +}); + +Cypress.Commands.add("connectNodeToResponse", (nodeTitle, returnStatement) => { + cy.get(workflowSelector.nodeName(nodeTitle)) + .should("exist") + .parents(".react-flow__node") + .as("sourceNode"); + + cy.get(workflowSelector.nodeHandleRight(nodeTitle)).trigger("mousedown", { + button: 0, + force: true, + }); + + cy.get(".react-flow__pane") + .trigger("mousemove", { clientX: 800, clientY: 400, force: true }) + .trigger("mouseup", { force: true }); + + cy.wait(500); + + cy.contains("Response", { timeout: 5000 }).click({ force: true }); + cy.wait(500); + + cy.get(workflowSelector.nodeName("response1")) + .parents(".react-flow__node") + .click({ force: true }); + + cy.get('.cm-content[contenteditable="true"]') + .clearAndTypeOnCodeMirror("") + .clearAndTypeOnCodeMirror("") + .clearAndTypeOnCodeMirror(returnStatement); + + cy.get("body").click(50, 50); + cy.wait(500); +}); + +Cypress.Commands.add("deleteWorkflow", (wfName) => { + cy.intercept("DELETE", "/api/apps/*").as("appDeleted"); + cy.backToWorkFlows(); + cy.get(commonSelectors.appCard(wfName)) + .realHover() + .find(commonSelectors.appCardOptionsButton) + .realHover() + .click(); + cy.get(workflowSelector.deleteWorkFlowOption).click(); + cy.get(commonSelectors.buttonSelector(commonText.modalYesButton)).click(); + cy.wait("@appDeleted"); +}); + +Cypress.Commands.add("backToWorkFlows", () => { + cy.get(commonSelectors.pageLogo).click(); + cy.get(commonSelectors.backToAppOption).click(); +}); diff --git a/frontend/ee b/frontend/ee index 7cfcb38fc1..ca6874f79f 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 7cfcb38fc16571927e5a1445c87b7ed59e83c8e2 +Subproject commit ca6874f79f288a04f694ab42e4b4643f49412744 diff --git a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx index fcc699dad1..416029dbaa 100644 --- a/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx +++ b/frontend/src/AppBuilder/CodeEditor/SingleLineCodeEditor.jsx @@ -430,7 +430,7 @@ const EditorInput = ({
{/* sticky element to position the preview box correctly on top without flowing out of container */} {usePortalEditor && ( diff --git a/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/Tabs.jsx b/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/Tabs.jsx index 948c613ffd..ec10b11f75 100644 --- a/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/Tabs.jsx +++ b/frontend/src/AppBuilder/QueryManager/QueryEditors/Restapi/Tabs.jsx @@ -6,6 +6,7 @@ import Cookies from './TabCookies'; import { Tab, ListGroup, Row } from 'react-bootstrap'; import { CustomToggleSwitch } from '@/Editor/QueryManager/Components/CustomToggleSwitch'; import { ButtonSolid } from '@/_ui/AppButton/AppButton'; +import { generateCypressDataCy } from '@/modules/common/helpers/cypressHelpers'; function ControlledTabs({ options, @@ -29,7 +30,11 @@ function ControlledTabs({
{tabs.map((tab) => ( - + {tab} ))} @@ -91,6 +96,7 @@ function ControlledTabs({ eventKey="body" bsPrefix={`rest-api-tabpanes ${bodyToggle && 'rest-api-tabpanes-body'}`} transition={false} + data-cy="restapi-tab-body-pane" > +
{this.props.selectedDataSource?.scope == 'global' &&
}{' '}
@@ -346,6 +346,7 @@ class Restapi extends React.Component {
{dataSourceURL && ( { @@ -371,13 +373,19 @@ class Restapi extends React.Component { placeholder={dataSourceURL ? 'Enter request endpoint' : 'Enter request URL'} componentName={`${queryName}::url`} lang="javascript" + cyLabel="url" />
-
+
handleFolderChange({})} - data-cy="all-applications-link" + data-cy={`all-${appType === 'workflow' ? 'workflows' : appType === 'module' ? 'modules' : 'applications'}-link`} > {appType === 'module' ? 'All modules' diff --git a/frontend/src/HomePage/HomePage.jsx b/frontend/src/HomePage/HomePage.jsx index c21203ee68..ffa5d67eef 100644 --- a/frontend/src/HomePage/HomePage.jsx +++ b/frontend/src/HomePage/HomePage.jsx @@ -1695,7 +1695,13 @@ class HomePageComponent extends React.Component { showCreateAppModal: true, }) } - data-cy="create-new-app-button" + data-cy={`create-new-${ + this.props.appType === 'workflow' + ? 'workflows' + : this.props.appType === 'module' + ? 'modules' + : 'apps' + }-button`} > <> {isImportingApp && ( diff --git a/frontend/src/_components/AppModal.jsx b/frontend/src/_components/AppModal.jsx index 0003a2cc9f..5f9780aeb7 100644 --- a/frontend/src/_components/AppModal.jsx +++ b/frontend/src/_components/AppModal.jsx @@ -6,6 +6,7 @@ import _, { noop } from 'lodash'; import { validateName } from '@/_helpers/utils'; import { FormWrapper } from './FormWrapper'; import { PluginsListForAppModal } from './PluginsListForAppModal'; +import { generateCypressDataCy } from '@/modules/common/helpers/cypressHelpers'; const APP_TYPE = { WORKFLOW: 'workflow', @@ -148,7 +149,7 @@ export function AppModal({ {isLoading ? actionLoadingButton : actionButton} @@ -164,7 +165,7 @@ export function AppModal({
-
)} -
+
{workflowsEnabled && ( -
  • +
  • Date: Mon, 25 Aug 2025 13:51:02 +0530 Subject: [PATCH 02/22] feat: add release automation workflow for version bump and submodule updates to main branch (#13893) * feat: add release automation workflow for version bump and submodule updates * update email configuration and enhance version file handling in release automation workflow * feat: enhance tagging process for base repo and submodules in release automation --- .github/workflows/merging-pr.yml | 6 +- .github/workflows/release-automation.yml | 395 +++++++++++++++++++++++ 2 files changed, 399 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/release-automation.yml diff --git a/.github/workflows/merging-pr.yml b/.github/workflows/merging-pr.yml index 9f4d4b9fdf..0f34831882 100644 --- a/.github/workflows/merging-pr.yml +++ b/.github/workflows/merging-pr.yml @@ -8,7 +8,8 @@ jobs: merge-submodules: if: | github.event.pull_request.merged == true && - (github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'lts-3.16') + (github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'lts-3.16') && + !startsWith(github.event.pull_request.head.ref, 'release/') runs-on: ubuntu-latest steps: @@ -46,7 +47,8 @@ jobs: needs: merge-submodules if: | github.event.pull_request.merged == true && - (github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'lts-3.16') + (github.event.pull_request.base.ref == 'main' || github.event.pull_request.base.ref == 'lts-3.16') && + !startsWith(github.event.pull_request.head.ref, 'release/') runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release-automation.yml b/.github/workflows/release-automation.yml new file mode 100644 index 0000000000..0006c5d5d3 --- /dev/null +++ b/.github/workflows/release-automation.yml @@ -0,0 +1,395 @@ +name: Release Automation + +on: + pull_request: + types: [closed] + branches: [main] + # Uncomment the line below to also trigger on lts-3.16 branch + # branches: [main, lts-3.16] + +permissions: + contents: write + pull-requests: write + issues: read + +jobs: + release-automation: + if: | + github.event.pull_request.merged == true && + startsWith(github.event.pull_request.head.ref, 'release/') && + contains(github.event.pull_request.title, '|') && + contains(github.event.pull_request.title, '[') && + contains(github.event.pull_request.title, ']') + runs-on: ubuntu-latest + + outputs: + version: ${{ steps.extract-version.outputs.version }} + tag: ${{ steps.create-tag.outputs.tag }} + release_notes: ${{ steps.generate-notes.outputs.release_notes }} + + steps: + - name: Extract Branch Name and Base Branch + run: | + echo "BRANCH_NAME=${{ github.event.pull_request.head.ref }}" >> $GITHUB_ENV + echo "BASE_BRANCH=${{ github.event.pull_request.base.ref }}" >> $GITHUB_ENV + + - name: Merge PR in ee-server (if exists) + run: | + PR=$(gh pr list -R ToolJet/ee-server --head "$BRANCH_NAME" --base "$BASE_BRANCH" --state open --json number -q '.[0].number') + if [ -n "$PR" ]; then + echo "Found ee-server PR: #$PR targeting $BASE_BRANCH" + gh pr merge -R ToolJet/ee-server "$PR" --merge --admin + else + echo "No open ee-server PR for branch $BRANCH_NAME targeting $BASE_BRANCH" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Merge PR in ee-frontend (if exists) + run: | + PR=$(gh pr list -R ToolJet/ee-frontend --head "$BRANCH_NAME" --base "$BASE_BRANCH" --state open --json number -q '.[0].number') + if [ -n "$PR" ]; then + echo "Found ee-frontend PR: #$PR targeting $BASE_BRANCH" + gh pr merge -R ToolJet/ee-frontend "$PR" --merge --admin + else + echo "No open ee-frontend PR for branch $BRANCH_NAME targeting $BASE_BRANCH" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Wait for submodule merges to complete + run: | + echo "Waiting for submodule merges to complete..." + sleep 30 + + - name: Extract Version from PR Title + id: extract-version + run: | + TITLE="${{ github.event.pull_request.title }}" + echo "PR Title: $TITLE" + + # Extract the complete tag from text after | character + if [[ "$TITLE" =~ \|.*\[([^]]+)\] ]]; then + TAG="${BASH_REMATCH[1]}" + echo "Extracted tag: $TAG" + echo "version=$TAG" >> $GITHUB_OUTPUT + else + echo "❌ No valid tag format found in PR title" + echo "Expected format: 'some text | [tag]'" + echo "Examples: 'platform release | [v3.16-beta.1]' or 'hotfix | [v3.16.18-lts]'" + exit 1 + fi + + - name: Checkout Repository + if: steps.extract-version.outputs.version != '' + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + submodules: recursive + + - name: Configure Git + run: | + git config user.name "GitHub Actions Bot" + git config user.email "adish.madhu@gmail.com" + + - name: Create Version Bump Branch + id: create-branch + run: | + TAG="${{ steps.extract-version.outputs.version }}" + # Create branch name using tag without special characters + CLEAN_TAG=$(echo "$TAG" | sed 's/[^a-zA-Z0-9.-]//g') + BRANCH_NAME="version-bump-$CLEAN_TAG-$(date +%s)" + echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT + git checkout -b "$BRANCH_NAME" + + - name: Update Version Files + run: | + TAG="${{ steps.extract-version.outputs.version }}" + # Remove 'v' prefix for .version files if present + VERSION="${TAG#v}" + + # Update all three .version files + echo "$VERSION" > .version + echo "$VERSION" > server/.version + echo "$VERSION" > frontend/.version + + echo "Updated all .version files to: $VERSION (from tag: $TAG)" + echo "Files updated:" + echo " - ./.version" + echo " - ./server/.version" + echo " - ./frontend/.version" + + + - name: Update Submodules to Latest + run: | + echo "Updating submodules to latest commits..." + + # Determine which branch to use for submodules + BASE_BRANCH="${{ github.event.pull_request.base.ref }}" + + # For main branch, use main in submodules + # For lts-3.16 branch, use lts-3.16 in submodules (when enabled) + if [ "$BASE_BRANCH" = "lts-3.16" ]; then + SUBMODULE_BRANCH="lts-3.16" + else + SUBMODULE_BRANCH="main" + fi + + echo "Base branch: $BASE_BRANCH" + echo "Using submodule branch: $SUBMODULE_BRANCH" + + # Get latest commit SHAs from submodule repositories + echo "Fetching latest commit from ToolJet/ee-frontend:$SUBMODULE_BRANCH" + FRONTEND_SHA=$(gh api repos/ToolJet/ee-frontend/branches/$SUBMODULE_BRANCH --jq '.commit.sha' || gh api repos/ToolJet/ee-frontend/branches/main --jq '.commit.sha') + echo "Frontend SHA: $FRONTEND_SHA" + + echo "Fetching latest commit from ToolJet/ee-server:$SUBMODULE_BRANCH" + SERVER_SHA=$(gh api repos/ToolJet/ee-server/branches/$SUBMODULE_BRANCH --jq '.commit.sha' || gh api repos/ToolJet/ee-server/branches/main --jq '.commit.sha') + echo "Server SHA: $SERVER_SHA" + + # Update submodule pointers to specific commit SHAs + cd frontend/ee + git fetch origin + git checkout "$FRONTEND_SHA" + cd ../.. + + cd server/ee + git fetch origin + git checkout "$SERVER_SHA" + cd ../.. + + # Check if there are any changes + if ! git diff --quiet .version server/.version frontend/.version frontend/ee server/ee; then + echo "Changes detected in version files and/or submodules" + else + echo "No changes detected" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Commit Changes + run: | + TAG="${{ steps.extract-version.outputs.version }}" + VERSION="${TAG#v}" # Remove 'v' prefix for display + git add .version server/.version frontend/.version frontend/ee server/ee + + # Only commit if there are changes + if ! git diff --cached --quiet; then + git commit -m "Version bump to $TAG + + - Update .version files to $VERSION + - Update submodules to latest commit SHA + + else + echo "No changes to commit" + fi + + - name: Create Version Bump PR + id: create-pr + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ steps.create-branch.outputs.branch_name }} + title: "Version bump to ${{ steps.extract-version.outputs.version }}" + body: | + ## Version Bump to ${{ steps.extract-version.outputs.version }} + + This PR updates the version files and submodules for the release version ${{ steps.extract-version.outputs.version }}. + + ### Changes: + - ✅ Updated `.version` files (root, server, frontend) to `${{ steps.extract-version.outputs.version }}` + - ✅ Updated submodules to latest commits + + ### Auto-generated + This PR was automatically created by the release automation workflow. + + base: ${{ github.event.pull_request.base.ref }} + # When lts-3.16 is enabled, this will use the correct base branch + + - name: Auto-merge Version Bump PR + if: steps.create-pr.outputs.pull-request-number != '' + run: | + PR_NUMBER="${{ steps.create-pr.outputs.pull-request-number }}" + echo "Auto-merging version bump PR #$PR_NUMBER" + + # Wait a moment for PR to be fully created + sleep 10 + + # Merge the PR + gh pr merge "$PR_NUMBER" --squash --admin + + # Wait for merge to complete + sleep 10 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout Updated Base Branch + run: | + BASE_BRANCH="${{ github.event.pull_request.base.ref }}" + git fetch origin "$BASE_BRANCH" + git checkout "$BASE_BRANCH" + git pull origin "$BASE_BRANCH" + + - name: Create Git Tag + id: create-tag + run: | + TAG="${{ steps.extract-version.outputs.version }}" + BASE_BRANCH="${{ github.event.pull_request.base.ref }}" + + # Determine correct branch for tag creation based on tag type + if [[ "$TAG" == *"lts"* ]]; then + TARGET_BRANCH="lts-3.16" + echo "LTS tag detected - creating tag from lts-3.16 branch" + elif [[ "$TAG" == *"beta"* ]]; then + TARGET_BRANCH="main" + echo "Beta tag detected - creating tag from main branch" + else + # Default to the base branch of the PR + TARGET_BRANCH="$BASE_BRANCH" + echo "Using PR base branch: $TARGET_BRANCH" + fi + + echo "Creating tag: $TAG from branch: $TARGET_BRANCH in base repo and submodules" + + # Ensure we're on the correct branch and it's up to date + git fetch origin "$TARGET_BRANCH" + git checkout "$TARGET_BRANCH" + git pull origin "$TARGET_BRANCH" + + # Create and push the tag in the base repository + echo "Creating tag in base repository..." + git tag -a "$TAG" -m "Release $TAG" + git push origin "$TAG" + + # Create tags in submodules + echo "Creating tag in ee-frontend submodule..." + cd frontend/ee + git fetch origin + if [[ "$TAG" == *"lts"* ]]; then + git checkout lts-3.16 2>/dev/null || git checkout main + else + git checkout main + fi + git pull origin HEAD + git tag -a "$TAG" -m "Release $TAG" + git push origin "$TAG" + cd ../.. + + echo "Creating tag in ee-server submodule..." + cd server/ee + git fetch origin + if [[ "$TAG" == *"lts"* ]]; then + git checkout lts-3.16 2>/dev/null || git checkout main + else + git checkout main + fi + git pull origin HEAD + git tag -a "$TAG" -m "Release $TAG" + git push origin "$TAG" + cd ../.. + + echo "Tags created successfully in all repositories" + echo "tag=$TAG" >> $GITHUB_OUTPUT + + - name: Generate Release Notes + id: generate-notes + run: | + TAG="${{ steps.extract-version.outputs.version }}" + + # Get the previous tag + PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") + + echo "Current tag: $TAG" + echo "Previous tag: $PREVIOUS_TAG" + + # Generate release notes using GitHub's auto-generation + BASE_BRANCH="${{ github.event.pull_request.base.ref }}" + if [ -n "$PREVIOUS_TAG" ]; then + NOTES=$(gh api --method POST /repos/ToolJet/ToolJet/releases/generate-notes \ + -f tag_name="$TAG" \ + -f previous_tag_name="$PREVIOUS_TAG" \ + -f target_commitish="$BASE_BRANCH" \ + --jq '.body') + else + NOTES="Initial release version $TAG" + fi + + # Set multiline output + { + echo 'release_notes<> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Send Slack Notification + if: steps.generate-notes.outputs.release_notes != '' + run: | + TAG="${{ steps.extract-version.outputs.version }}" + REPO_URL="https://github.com/ToolJet/ToolJet/releases/tag/$TAG" + + # Create simplified Slack message + SLACK_MESSAGE="🚀 New Release: $TAG + + Tag: $TAG + + A new release has been created and is ready for testing. + + Release: $REPO_URL + + Please test thoroughly before promotion." + + # Send to Slack (using webhook URL from secrets) + if [ -n "${{ secrets.SLACK_WEBHOOK_URL }}" ]; then + curl -X POST -H 'Content-type: application/json' \ + --data "{\"text\":\"$SLACK_MESSAGE\"}" \ + "${{ secrets.SLACK_WEBHOOK_URL }}" + echo "✅ Slack notification sent successfully" + else + echo "⚠️ SLACK_WEBHOOK_URL secret not configured - skipping notification" + fi + + - name: Create GitHub Release + if: steps.create-tag.outputs.tag != '' + run: | + TAG="${{ steps.create-tag.outputs.tag }}" + + # Determine if this is a pre-release based on tag content + if [[ "$TAG" == *"beta"* ]]; then + PRERELEASE_FLAG="--prerelease" + NOTES_PREFIX="Pre-release version $TAG for testing purposes." + elif [[ "$TAG" == *"lts"* ]]; then + PRERELEASE_FLAG="" + NOTES_PREFIX="LTS release version $TAG." + else + PRERELEASE_FLAG="--prerelease" + NOTES_PREFIX="Release version $TAG." + fi + + gh release create "$TAG" \ + --title "Release $TAG" \ + --generate-notes \ + $PRERELEASE_FLAG \ + --notes "$NOTES_PREFIX Please test thoroughly before promotion." + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Summary + run: | + echo "## 🎉 Release Automation Complete!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### ✅ Completed Tasks:" >> $GITHUB_STEP_SUMMARY + echo "- [x] Extracted version: \`${{ steps.extract-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY + echo "- [x] Updated .version file" >> $GITHUB_STEP_SUMMARY + echo "- [x] Updated submodules to latest commits" >> $GITHUB_STEP_SUMMARY + echo "- [x] Created and merged version bump PR" >> $GITHUB_STEP_SUMMARY + echo "- [x] Created git tag: \`${{ steps.create-tag.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY + echo "- [x] Generated release notes" >> $GITHUB_STEP_SUMMARY + echo "- [x] Sent Slack notification" >> $GITHUB_STEP_SUMMARY + echo "- [x] Created GitHub release" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### 🔗 Links:" >> $GITHUB_STEP_SUMMARY + echo "- [Tag](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ steps.create-tag.outputs.tag }})" >> $GITHUB_STEP_SUMMARY + echo "- [Release](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ steps.create-tag.outputs.tag }})" >> $GITHUB_STEP_SUMMARY \ No newline at end of file From 188a4bbe01d95d4dfdb17f1157c86d976b61c2a2 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Mon, 25 Aug 2025 13:52:33 +0530 Subject: [PATCH 03/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#13916)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/ee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/ee b/frontend/ee index ca6874f79f..7cfcb38fc1 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit ca6874f79f288a04f694ab42e4b4643f49412744 +Subproject commit 7cfcb38fc16571927e5a1445c87b7ed59e83c8e2 From dc65cf0a262d523f4a469e1ba91b8fe506befad3 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:50:00 +0530 Subject: [PATCH 04/22] Modify security audit for frontend and remove cypress checks (#13967) Updated the security audit step to target the frontend directory and removed the cypress audit checks. --- .github/workflows/vulnerability-ci.yml | 111 +------------------------ 1 file changed, 1 insertion(+), 110 deletions(-) diff --git a/.github/workflows/vulnerability-ci.yml b/.github/workflows/vulnerability-ci.yml index ca8c525ace..17d1493e31 100644 --- a/.github/workflows/vulnerability-ci.yml +++ b/.github/workflows/vulnerability-ci.yml @@ -33,7 +33,7 @@ jobs: run: npm --prefix frontend install - name: Running security audit - run: npm --prefix server audit --json > Periodic-frontend-audit.json + run: npm --prefix frontend audit --json > Periodic-frontend-audit.json continue-on-error: true - name: Parse audit summary @@ -218,57 +218,6 @@ jobs: curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }} - PeriodicVulnerability-CheckOn-cypress-code: - if: github.event_name == 'schedule' - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - ref: refs/heads/main - - - name: Use Node.js 22.15.1 - uses: actions/setup-node@v3 - with: - node-version: 22.15.1 - - - name: Install dependencies - run: npm --prefix cypress-tests install - - - name: Running security audit - run: npm --prefix cypress-tests audit --json > Periodic-cypress-audit.json - continue-on-error: true - - - name: Parse audit summary - id: parse-audit - run: | - vulnerabilities=$(jq '.metadata.vulnerabilities' Periodic-cypress-audit.json) - moderate=$(echo $vulnerabilities | jq '.moderate') - high=$(echo $vulnerabilities | jq '.high') - critical=$(echo $vulnerabilities | jq '.critical') - echo "::set-output name=moderate::$moderate" - echo "::set-output name=high::$high" - echo "::set-output name=critical::$critical" - - - name: Upload audit report - uses: actions/upload-artifact@v4 - with: - name: Periodic-cypress-audit-report - path: Periodic-cypress-audit.json - - - name: Send Slack Notification - run: | - message="Periodic Security Audit Report Of Cypress directory\n - Node module vulnerabilities summary:\n - 🔴 Critical: ${{ steps.parse-audit.outputs.critical }}\n - 🟠 High: ${{ steps.parse-audit.outputs.high }}\n - 🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }}\n - \nDownload Audit Report: http://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - - curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" ${{ secrets.SLACK_WEBHOOK_URL_VUR }} - - PeriodicVulnerability-CheckOn-root-code: if: github.event_name == 'schedule' runs-on: ubuntu-latest @@ -538,64 +487,6 @@ jobs: Please find the JSON file in the [summary page](${{ github.plugins_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). - - - ManualVulnerability-CheckOn-cypress-code: - if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'cypress-vulnerability' || github.event.label.name == 'check-vulnerability') }} - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.ref }} - - - name: Use Node.js 22.15.1 - uses: actions/setup-node@v3 - with: - node-version: 22.15.1 - - - name: Install dependencies - run: npm --prefix cypress-tests install - - - name: Running security audit - run: npm --prefix cypress-tests audit --json > cypress-audit.json - continue-on-error: true - - - name: Parse audit summary - id: parse-audit - run: | - vulnerabilities=$(jq '.metadata.vulnerabilities' cypress-audit.json) - moderate=$(echo $vulnerabilities | jq '.moderate') - high=$(echo $vulnerabilities | jq '.high') - critical=$(echo $vulnerabilities | jq '.critical') - echo "::set-output name=moderate::$moderate" - echo "::set-output name=high::$high" - echo "::set-output name=critical::$critical" - - - name: Upload audit report - uses: actions/upload-artifact@v4 - with: - name: cypress-audit-report - path: cypress-audit.json - - - name: Create or update PR comment - uses: peter-evans/create-or-update-comment@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ github.repository }} - issue-number: ${{ github.event.pull_request.number }} - body: | - ### Security Audit Report Of Cypress directory - **Node module vulnerabilities summary:** - 🔴 Critical: ${{ steps.parse-audit.outputs.critical }} - 🟠 High: ${{ steps.parse-audit.outputs.high }} - 🟡 Moderate: ${{ steps.parse-audit.outputs.moderate }} - - Please find the JSON file in the [summary page](${{ github.cypress_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). - - - ManualVulnerability-CheckOn-root-code: if: ${{ github.event.action == 'labeled' && (github.event.label.name == 'root-vulnerability' || github.event.label.name == 'check-vulnerability') }} runs-on: ubuntu-latest From d446fd8b984e2c3a69302cbaaadd6e420ba519f2 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Thu, 22 Jan 2026 12:07:10 +0530 Subject: [PATCH 05/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15044)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> --- frontend/ee | 2 +- server/ee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/ee b/frontend/ee index 3ac76fe3f7..33df96293f 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 3ac76fe3f7af176015ea603e9ff770bf24179ebc +Subproject commit 33df96293f1621058ba6207e8992088f9168f595 diff --git a/server/ee b/server/ee index 7b8a4b544b..3312230f74 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit 7b8a4b544bc1aadcdb663319395fe295f521e4d8 +Subproject commit 3312230f74d5b0310195093b3d25df5418730bd3 From b21dc95a5614311cca9c0f5572f2b3b935529348 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Thu, 22 Jan 2026 12:08:09 +0530 Subject: [PATCH 06/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15045)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> From 9fb8fc505bef7bc998e3a3fbdb522ae1fb1cc571 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Fri, 20 Feb 2026 22:34:38 +0530 Subject: [PATCH 07/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15325)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> --- frontend/ee | 2 +- server/ee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/ee b/frontend/ee index 33df96293f..2a21dc5fa3 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 33df96293f1621058ba6207e8992088f9168f595 +Subproject commit 2a21dc5fa3c3706c3efb85082da2d41f749ee6cf diff --git a/server/ee b/server/ee index 3312230f74..fda51bc8a4 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit 3312230f74d5b0310195093b3d25df5418730bd3 +Subproject commit fda51bc8a43d3019158dde608882f29b3d076e02 From 37109d242cffcd7ce0d74fadf315b87e4e4b8adc Mon Sep 17 00:00:00 2001 From: Midhun G S Date: Fri, 20 Feb 2026 23:55:01 +0530 Subject: [PATCH 08/22] Feature - Gitsync with multi branch (#15326) * added app_versions fields * added data migration for backward compatibility * added ce specific logic * fixed ce migration (need to dev-test) * moved to data migration * migration changes * added endpoint to create draft version * backend changes * added draft to app_import scenario * added version description * minor changes (needs improvement) * fixed breaking dropdown in editor * updated submodule commits * revert package.json * revert ui not used changes * submodule changes * reverting non used files * ui changes * ui changes * ui changes * ui changes * ui changes * copywriting changes * ui changes * ui changes * edit version modal changes * ui integration changes * added button solid and removed unused css * removed commented code from create version modal * updated button size to use large * ui changes * draft version modal changes * added sub-module commits to main * draft version endpoint changes * ui changes for draft version modal * fix breaking ui * ui changes for banner * minor ui changes * remove scss changes from themes file * removed unused components (cleanup) * removed unused components (pr cleanup) * draft version changes * create version modal changes * canvas banner fixes * comment creation logic * refactor: version dropdown * update endpoint changes * fix: promote logic * update submodule * fix: released version and create version modal * fix draft version creation * minor ui changes * minor backend fixes * tooltip changes * added all components in same folder * added minor comments * import fixes * refactor files * fix: overlay issues * fix: on version creation * fix ce bugs * bug fixes * bug fixes * bug fixes * add migrations * splitting changes for import export * minor fixes * draft version of adapter for import -export * git sync minor changes * removed updatedAt from data queries * bug fixes * backend changes * made field optional * added get all branch endpoint (pending to test) * migration changes * branch creation endpoint and dto changes * app_version util service changes * fixed version type changes * branching related changes * chore: Update submodule hash * added logic to allow only single draft version for branching feature * added default value as true for branching * added feature keys * minor changes * minor changes * minor fixes * initial branching support * minor changes * added created by field in app_versions table * minor changes * branching api fixes * bug fixes * minor fix * fix: auto-commit during version creation * chore: update frontend submodule hash * pull changes * fix: include organisationId in fetchPr * chore: update server submodule hash * minor fix (pending to dev test) * scss changes * remove git sync css from themes file * minor change * fix styling * fix: add copy-writing for main branch lockedbanner * chore: update frontend submodule hash * fix: version listing * chore: Update server submodule hash * fix banner lock * base merge * chore: update frontend submodule hash * fix: version listing * merge base * fix: add new prop in AppGitPushDto * chore: update frontend & server submodule hash * fix: auto-commit on promoting the default branch * fix: dropdown states * fix: dropdown states * fix: hide pull commit button from promoted environments * fix: enhance git sync handling for draft versions and improve version creation logic * fix: remove unnecessary whitespace in VersionManagerDropdown component * freeze state fixes * fix: correctly read branch author * chore: update frontend and backend submodule * fixes * fix: atomic changes during branch creation * fix: error propagation * fixed freeze state * refactor methods * submodule update * fix: update autoCommit default state and disable checkbox in CreateBranchModal; remove tooltips in LifecycleCTAButton * feat: enhance BranchDropdown and LifecycleCTAButton; update icons and styles; add Check2 icon * minor fixes * feat: update BranchDropdown to always show Create PR button; enhance CreateBranchModal to refresh versions and include releasedVersionId; improve CreateDraftVersionModal to refresh versions after creating a draft * chore: update subproject commit reference in server/ee * feat: enhance CreateDraftVersionModal to improve version selection logic and add debugging logs * chore: update server submodule * chore: update subproject commit reference in frontend/ee * update submodule * update submodule * chore: comment out import option label in BaseImportAppMenu * ce build fix * fixes * minor fixes * fixes build issues * Git Sync Phase2 Changes (#14886) * Feature: Adding co-relation-id mapping (#14621) * feat: add migration for co_relation_id column * minor cleanup * added entities and dummy util file * fix: Add co-relation column for events * fixed compilation issues * added fields * minor changes * added timestamp cleanups * modified existing migration t * minor updates in co_relation id changes * fix: update migration script * feat: map co-relation-id during pull * chore: update server submodule * fixed layout co_relation id issue * fixed migration changes * revert * timestamp fixes * minor fixes * minor fix * chore: update server submodule (#14755) --------- Co-authored-by: rohanlahori * resolved merge conflicts * fixed app crashing * Feature/version tagging (#14903) * feat: add migration for co_relation_id column * minor cleanup * added entities and dummy util file * fix: Add co-relation column for events * fixed compilation issues * added fields * minor changes * added timestamp cleanups * modified existing migration t * minor updates in co_relation id changes * fix: update migration script * feat: map co-relation-id during pull * chore: update server submodule * fixed layout co_relation id issue * fixed migration changes * revert * timestamp fixes * minor fixes * minor fix * added migration * minor changes * migration fix * dto changes * fixes * feature: api call for github tags post saving version * chore: update frontend & server submodule hash * fix for sub-branch pull * minor fix * feat: send message in api call * chore: update frontend & server submodule hash * chore: update frontend submodule hash * chore: update frontend submodule hash * minor fixes in import flow * fix: remove await from createGit tag * chore: Update server & frontend submodule hash * save version before committing * removed all logs * removed unused console logs * removed logs * fixes * minor fixes * fixes * removed commit changes flow from draft versions * version id fix * minor fixes * added latest changes endpoint using app Name * co_relation_id fix * added co_relation id changes * fixed co_relation id import issue * minor ui fix * fixes for tag flow * version tag fixes * submodule commits --------- Co-authored-by: parthy007 * fixed appId issue * commented not used entity field * minor co_relation_id fix * auto-commit on app creation changes * normalize(folder-apps): enforce single folder per app using created_at * Changed message * feat: enhance branch and version management UI with improved styles and functionality * Toast message copywritin * git sync related things * feat: Add tooljet folder architecture to gitsync * fix: remove autocommit on app creation * chore: Update server and frontend submodules * git sync apps & folder restriction * chore: Update server and frontend submodules * fix: restrict app rename * feat: Add version dropdown on app import * chore: Update server submodule hash * moved some logic to util.service.ts * fix branch dropdown and draft button status * feat: Support saved version import on app name change * chore: Update server & frontend submodule hash * chore: Update server and frontend server submodule * fix: add flag to skip folder check * chore: Update server and frontend submodules * chore: Update frontend submodule hash * chore: Update frontend & server submodule hash * fix: version name in version dropdown of import modal * fix: sub module * chore: update server and frontend submodule hashes * fix: send correct version name * fix: retriggering of renaming listner * chore: Update frontend & server submodule hash * fix: latest commit on pull tab * rebase submodule * fix imported app version status * remove draft tag on version dropdown in modal * version desc. optional & app removel message & empty version push err message * fix: restrict app rename without draft version * chore: Update frontend & server submodule hash * fix: latest commit on pull modal * fixed the folder success toast (#15272) * fix: git commit on version creation * fix commit button states on valid/invalid license * chore: Update frontend & server submodule hash * fix: pull error text --------- Co-authored-by: Parth <108089718+parthy007@users.noreply.github.com> Co-authored-by: parthy007 Co-authored-by: Pratush Co-authored-by: Vijaykant Yadav Co-authored-by: Pratush Co-authored-by: YuktiGoyal02 <100783212+YuktiGoyal02@users.noreply.github.com> --------- Co-authored-by: rohanlahori Co-authored-by: Vijaykant Yadav Co-authored-by: parthy007 Co-authored-by: Rohan Lahori <64496391+rohanlahori@users.noreply.github.com> Co-authored-by: Parth <108089718+parthy007@users.noreply.github.com> Co-authored-by: Pratush Co-authored-by: Pratush Co-authored-by: YuktiGoyal02 <100783212+YuktiGoyal02@users.noreply.github.com> --- .../cypress/constants/texts/common.js | 4 +- .../src/AppBuilder/AppCanvas/AppCanvas.jsx | 6 +- .../src/AppBuilder/Header/BranchDropdown.jsx | 717 ++++++++++ .../AppBuilder/Header/CreateBranchModal.jsx | 396 ++++++ .../Header/CreateDraftVersionModal.jsx | 57 +- .../AppBuilder/Header/CreateVersionModal.jsx | 47 +- .../Header/DraftVersionWarningModal.jsx | 66 + .../src/AppBuilder/Header/EditAppName.jsx | 29 +- .../src/AppBuilder/Header/EditorHeader.jsx | 21 +- .../AppBuilder/Header/LifecycleCTAButton.jsx | 96 ++ .../AppBuilder/Header/LockedBranchBanner.jsx | 53 + .../RightTopHeaderButtons.jsx | 16 +- .../AppBuilder/Header/SwitchBranchModal.jsx | 269 ++++ .../VersionManager/CreateDraftButton.jsx | 9 +- .../VersionManager/VersionManagerDropdown.jsx | 31 +- .../VersionManager/environment-toggle.scss | 84 +- .../Header/VersionManager/style.scss | 17 +- .../version-switcher-button.scss | 2 +- .../AppBuilder/_stores/slices/branchSlice.js | 565 ++++++++ .../slices/environmentsAndVersionsSlice.js | 45 +- .../AppBuilder/_stores/slices/gitSyncSlice.js | 17 +- frontend/src/AppBuilder/_stores/store.js | 2 + frontend/src/HomePage/HomePage.jsx | 258 +++- frontend/src/_components/AppModal.jsx | 42 +- frontend/src/_services/appVersion.service.js | 11 +- frontend/src/_services/git_sync.service.js | 143 +- .../_stores/environmentsAndVersionsStore.js | 18 +- frontend/src/_stores/versionManagerStore.js | 4 + frontend/src/_styles/branch-dropdown.scss | 1153 +++++++++++++++++ frontend/src/_styles/create-branch-modal.scss | 574 ++++++++ .../_styles/draft-version-warning-modal.scss | 158 +++ .../src/_styles/locked-branch-banner.scss | 78 ++ frontend/src/_styles/pages-sidebar.scss | 346 ++--- frontend/src/_styles/switch-branch-modal.scss | 225 ++++ frontend/src/_styles/theme.scss | 141 -- frontend/src/_styles/versions.scss | 7 +- frontend/src/_ui/Icon/solidIcons/Check2.jsx | 23 + .../_ui/Icon/solidIcons/ChevronDownSmall.jsx | 16 + .../src/_ui/Icon/solidIcons/CircleDot.jsx | 16 + frontend/src/_ui/Icon/solidIcons/Commit.jsx | 22 + .../_ui/Icon/solidIcons/ExternalLinkIcon.jsx | 28 + .../src/_ui/Icon/solidIcons/GitBranch.jsx | 19 + .../src/_ui/Icon/solidIcons/GitMergeIcon.jsx | 21 + .../src/_ui/Icon/solidIcons/LockClosed.jsx | 19 + frontend/src/_ui/Icon/solidIcons/PlusIcon.jsx | 19 + frontend/src/_ui/Icon/solidIcons/Refresh.jsx | 21 + .../src/_ui/Icon/solidIcons/RocketIcon.jsx | 33 + frontend/src/_ui/Icon/solidIcons/index.js | 33 + .../PromoteConfirmationModal.jsx | 1 + ...FolderAppsKeepFirstCreatedMappingPerApp.ts | 30 + ...43997765065-AddCoRelationIdToComponents.ts | 13 + ...ddBranchingAndSchemaVersionToOrgGitSync.ts | 28 + .../1761828800001-AddVersionTypeColumn.ts | 24 + ...1762860937123-AddCreatedByToAppVersions.ts | 30 + ...3549159927-AddCoRelationIdToAppEntities.ts | 39 + ...1765630548010-AddSourceTagToAppVersions.ts | 24 + .../1768289065973-AddCoRelationIdToApps.ts | 13 + server/src/dto/organization_git.dto.ts | 13 +- server/src/entities/app.entity.ts | 3 + server/src/entities/app_version.entity.ts | 24 + server/src/entities/component.entity.ts | 3 + server/src/entities/data_query.entity.ts | 3 + server/src/entities/data_source.entity.ts | 3 + .../entities/data_source_options.entity.ts | 3 + server/src/entities/event_handler.entity.ts | 3 + server/src/entities/internal_table.entity.ts | 3 + server/src/entities/layout.entity.ts | 3 + .../entities/organization_git_sync.entity.ts | 6 + server/src/entities/page.entity.ts | 3 + .../src/modules/app-environments/service.ts | 3 +- server/src/modules/app-git/ability/index.ts | 5 + .../src/modules/app-git/constants/feature.ts | 16 + server/src/modules/app-git/constants/index.ts | 5 + server/src/modules/app-git/dto/index.ts | 69 +- server/src/modules/app-git/module.ts | 6 +- server/src/modules/app-git/types/index.ts | 4 + server/src/modules/apps/module.ts | 3 +- server/src/modules/apps/service.ts | 27 +- .../services/app-import-export.service.ts | 402 +++++- server/src/modules/apps/util.service.ts | 42 +- server/src/modules/folder-apps/service.ts | 33 +- .../src/modules/folder-apps/util.service.ts | 66 +- server/src/modules/folders/service.ts | 61 +- server/src/modules/folders/util.service.ts | 36 + .../modules/git-sync/base-git-util.service.ts | 9 +- server/src/modules/git-sync/dto/index.ts | 6 - .../src/modules/git-sync/git-sync-adapter.ts | 3 + server/src/modules/git-sync/module.ts | 5 + .../modules/group-permissions/repository.ts | 3 +- .../import-export-resources/service.ts | 6 +- server/src/modules/modules/module.ts | 2 + server/src/modules/versions/dto/index.ts | 7 + .../modules/versions/find-relations.util.ts | 212 +++ server/src/modules/versions/module.ts | 2 + server/src/modules/versions/repository.ts | 10 + server/src/modules/versions/service.ts | 89 +- .../versions/services/create.service.ts | 19 +- server/src/modules/versions/util.service.ts | 153 ++- server/src/modules/workflows/module.ts | 24 +- 99 files changed, 6808 insertions(+), 769 deletions(-) create mode 100644 frontend/src/AppBuilder/Header/BranchDropdown.jsx create mode 100644 frontend/src/AppBuilder/Header/CreateBranchModal.jsx create mode 100644 frontend/src/AppBuilder/Header/DraftVersionWarningModal.jsx create mode 100644 frontend/src/AppBuilder/Header/LifecycleCTAButton.jsx create mode 100644 frontend/src/AppBuilder/Header/LockedBranchBanner.jsx create mode 100644 frontend/src/AppBuilder/Header/SwitchBranchModal.jsx create mode 100644 frontend/src/AppBuilder/_stores/slices/branchSlice.js create mode 100644 frontend/src/_styles/branch-dropdown.scss create mode 100644 frontend/src/_styles/create-branch-modal.scss create mode 100644 frontend/src/_styles/draft-version-warning-modal.scss create mode 100644 frontend/src/_styles/locked-branch-banner.scss create mode 100644 frontend/src/_styles/switch-branch-modal.scss create mode 100644 frontend/src/_ui/Icon/solidIcons/Check2.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/ChevronDownSmall.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/CircleDot.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/Commit.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/ExternalLinkIcon.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/GitBranch.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/GitMergeIcon.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/LockClosed.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/PlusIcon.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/Refresh.jsx create mode 100644 frontend/src/_ui/Icon/solidIcons/RocketIcon.jsx create mode 100644 server/data-migrations/1769151383974-NormalizeFolderAppsKeepFirstCreatedMappingPerApp.ts create mode 100644 server/migrations/1743997765065-AddCoRelationIdToComponents.ts create mode 100644 server/migrations/1761828716101-AddBranchingAndSchemaVersionToOrgGitSync.ts create mode 100644 server/migrations/1761828800001-AddVersionTypeColumn.ts create mode 100644 server/migrations/1762860937123-AddCreatedByToAppVersions.ts create mode 100644 server/migrations/1763549159927-AddCoRelationIdToAppEntities.ts create mode 100644 server/migrations/1765630548010-AddSourceTagToAppVersions.ts create mode 100644 server/migrations/1768289065973-AddCoRelationIdToApps.ts create mode 100644 server/src/modules/git-sync/git-sync-adapter.ts create mode 100644 server/src/modules/versions/find-relations.util.ts diff --git a/cypress-tests/cypress/constants/texts/common.js b/cypress-tests/cypress/constants/texts/common.js index f39142b713..ab5c35b533 100644 --- a/cypress-tests/cypress/constants/texts/common.js +++ b/cypress-tests/cypress/constants/texts/common.js @@ -26,12 +26,12 @@ export const commonText = { cancelButton: "Cancel", folderCreatedToast: "Folder created.", createFolder: "Create folder", - AddedToFolderToast: "Added to folder.", + AddedToFolderToast: "Application added to folder successfully!", appCreatedToast: "App created successfully!", appRenamedToast: "App name has been updated!", appRemovedFromFolderMessage: "The app will be removed from this folder, do you want to continue?", - appRemovedFromFolderTaost: "Removed from folder.", + appRemovedFromFolderTaost: "Application removed from folder successfully!", modalYesButton: "Yes", emptyFolderText: "This folder is empty", allApplicationsLink: "All applications", diff --git a/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx b/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx index df1ab2e924..ff1bd6c2af 100644 --- a/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx +++ b/frontend/src/AppBuilder/AppCanvas/AppCanvas.jsx @@ -110,8 +110,8 @@ export const AppCanvas = ({ appId, switchDarkMode, darkMode }) => { currentMode === 'view' ? computeViewerBackgroundColor(isAppDarkMode, canvasBgColor) : !isAppDarkMode - ? '#EBEBEF' - : '#2F3C4C'; + ? '#EBEBEF' + : '#2F3C4C'; if (isModuleMode) { return { @@ -274,4 +274,4 @@ export const AppCanvas = ({ appId, switchDarkMode, darkMode }) => {
  • ); -}; +}; \ No newline at end of file diff --git a/frontend/src/AppBuilder/Header/BranchDropdown.jsx b/frontend/src/AppBuilder/Header/BranchDropdown.jsx new file mode 100644 index 0000000000..6228cfe93a --- /dev/null +++ b/frontend/src/AppBuilder/Header/BranchDropdown.jsx @@ -0,0 +1,717 @@ +import React, { useState, useRef, useEffect } from 'react'; +import cx from 'classnames'; +import { Overlay, Popover } from 'react-bootstrap'; +import useStore from '@/AppBuilder/_stores/store'; +import SolidIcon from '@/_ui/Icon/SolidIcons'; +import '@/_styles/branch-dropdown.scss'; +import { toast } from 'react-hot-toast'; +import { CreateBranchModal } from './CreateBranchModal'; +import { SwitchBranchModal } from './SwitchBranchModal'; +import { Tooltip } from 'react-tooltip'; +import { gitSyncService } from '@/_services'; +import OverflowTooltip from '@/_components/OverflowTooltip'; +import { AlertTriangle } from 'lucide-react'; + +export function BranchDropdown({ appId, organizationId }) { + const [showDropdown, setShowDropdown] = useState(false); + const [expandedBranches, setExpandedBranches] = useState(new Set()); + const [showCreateModal, setShowCreateModal] = useState(false); + const [showSwitchModal, setShowSwitchModal] = useState(false); + const [activeTab, setActiveTab] = useState('open'); // 'open' or 'closed' + const [lastCommit, setLastCommit] = useState(null); + const [isLoadingCommit, setIsLoadingCommit] = useState(false); + const [hasFetchedPRs, setHasFetchedPRs] = useState(false); // Track if PRs have been fetched + const [hasFetchedBranchInfo, setHasFetchedBranchInfo] = useState(false); // Track if branch info has been fetched + const [isLoadingPRs, setIsLoadingPRs] = useState(false); // Track PR loading state + const dropdownRef = useRef(null); + const buttonRef = useRef(null); + const popoverRef = useRef(null); + + // Helper function to get relative time + const getRelativeTime = (dateString) => { + if (!dateString) return null; + const date = new Date(dateString); + const now = new Date(); + const diffMs = now - date; + const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + + if (diffDays === 0) return 'Updated today'; + if (diffDays === 1) return 'Updated yesterday'; + if (diffDays < 7) return `Updated ${diffDays} days ago`; + if (diffDays < 30) return `Updated ${Math.floor(diffDays / 7)} weeks ago`; + return `Updated ${Math.floor(diffDays / 30)} months ago`; + }; + + // Helper function to format commit date (e.g., "25 Sept, 8:45am") + const formatCommitDate = (dateString) => { + if (!dateString) return 'Unknown date'; + const date = new Date(dateString); + const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec']; + const day = date.getDate(); + const month = months[date.getMonth()]; + let hours = date.getHours(); + const minutes = date.getMinutes(); + const ampm = hours >= 12 ? 'pm' : 'am'; + hours = hours % 12 || 12; + const minutesStr = minutes < 10 ? `0${minutes}` : minutes; + return `${day} ${month}, ${hours}:${minutesStr}${ampm}`; + }; + + // Helper function to check if branch is locked (will be used for branch switching UI later) + const _isBranchLocked = (branch) => { + return branch.is_merged || branch.isMerged || branch.is_released || branch.isReleased; + }; + + // Helper function to build PR creation URL + const buildPRCreationURL = () => { + const defaultBranchName = orgGit?.git_https?.github_branch || orgGit?.git_ssh?.github_branch || 'main'; + const sourceBranch = currentBranchName; + + // Get repository URL from orgGit (check https_url, ssh_url, or repository fields) + const repoUrl = + orgGit?.git_https?.https_url || + orgGit?.git_https?.repository || + orgGit?.git_ssh?.ssh_url || + orgGit?.git_ssh?.repository; + + if (!repoUrl) { + console.error('No repository URL found in orgGit:', orgGit); + return null; + } + + // Extract owner and repo name from URL + // Handles: https://github.com/owner/repo.git, git@github.com:owner/repo.git, etc. + // Updated regex to handle dots in repo names (e.g., git-sync-2.0-repo.git) + const githubMatch = repoUrl.match(/github\.com[:/]([^/]+)\/(.+?)(\.git)?$/); + const gitlabMatch = repoUrl.match(/gitlab\.com[:/]([^/]+)\/(.+?)(\.git)?$/); + const bitbucketMatch = repoUrl.match(/bitbucket\.org[:/]([^/]+)\/(.+?)(\.git)?$/); + + if (githubMatch) { + const [, owner, repo] = githubMatch; + return `https://github.com/${owner}/${repo}/compare/${defaultBranchName}...${sourceBranch}?expand=1`; + } else if (gitlabMatch) { + const [, owner, repo] = gitlabMatch; + return `https://gitlab.com/${owner}/${repo}/-/merge_requests/new?merge_request[source_branch]=${sourceBranch}&merge_request[target_branch]=${defaultBranchName}`; + } else if (bitbucketMatch) { + const [, owner, repo] = bitbucketMatch; + return `https://bitbucket.org/${owner}/${repo}/pull-requests/new?source=${sourceBranch}&dest=${defaultBranchName}`; + } + + console.error('Could not parse repository URL:', repoUrl); + return null; + }; + + // Handle Create PR action + const _handleCreatePR = () => { + const prUrl = buildPRCreationURL(); + if (prUrl) { + window.open(prUrl, '_blank', 'noopener,noreferrer'); + setShowDropdown(false); + } else { + toast.error('Unable to determine repository URL for PR creation'); + } + }; + + // Zustand state + const { + currentBranch, + allBranches, + pullRequests, + branchingEnabled, + fetchBranches, + fetchPullRequests, + fetchDevelopmentVersions, + switchBranch, + switchToDefaultBranch, + setCurrentBranch, + orgGit, + selectedVersion, + } = useStore((state) => ({ + currentBranch: state.currentBranch, + allBranches: state.allBranches, + pullRequests: state.pullRequests, + branchingEnabled: state.branchingEnabled, + fetchBranches: state.fetchBranches, + fetchPullRequests: state.fetchPullRequests, + fetchDevelopmentVersions: state.fetchDevelopmentVersions, + switchBranch: state.switchBranch, + switchToDefaultBranch: state.switchToDefaultBranch, + setCurrentBranch: state.setCurrentBranch, + orgGit: state.orgGit, + selectedVersion: state.selectedVersion, + })); + + const darkMode = localStorage.getItem('darkMode') === 'true' || false; + + // Handle click outside to close dropdown + useEffect(() => { + const handleClickOutside = (event) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { + setShowDropdown(false); + event.stopPropagation(); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, []); + + // Reset commit state when dropdown closes + useEffect(() => { + if (!showDropdown) { + setLastCommit(null); + setIsLoadingCommit(false); + setHasFetchedPRs(false); // Reset PR fetch state when dropdown closes + setHasFetchedBranchInfo(false); // Reset branch info fetch state when dropdown closes + } + }, [showDropdown]); + + // Fetch branches and PRs on mount and when dropdown opens + useEffect(() => { + if (branchingEnabled && appId && organizationId) { + handleRefresh(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [branchingEnabled, appId, organizationId]); + + // Manual fetch last commit function + const fetchLastCommit = async () => { + const currentBranchName = selectedVersion?.name || currentBranch?.name; + const defaultBranchName = orgGit?.git_https?.github_branch || orgGit?.git_ssh?.github_branch || 'main'; + const isOnDefaultBranch = currentBranchName === defaultBranchName; + + // Only fetch commit if on non-default branch + if (!isOnDefaultBranch && currentBranchName && appId && organizationId) { + setIsLoadingCommit(true); + try { + const data = await gitSyncService.checkForUpdates(appId, currentBranchName); + const latestCommit = data?.meta_data?.latest_commit?.[0]; + + if (latestCommit) { + setLastCommit({ + message: latestCommit.message || latestCommit.commitMessage, + author: latestCommit.author || latestCommit.author_name, + date: latestCommit.date || latestCommit.committed_date, + }); + toast.success('Branch info fetched successfully'); + } else { + setLastCommit(null); + toast.info('No commits found for this branch'); + } + setIsLoadingCommit(false); + setHasFetchedBranchInfo(true); // Mark branch info as fetched + } catch (error) { + console.error('Error fetching last commit:', error); + setLastCommit(null); + setIsLoadingCommit(false); + setHasFetchedBranchInfo(true); // Mark as fetched even on error to hide button + // toast.error('Failed to fetch branch info'); + } + } else { + setLastCommit(null); + setIsLoadingCommit(false); + } + }; + + const handleRefresh = async () => { + if (!appId || !organizationId) return; + + setIsLoadingPRs(true); + try { + await Promise.all([ + fetchBranches(appId, organizationId), + fetchPullRequests(appId, organizationId), + fetchDevelopmentVersions(appId), // Fetch development versions for branch switching + ]); + setHasFetchedPRs(true); // Mark PRs as fetched + } catch (error) { + console.error('Error refreshing branches/PRs:', error); + toast.error('Failed to refresh branches'); + } finally { + setIsLoadingPRs(false); + } + }; + + const _handleBranchClick = async (branch) => { + if (branch.name === currentBranch?.name) { + setShowDropdown(false); + return; + } + + try { + // Check if this is the default branch (main/master/etc from config) + const defaultBranchName = orgGit?.git_https?.github_branch || orgGit?.git_ssh?.github_branch || 'main'; + const isDefaultBranch = branch.name === defaultBranchName; + + if (isDefaultBranch) { + // Switch to default branch (finds active draft or latest version) + const result = await switchToDefaultBranch(appId, branch.name); + if (result.success) { + setCurrentBranch(branch); + if (result.isDraft) { + toast.success(`Switched to ${branch.name} - Working on draft version`); + } else { + toast.success(`Switched to ${branch.name}`); + } + setShowDropdown(false); + } else { + toast.error(`Failed to switch to default branch: ${result.error}`); + } + } else { + // Switch to feature branch + const result = await switchBranch(appId, branch.name); + if (result.success) { + setCurrentBranch(branch); + setShowDropdown(false); + } else { + toast.error(`Failed to switch branch: ${result.error}`); + } + } + } catch (error) { + console.error('Error switching branch:', error); + toast.error(error.message || 'Failed to switch branch'); + } + }; + + const _toggleBranchExpand = (branchName) => { + const newExpanded = new Set(expandedBranches); + if (newExpanded.has(branchName)) { + newExpanded.delete(branchName); + } else { + newExpanded.add(branchName); + } + setExpandedBranches(newExpanded); + }; + + const _getPRForBranch = (branchName) => { + return pullRequests.find((pr) => pr.source_branch === branchName || pr.sourceBranch === branchName); + }; + + // Check if current branch is the default branch + const defaultBranchName = orgGit?.git_https?.github_branch || orgGit?.git_ssh?.github_branch || 'main'; + // Use selectedVersion.name as the current branch (ToolJet's version/branch name) + const currentBranchName = selectedVersion?.name || currentBranch?.name; + + // Determine if on default branch: + // - If versionType is 'version', we're on a regular version (show default branch UI) + // - If versionType is 'branch', we're on a feature branch (show branch commit UI) + const isOnDefaultBranch = selectedVersion?.versionType === 'version' || selectedVersion?.versionType !== 'branch'; + + // Display name: show default branch name when on a version, otherwise show current branch name + const displayBranchName = isOnDefaultBranch ? defaultBranchName : currentBranchName; + + // Filter PRs based on active tab + // Check both 'state' and 'status' fields to support different API responses + const openPRs = pullRequests.filter( + (pr) => pr.state?.toLowerCase() === 'open' || pr.status?.toLowerCase() === 'open' + ); + const closedPRs = pullRequests.filter( + (pr) => + pr.state?.toLowerCase() === 'closed' || + pr.status?.toLowerCase() === 'closed' || + (pr.state?.toLowerCase() !== 'open' && pr.status?.toLowerCase() !== 'open') + ); + const displayPRs = activeTab === 'open' ? openPRs : closedPRs; + + // Format PR date + const formatPRDate = (dateString) => { + if (!dateString) return ''; + const date = new Date(dateString); + return date.toLocaleDateString('en-US', { + day: 'numeric', + month: 'short', + hour: '2-digit', + minute: '2-digit', + hour12: true, + }); + }; + + if (!branchingEnabled) { + return null; + } + + const renderPopover = (overlayProps) => ( + + +
    + {/* Current Branch Header */} +
    + {isOnDefaultBranch ? ( + <> +
    + +
    +
    +
    {displayBranchName || 'No branch selected'}
    +
    + Default branch + {(currentBranch?.updatedAt || currentBranch?.updated_at) && ( + <> + + + {getRelativeTime(currentBranch.updatedAt || currentBranch.updated_at)} + + + )} +
    +
    + + ) : ( + <> +
    + +
    +
    +
    {displayBranchName || 'No branch selected'}
    +
    + + Created by {currentBranch?.created_by || currentBranch?.author || 'Unknown'} + + + + {getRelativeTime( + selectedVersion?.createdAt || + selectedVersion?.created_at || + currentBranch?.createdAt || + currentBranch?.created_at + )} + +
    +
    + + )} +
    + + {/* Main Content Area */} + {isOnDefaultBranch ? ( + <> + {/* Fetch PRs Button - Shown at top for default branch, hides after fetching */} + {!hasFetchedPRs && ( +
    + +
    + )} + + {/* PR Tabs and List - Only shown after fetching */} + {hasFetchedPRs && ( + <> + {/* PR Tabs */} +
    + + +
    + + {/* PR List */} +
    + {displayPRs.length === 0 ? ( +
    + +
    +
    + {activeTab === 'open' ? 'There are no open PRs' : 'There are no closed PRs'} +
    +
    + {activeTab === 'open' + ? 'Create a pull request to contribute your changes' + : 'Merge a pull request to contribute your changes'} +
    +
    +
    + ) : ( + displayPRs.map((pr) => ( +
    +
    + +
    +
    + + {pr.title || 'Untitled PR'} + +
    + from {pr.source_branch || pr.sourceBranch} | {formatPRDate(pr.created_at || pr.createdAt)} +
    +
    +
    + )) + )} +
    + + )} + + ) : ( + <> + {/* Fetch Branch Info Button - Only show when not fetched yet */} + {!hasFetchedBranchInfo && ( +
    + +
    + )} + + {/* Latest Commit Section & Empty State - Only show after fetching */} + {hasFetchedBranchInfo && ( + <> + {/* Latest Commit Section - for non-default branches with commits */} + {lastCommit && !isLoadingCommit && ( +
    + {/*
    + LATEST COMMIT +
    */} +
    +
    + +
    +
    +
    {lastCommit.message || 'No message'}
    +
    + By {lastCommit.author || 'Unknown'} | {formatCommitDate(lastCommit.date)} +
    +
    +
    +
    + )} + + {/* Empty state - no commits yet */} + {!lastCommit && !isLoadingCommit && ( +
    + +
    +
    There are no commits yet
    +
    + Commit your changes to create a pull request to contribute them +
    +
    +
    + )} + + {/* Loading state for commit */} + {isLoadingCommit && ( +
    +
    + Loading commit info... +
    + )} + + )} + + )} + + {/* Footer actions */} +
    + {/* Default branch footer: Create branch + Switch branch */} + {isOnDefaultBranch ? ( + <> + + {console.log('BranchDropdown - allBranches:', allBranches, 'length:', allBranches.length) || + (true && allBranches.length > 0 && ( + + ))} + + ) : ( + <> + {/* Feature branch footer: Create PR + Switch branch */} + {/* Always show Create PR button when on sub-branch */} + + {allBranches.length > 0 && ( + + )} + + )} +
    +
    +
    +
    + ); + + return ( + <> +
    + +
    + + setShowDropdown(false)} + popperConfig={{ + modifiers: [ + { + name: 'preventOverflow', + options: { + boundary: 'viewport', + padding: 8, + }, + }, + { + name: 'flip', + options: { + fallbackPlacements: ['bottom-start', 'top-end', 'top-start'], + }, + }, + { + name: 'offset', + options: { + offset: [0, 4], + }, + }, + ], + }} + > + {({ placement: _placement, arrowProps: _arrowProps, show: _show, popper: _popper, ...props }) => ( +
    + {renderPopover(props)} +
    + )} +
    + + {/* Create Branch Modal */} + {showCreateModal && ( + setShowCreateModal(false)} + onSuccess={(newBranch) => { + // Optionally switch to the new branch after creation + if (newBranch) { + setCurrentBranch(newBranch); + } + }} + /> + )} + + {/* Switch Branch Modal */} + {showSwitchModal && ( + setShowSwitchModal(false)} + appId={appId} + organizationId={organizationId} + /> + )} + + {/* Tooltip for PR details */} + {/* Tooltip for PR details */} + + + ); +} diff --git a/frontend/src/AppBuilder/Header/CreateBranchModal.jsx b/frontend/src/AppBuilder/Header/CreateBranchModal.jsx new file mode 100644 index 0000000000..46be9f9d16 --- /dev/null +++ b/frontend/src/AppBuilder/Header/CreateBranchModal.jsx @@ -0,0 +1,396 @@ +import React, { useState, useEffect, useRef } from 'react'; +import useStore from '@/AppBuilder/_stores/store'; +import { useVersionManagerStore } from '@/_stores/versionManagerStore'; +import { toast } from 'react-hot-toast'; +import { ButtonSolid } from '@/_ui/AppButton/AppButton'; +import SolidIcon from '@/_ui/Icon/SolidIcons'; +import { DraftVersionWarningModal } from './DraftVersionWarningModal'; +import { Alert } from '@/_ui/Alert'; +import AlertDialog from '@/_ui/AlertDialog'; +import cx from 'classnames'; +import '@/_styles/create-branch-modal.scss'; + +export function CreateBranchModal({ onClose, onSuccess, appId, organizationId }) { + const [branchName, setBranchName] = useState(''); + const [createFrom, setCreateFrom] = useState(''); + const [autoCommit, setAutoCommit] = useState(true); + const [isCreating, setIsCreating] = useState(false); + const [validationError, setValidationError] = useState(''); + const [showDraftWarning, setShowDraftWarning] = useState(false); + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const dropdownRef = useRef(null); + + const { + allBranches, + isDraftVersionActive, + createBranch, + switchBranch, + fetchBranches, + lazyLoadAppVersions, + fetchDevelopmentVersions, + editingVersion, + currentBranch, + releasedVersionId, + } = useStore((state) => ({ + allBranches: state.allBranches || [], + isDraftVersionActive: state.isDraftVersionActive, + createBranch: state.createBranch, + switchBranch: state.switchBranch, + fetchBranches: state.fetchBranches, + lazyLoadAppVersions: state.lazyLoadAppVersions, + fetchDevelopmentVersions: state.fetchDevelopmentVersions, + editingVersion: state.editingVersion, + currentBranch: state.currentBranch, + releasedVersionId: state.releasedVersionId, + })); + + // Get versions from versionManagerStore + const { versions, fetchVersions } = useVersionManagerStore((state) => ({ + versions: state.versions || [], + fetchVersions: state.fetchVersions, + })); + + // Load versions when modal opens - always refresh to get latest versions + useEffect(() => { + if (appId) { + fetchVersions(appId); + } + }, [appId, fetchVersions]); + + // Close dropdown when clicking outside + useEffect(() => { + const handleClickOutside = (event) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { + setIsDropdownOpen(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, []); + + // Get status badge for version + const getVersionStatusBadge = (version) => { + const status = version.status || ''; + // Use releasedVersionId to determine if version is released (same pattern as VersionDropdownItem) + const isReleased = version.id === releasedVersionId; + + if (status === 'DRAFT') { + return { label: 'Draft', className: 'status-badge-draft' }; + } else if (isReleased) { + return { label: 'Released', className: 'status-badge-released' }; + } + return null; + }; + + // Get parent version name for "Created from" text + const getCreatedFromText = (version) => { + if (version.parentVersionId) { + // Look up the parent version to get its name + const parentVersion = versions.find((v) => v.id === version.parentVersionId); + const parentName = parentVersion?.name || `v${version.parentVersionId}`; + return `Created from ${parentName}`; + } + return version.description || ''; + }; + + const selectedVersion = versions.find((v) => v.id === createFrom); + const selectedBadge = selectedVersion ? getVersionStatusBadge(selectedVersion) : null; + + const validateBranchName = (name) => { + if (!name || name.trim().length === 0) { + return 'Branch name is required'; + } + + // No spaces allowed + if (/\s/.test(name)) { + return 'Branch name cannot contain spaces'; + } + + // Only alphanumeric, hyphens, and underscores + if (!/^[a-zA-Z0-9_-]+$/.test(name)) { + return 'Branch name can only contain letters, numbers, hyphens, and underscores'; + } + + // Check for uniqueness + const existingBranch = allBranches.find((b) => b.name?.toLowerCase() === name.toLowerCase()); + if (existingBranch) { + return 'A branch with this name already exists'; + } + + // Reserved names + const reservedNames = ['main', 'master', 'head', 'origin']; + if (reservedNames.includes(name.toLowerCase())) { + return 'This branch name is reserved'; + } + + return ''; + }; + + const handleBranchNameChange = (e) => { + const newName = e.target.value; + setBranchName(newName); + + // Clear validation error when user starts typing + if (validationError) { + setValidationError(''); + } + }; + + const handleCreateBranch = async () => { + // Validate branch name + const error = validateBranchName(branchName); + if (error) { + setValidationError(error); + return; + } + + setIsCreating(true); + + // Determine the base branch - use current branch name or default to 'main' + const baseBranchName = currentBranch?.name || 'main'; + + const branchData = { + branchName: branchName.trim(), + versionFromId: createFrom, + baseBranch: baseBranchName, + autoCommit: autoCommit, + }; + + try { + const result = await createBranch(appId, organizationId, branchData); + + if (result.success) { + toast.success(`Branch "${branchName}" created successfully`); + + // Refresh branches list and versions BEFORE switching + // This ensures the new branch version is available when we call switchBranch + await Promise.all([ + fetchBranches(appId, organizationId), + lazyLoadAppVersions(appId), + // Also fetch development versions since the new branch is in Development environment + fetchDevelopmentVersions(appId), + ]); + + console.log('CreateBranchModal - versions refreshed, now switching to branch:', branchName.trim()); + + // Switch to the newly created branch (similar to version creation) + try { + const switchResult = await switchBranch(appId, branchName.trim()); + console.log('CreateBranchModal - switchBranch result:', switchResult); + } catch (switchError) { + console.error('Error switching to new branch:', switchError); + toast.error('Branch created but failed to switch to it'); + } + + onSuccess?.(result.data); + onClose(); + } else { + // Handle specific errors + if (result.error === 'DRAFT_EXISTS') { + setShowDraftWarning(true); + } else { + setValidationError(result.error || 'Failed to create branch'); + toast.error(result.error || 'Failed to create branch'); + } + } + } catch (error) { + console.error('Error creating branch:', error); + setValidationError('An unexpected error occurred'); + toast.error('Failed to create branch'); + } finally { + setIsCreating(false); + } + }; + + const handleKeyDown = (e) => { + if (e.key === 'Enter' && !isCreating && !isDropdownOpen) { + handleCreateBranch(); + } else if (e.key === 'Escape' && isDropdownOpen) { + setIsDropdownOpen(false); + } + }; + + // Set default "Create from" on mount + useEffect(() => { + if (versions.length > 0 && !createFrom) { + // Filter to only version-type versions (exclude branches) + const versionTypeVersions = versions.filter((v) => { + const versionType = v.versionType || v.version_type; + return versionType === 'version'; + }); + + if (versionTypeVersions.length === 0) { + return; // No valid versions to select from + } + + // If editingVersion is a version-type, use it; otherwise use first valid version + if (editingVersion?.id) { + const editingVersionType = editingVersion.versionType || editingVersion.version_type; + if (editingVersionType === 'version') { + setCreateFrom(editingVersion.id); + } else { + // Current editing version is a branch, use first version-type version + setCreateFrom(versionTypeVersions[0].id); + } + } else { + setCreateFrom(versionTypeVersions[0].id); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [versions]); + + return ( + <> + +
    + {/* Draft warning message */} + {isDraftVersionActive && ( +
    + + A draft version exists. Commit or discard it before creating a new branch. +
    + )} + + {/* Create from dropdown */} +
    + +
    + + {isDropdownOpen && ( +
    + {versions + .filter((version) => { + // Only show versions with versionType === 'version' (exclude branch-type versions) + const versionType = version.versionType || version.version_type; + return versionType === 'version'; + }) + .map((version) => { + const badge = getVersionStatusBadge(version); + const createdFrom = getCreatedFromText(version); + const isSelected = version.id === createFrom; + + return ( +
    { + setCreateFrom(version.id); + setIsDropdownOpen(false); + }} + > + {isSelected && ( +
    + +
    + )} + {!isSelected &&
    } +
    +
    + {version.name} + {badge && {badge.label}} +
    + {createdFrom &&
    {createdFrom}
    } +
    +
    + ); + })} +
    + )} +
    +
    + + {/* Branch name input */} +
    + + + {validationError &&
    {validationError}
    } +
    Version name must be unique and max 50 characters
    +
    + + {/* Auto-commit checkbox */} +
    + +
    + + {/* Info message about branch creation */} + + Branch can only be created from master + + + {/* Footer buttons */} +
    + + Cancel + + + {'Create branch'} + +
    +
    + + + {/* Draft Version Warning Modal */} + {showDraftWarning && setShowDraftWarning(false)} />} + + ); +} diff --git a/frontend/src/AppBuilder/Header/CreateDraftVersionModal.jsx b/frontend/src/AppBuilder/Header/CreateDraftVersionModal.jsx index f80ba7dce6..a5320f2370 100644 --- a/frontend/src/AppBuilder/Header/CreateDraftVersionModal.jsx +++ b/frontend/src/AppBuilder/Header/CreateDraftVersionModal.jsx @@ -9,20 +9,14 @@ import useStore from '@/AppBuilder/_stores/store'; import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; import { ButtonSolid } from '@/_ui/AppButton/AppButton'; import '../../_styles/version-modal.scss'; +import { useVersionManagerStore } from '@/_stores/versionManagerStore'; -const CreateDraftVersionModal = ({ - showCreateAppVersion, - setShowCreateAppVersion, - handleCommitEnableChange, - canCommit, - orgGit, - fetchingOrgGit, - handleCommitOnVersionCreation = () => { }, -}) => { +const CreateDraftVersionModal = ({ showCreateAppVersion, setShowCreateAppVersion, fetchingOrgGit }) => { const { moduleId } = useModuleContext(); const [isCreatingVersion, setIsCreatingVersion] = useState(false); const [versionName, setVersionName] = useState(''); const [isGitSyncEnabled, setIsGitSyncEnabled] = useState(false); + const refreshVersions = useVersionManagerStore((state) => state.refreshVersions); const { createNewVersionAction, changeEditorVersionAction, @@ -30,6 +24,9 @@ const CreateDraftVersionModal = ({ developmentVersions, appId, selectedVersion, + selectedEnvironment, + orgGit, + appGit, } = useStore( (state) => ({ createNewVersionAction: state.createNewVersionAction, @@ -42,6 +39,8 @@ const CreateDraftVersionModal = ({ appId: state.appStore.modules[moduleId].app.appId, currentVersionId: state.currentVersionId, selectedVersion: state.selectedVersion, + appGit: state.appGit, + orgGit: state.orgGit, }), shallow ); @@ -50,12 +49,11 @@ const CreateDraftVersionModal = ({ const savedVersions = developmentVersions.filter((version) => version.status !== 'DRAFT'); useEffect(() => { const gitSyncEnabled = - orgGit?.git_ssh?.is_enabled || - orgGit?.git_https?.is_enabled || - orgGit?.git_lab?.is_enabled; + appGit?.org_git?.git_ssh?.is_enabled || + appGit?.org_git?.git_https?.is_enabled || + appGit?.org_git?.git_lab?.is_enabled; setIsGitSyncEnabled(gitSyncEnabled); - }, [orgGit]); - + }, [appGit]); const [selectedVersionForCreation, setSelectedVersionForCreation] = useState(null); useEffect(() => { @@ -105,8 +103,8 @@ const CreateDraftVersionModal = ({ savedVersions.length > 0 ? savedVersions.map((version) => ({ label: version.name, value: version.id })) : selectedVersion && selectedVersion.status !== 'DRAFT' - ? [{ label: selectedVersion.name, value: selectedVersion.id }] - : []; + ? [{ label: selectedVersion.name, value: selectedVersion.id }] + : []; const createVersion = () => { if (versionName.trim().length > 25) { @@ -138,14 +136,13 @@ const CreateDraftVersionModal = ({ setShowCreateAppVersion(false); // Refresh development versions to update the list with the new draft fetchDevelopmentVersions(appId); + refreshVersions(appId, selectedEnvironment?.id); // Use changeEditorVersionAction to properly switch to the new draft version // This will update selectedVersion with all fields including status changeEditorVersionAction( appId, newVersion.id, - (data) => { - handleCommitOnVersionCreation(data); - }, + () => {}, (error) => { console.error('Error switching to new draft version:', error); toast.error('Draft created but failed to switch to it'); @@ -253,28 +250,6 @@ const CreateDraftVersionModal = ({
    - - {isGitSyncEnabled && ( -
    -
    - -
    -
    -
    - Commit changes -
    -
    - This will commit the creation of the new version to the git repo -
    -
    -
    - )}
    diff --git a/frontend/src/AppBuilder/Header/CreateVersionModal.jsx b/frontend/src/AppBuilder/Header/CreateVersionModal.jsx index 41b8d13598..d043da3f7c 100644 --- a/frontend/src/AppBuilder/Header/CreateVersionModal.jsx +++ b/frontend/src/AppBuilder/Header/CreateVersionModal.jsx @@ -18,9 +18,10 @@ const CreateVersionModal = ({ canCommit, orgGit, fetchingOrgGit, - handleCommitOnVersionCreation = () => { }, + handleCommitOnVersionCreation, versionId, onVersionCreated, + isBranchingEnabled, }) => { const { moduleId } = useModuleContext(); const setResolvedGlobals = useStore((state) => state.setResolvedGlobals, shallow); @@ -28,6 +29,8 @@ const CreateVersionModal = ({ const [versionName, setVersionName] = useState(''); const [versionDescription, setVersionDescription] = useState(''); const isGitSyncEnabled = orgGit?.git_ssh?.is_enabled || orgGit?.git_https?.is_enabled || orgGit?.git_lab?.is_enabled; + const { current_organization_id } = authenticationService.currentSessionValue; + const { changeEditorVersionAction, environmentChangedAction, @@ -146,12 +149,39 @@ const CreateVersionModal = ({ setIsCreatingVersion(true); try { + // Only call git-related APIs if git sync is enabled await appVersionService.save(appId, selectedVersionForCreation.id, { name: versionName, - description: versionDescription, + description: versionDescription || undefined, // need to add commit changes logic here status: 'PUBLISHED', }); + if (isGitSyncEnabled) { + // The backend's version-rename-commit event is suppressed when the status is + // also changing to PUBLISHED (save-version flow), so there's no competing push. + // We always handle the commit here with the correct "Version Created" message. + const updatedVersionData = { + ...selectedVersionForCreation, + name: versionName, + description: versionDescription, + }; + handleCommitOnVersionCreation(updatedVersionData, selectedVersion) + .then((commitDone) => { + if (!commitDone) return; + if (isBranchingEnabled) { + return gitSyncService.createGitTag( + appId, + selectedVersionForCreation.id, + versionDescription || `Version ${versionName.trim()} created` + ); + } + }) + .catch((error) => { + console.error('Commit or tag failed:', error); + toast.error(error?.data?.message || 'Commit or tag failed'); + }); + } + toast.success('Version Created successfully'); setVersionName(''); setVersionDescription(''); @@ -194,10 +224,7 @@ const CreateVersionModal = ({ changeEditorVersionAction( appId, newVersionData.editing_version.id, - () => { - console.log('Successfully switched environment and version'); - handleCommitOnVersionCreation(newVersionData, selectedVersion); - }, + () => {}, (error) => { console.error('Error switching to newly created version:', error); toast.error('Version created but failed to switch to it'); @@ -210,9 +237,7 @@ const CreateVersionModal = ({ await changeEditorVersionAction( appId, newVersionData.editing_version.id, - () => { - handleCommitOnVersionCreation(newVersionData, selectedVersion); - }, + () => {}, (error) => { console.error('Error switching to newly created version:', error); toast.error('Version created but failed to switch to it'); @@ -229,8 +254,7 @@ const CreateVersionModal = ({ toast.error('Version name already exists.'); } else if (error?.error) { toast.error(error?.error); - } - else { + } else { toast.error('Error while creating version. Please try again.'); } } finally { @@ -333,6 +357,7 @@ const CreateVersionModal = ({ checked={canCommit} type="checkbox" onChange={handleCommitEnableChange} + disabled={isBranchingEnabled} data-cy="git-commit-input" />
    diff --git a/frontend/src/AppBuilder/Header/DraftVersionWarningModal.jsx b/frontend/src/AppBuilder/Header/DraftVersionWarningModal.jsx new file mode 100644 index 0000000000..bf396dd8b4 --- /dev/null +++ b/frontend/src/AppBuilder/Header/DraftVersionWarningModal.jsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { ButtonSolid } from '@/_ui/AppButton/AppButton'; +import SolidIcon from '@/_ui/Icon/SolidIcons'; +import '@/_styles/draft-version-warning-modal.scss'; + +export function DraftVersionWarningModal({ onClose }) { + const handleOverlayClick = (e) => { + if (e.target.classList.contains('draft-warning-modal-overlay')) { + onClose(); + } + }; + + const handleKeyDown = (e) => { + if (e.key === 'Escape') { + onClose(); + } + }; + + React.useEffect(() => { + document.addEventListener('keydown', handleKeyDown); + return () => { + document.removeEventListener('keydown', handleKeyDown); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( +
    +
    +
    +
    + +
    + +
    + +
    +

    Draft Version Exists

    +

    + You cannot create a new branch while a draft version exists. Please commit or discard the current draft + version before creating a new branch. +

    + +
    + +
    + What's a draft version? +

    + A draft version contains uncommitted changes. Only one draft version can exist at a time to prevent + conflicts. +

    +
    +
    +
    + +
    + + Close + +
    +
    +
    + ); +} diff --git a/frontend/src/AppBuilder/Header/EditAppName.jsx b/frontend/src/AppBuilder/Header/EditAppName.jsx index 2dad9e6348..40df8f4b4c 100644 --- a/frontend/src/AppBuilder/Header/EditAppName.jsx +++ b/frontend/src/AppBuilder/Header/EditAppName.jsx @@ -10,16 +10,20 @@ import { PenLine } from 'lucide-react'; function EditAppName() { const { moduleId } = useModuleContext(); - const [appId, appName, setAppName, appCreationMode] = useStore( + const [appId, appName, setAppName, appCreationMode, selectedVersion] = useStore( (state) => [ state.appStore.modules[moduleId].app.appId, state.appStore.modules[moduleId].app.appName, state.setAppName, state.appStore.modules[moduleId].app.creationMode, + state.selectedVersion, ], shallow ); + const isDraftVersion = selectedVersion?.status === 'DRAFT'; + const isRenameDisabled = !isDraftVersion; + const [showRenameModal, setShowRenameModal] = useState(false); const handleRenameApp = async (newAppName, appId) => { @@ -48,12 +52,21 @@ function EditAppName() { return ( <>
    - +
    diff --git a/frontend/src/AppBuilder/Header/EditorHeader.jsx b/frontend/src/AppBuilder/Header/EditorHeader.jsx index d5dafb654e..2151831ba6 100644 --- a/frontend/src/AppBuilder/Header/EditorHeader.jsx +++ b/frontend/src/AppBuilder/Header/EditorHeader.jsx @@ -6,21 +6,25 @@ import LogoNavDropdown from '@/modules/Appbuilder/components/LogoNavDropdown'; import HeaderActions from './HeaderActions'; import { VersionManagerDropdown, VersionManagerErrorBoundary } from './VersionManager'; import useStore from '@/AppBuilder/_stores/store'; -import RightTopHeaderButtons from './RightTopHeaderButtons/RightTopHeaderButtons'; +import RightTopHeaderButtons, { PreviewAndShareIcons } from './RightTopHeaderButtons/RightTopHeaderButtons'; import BuildSuggestions from './BuildSuggestions'; import { ModuleEditorBanner } from '@/modules/Modules/components'; import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; +import { BranchDropdown } from './BranchDropdown'; import './styles/style.scss'; import SaveIndicator from './SaveIndicator'; export const EditorHeader = ({ darkMode }) => { const { moduleId, isModuleEditor } = useModuleContext(); - const { isSaving, saveError, isVersionReleased } = useStore( + const { isSaving, saveError, isVersionReleased, appId, organizationId, selectedVersion } = useStore( (state) => ({ isSaving: state.appStore.modules[moduleId].app.isSaving, saveError: state.appStore.modules[moduleId].app.saveError, isVersionReleased: state.isVersionReleased, + appId: state.appStore.modules[moduleId].app.appId, + organizationId: state.appStore.modules[moduleId].app.organizationId, + selectedVersion: state.selectedVersion, }), shallow ); @@ -51,7 +55,7 @@ export const EditorHeader = ({ darkMode }) => {
    - {isModuleEditor && } + {isModuleEditor && }
    @@ -78,9 +82,14 @@ export const EditorHeader = ({ darkMode }) => {
    {!isModuleEditor && ( <> - - - + + {} + {/* Hide version dropdown when on a feature branch */} + {selectedVersion?.versionType !== 'branch' && ( + + + + )} )} diff --git a/frontend/src/AppBuilder/Header/LifecycleCTAButton.jsx b/frontend/src/AppBuilder/Header/LifecycleCTAButton.jsx new file mode 100644 index 0000000000..dde2b6b7f9 --- /dev/null +++ b/frontend/src/AppBuilder/Header/LifecycleCTAButton.jsx @@ -0,0 +1,96 @@ +import React from 'react'; +import useStore from '@/AppBuilder/_stores/store'; +import { Button } from '@/components/ui/Button/Button'; +import SolidIcon from '@/_ui/Icon/SolidIcons'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; +import { shallow } from 'zustand/shallow'; + +/** + * LifecycleCTAButton - Dynamic button that shows git operations based on branch type + * + * States: + * - Default Branch: "Pull commit" - Opens git sync modal with pull/push tabs + * - Feature Branch: "Commit" - Opens git sync modal to commit changes + */ +const LifecycleCTAButton = () => { + const { moduleId } = useModuleContext(); + + const { selectedVersion, toggleGitSyncModal, creationMode, featureAccess, isEditorFreezed, isGitSyncConfigured } = + useStore( + (state) => ({ + selectedVersion: state.selectedVersion, + toggleGitSyncModal: state.toggleGitSyncModal, + creationMode: state.appStore.modules[moduleId]?.app?.creationMode, + featureAccess: state?.license?.featureAccess, + isEditorFreezed: state.isEditorFreezed, + isGitSyncConfigured: state.isGitSyncConfigured, + }), + shallow + ); + + const isGitSyncEnabled = featureAccess?.gitSync; + + // If git sync is not available in the plan or license is expired, hide completely + if (!isGitSyncEnabled) { + return null; + } + + // Determine if we're on default branch or feature branch + // - versionType === 'version' means default branch + // - versionType === 'branch' means feature branch + const isOnDefaultBranch = selectedVersion?.versionType === 'version' || selectedVersion?.versionType !== 'branch'; + + // Determine button state based on git configuration and branch type + const getButtonConfig = () => { + if (!isGitSyncConfigured) { + // Git is in the plan but not configured in the workspace + return { + label: 'Configure Git', + icon: 'commit', + variant: 'secondary', + disabled: false, + }; + } + + if (isOnDefaultBranch) { + // Default branch - show "Pull commit" button + return { + label: 'Pull commit', + icon: 'commit', + variant: 'secondary', + disabled: false, + }; + } else { + // Feature branch - show "Commit" button + return { + label: 'Commit', + icon: 'commit', + variant: 'secondary', + disabled: false, + }; + } + }; + + const config = getButtonConfig(); + const handleClick = () => { + // Open the git sync modal (which has pull/push tabs) + toggleGitSyncModal(creationMode); + }; + + return ( +
    + +
    + ); +}; + +export default LifecycleCTAButton; diff --git a/frontend/src/AppBuilder/Header/LockedBranchBanner.jsx b/frontend/src/AppBuilder/Header/LockedBranchBanner.jsx new file mode 100644 index 0000000000..47d858c35d --- /dev/null +++ b/frontend/src/AppBuilder/Header/LockedBranchBanner.jsx @@ -0,0 +1,53 @@ +import React from 'react'; +import '@/_styles/locked-branch-banner.scss'; + +/** + * LockedBranchBanner - Displays a full-width warning banner when viewing a read-only branch + * Shows below the editor navigation bar when current branch is locked (merged/released) + * + * @param {boolean} isVisible - Whether to show the banner + * @param {string} branchName - Name of the locked branch + * @param {string} reason - Reason why branch is locked (e.g., "merged", "released") + */ +const LockedBranchBanner = ({ isVisible = false, branchName = '', reason = 'merged' }) => { + if (!isVisible) { + return null; + } + + const reasonText = + reason === 'released' + ? 'This branch has been released and is now read-only' + : reason === 'main_config_branch' + ? `${branchName} is locked. Create a branch to make edits.` + : 'This branch has been merged and is now read-only'; + + return ( +
    +
    + + + +
    + {reasonText} + {branchName && ( + + Branch: {branchName} + + )} +
    +
    +
    + ); +}; + +export default LockedBranchBanner; diff --git a/frontend/src/AppBuilder/Header/RightTopHeaderButtons/RightTopHeaderButtons.jsx b/frontend/src/AppBuilder/Header/RightTopHeaderButtons/RightTopHeaderButtons.jsx index 1f277d2d7e..648bc97369 100644 --- a/frontend/src/AppBuilder/Header/RightTopHeaderButtons/RightTopHeaderButtons.jsx +++ b/frontend/src/AppBuilder/Header/RightTopHeaderButtons/RightTopHeaderButtons.jsx @@ -6,24 +6,34 @@ import { shallow } from 'zustand/shallow'; import queryString from 'query-string'; import { isEmpty } from 'lodash'; import GitSyncManager from '../GitSyncManager'; +import LifecycleCTAButton from '../LifecycleCTAButton'; import useStore from '@/AppBuilder/_stores/store'; import PromoteReleaseButton from '@/modules/Appbuilder/components/PromoteReleaseButton'; import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; const RightTopHeaderButtons = ({ isModuleEditor }) => { + const { selectedVersion, selectedEnvironment } = useStore((state) => ({ + selectedVersion: state.selectedVersion, + selectedEnvironment: state.selectedEnvironment, + })); + + const isNotPromotedOrReleased = selectedEnvironment?.name === 'development' && !selectedVersion?.isReleased; + return (
    - + {/* */} + {isNotPromotedOrReleased && } + {/* need to review if we need this or not */} {/* {!isModuleEditor && } */}
    ); }; -const PreviewAndShareIcons = () => { +export const PreviewAndShareIcons = () => { const { moduleId } = useModuleContext(); const { featureAccess, @@ -73,7 +83,7 @@ const PreviewAndShareIcons = () => { return ( <> -
    +
    {appId && ( ({ + allBranches: state.allBranches, + selectedVersion: state.selectedVersion, + currentBranch: state.currentBranch, + fetchBranches: state.fetchBranches, + switchBranch: state.switchBranch, + switchToDefaultBranch: state.switchToDefaultBranch, + setCurrentBranch: state.setCurrentBranch, + orgGit: state.orgGit, + lazyLoadAppVersions: state.lazyLoadAppVersions, + fetchDevelopmentVersions: state.fetchDevelopmentVersions, + appVersions: state.appVersions, + })); + + const defaultBranchName = orgGit?.git_https?.github_branch || orgGit?.git_ssh?.github_branch || 'main'; + // Determine current branch name: use selectedVersion.name for branches, or default branch name for versions + const currentBranchName = + selectedVersion?.versionType === 'branch' || selectedVersion?.version_type === 'branch' + ? selectedVersion?.name + : selectedVersion?.versionType === 'version' || selectedVersion?.version_type === 'version' + ? defaultBranchName + : currentBranch?.name || defaultBranchName; + + useEffect(() => { + if (show && appId && organizationId) { + setIsLoading(true); + // Fetch branches, versions, and development versions for proper branch switching + Promise.all([ + fetchBranches(appId, organizationId), + lazyLoadAppVersions(appId), + fetchDevelopmentVersions(appId), + ]).finally(() => setIsLoading(false)); + } + }, [show, appId, organizationId, fetchBranches, lazyLoadAppVersions, fetchDevelopmentVersions]); + + // Filter branches: exclude branches that are version names (versionType === 'version') + const filteredBranches = allBranches.filter((branch) => { + // Apply search filter + if (!branch.name.toLowerCase().includes(searchTerm.toLowerCase())) { + return false; + } + + // Check if this branch name corresponds to a version with versionType === 'version' + // If so, exclude it (it's a version name, not an actual branch) + const isVersionName = appVersions?.some( + (v) => v.name === branch.name && (v.versionType === 'version' || v.version_type === 'version') + ); + + // Show the branch only if it's NOT a version name + return !isVersionName; + }); + + const handleBranchClick = async (branch) => { + if (branch.name === currentBranchName) { + onClose(); + return; + } + + try { + // Determine if this is the default branch + const defaultBranchName = orgGit?.git_https?.github_branch || orgGit?.git_ssh?.github_branch || 'main'; + const isDefaultBranch = branch.name === defaultBranchName; + + if (isDefaultBranch) { + // Switch to default branch (finds active draft or latest version) + const result = await switchToDefaultBranch(appId, branch.name); + if (result.success) { + setCurrentBranch(branch); + if (result.isDraft) { + toast.success(`Switched to ${branch.name} - Working on draft version`); + } + onClose(); + } + } else { + // Switch to feature branch + await switchBranch(appId, branch.name); + setCurrentBranch(branch); + onClose(); + } + } catch (error) { + console.error('Error switching branch:', error); + const errorMessage = error?.error || error?.message || 'Failed to switch branch'; + toast.error(errorMessage); + } + }; + + const getRelativeTime = (dateString) => { + if (!dateString) return ''; + const date = new Date(dateString); + const now = new Date(); + const diffMs = now - date; + const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + + if (diffDays === 0) return 'today'; + if (diffDays === 1) return 'yesterday'; + if (diffDays < 7) return `${diffDays} days ago`; + if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`; + return `${Math.floor(diffDays / 30)} months ago`; + }; + + const handleViewInGitRepo = () => { + // Get repository URL from orgGit (check https_url, ssh_url, or repository fields) + const repoUrl = + orgGit?.git_https?.https_url || + orgGit?.git_https?.repository || + orgGit?.git_ssh?.ssh_url || + orgGit?.git_ssh?.repository; + + if (!repoUrl) { + console.error('No repository URL found in orgGit:', orgGit); + toast.error('Git repository URL not available'); + return; + } + + // Extract owner and repo name from URL and construct web URL + // Handles: https://github.com/owner/repo.git, git@github.com:owner/repo.git, etc. + const githubMatch = repoUrl.match(/github\.com[:/]([^/]+)\/(.+?)(\.git)?$/); + const gitlabMatch = repoUrl.match(/gitlab\.com[:/]([^/]+)\/(.+?)(\.git)?$/); + const bitbucketMatch = repoUrl.match(/bitbucket\.org[:/]([^/]+)\/(.+?)(\.git)?$/); + + let webUrl = null; + if (githubMatch) { + const [, owner, repo] = githubMatch; + webUrl = `https://github.com/${owner}/${repo}`; + } else if (gitlabMatch) { + const [, owner, repo] = gitlabMatch; + webUrl = `https://gitlab.com/${owner}/${repo}`; + } else if (bitbucketMatch) { + const [, owner, repo] = bitbucketMatch; + webUrl = `https://bitbucket.org/${owner}/${repo}`; + } else { + // Fallback: try to clean up the URL + webUrl = repoUrl + .replace(/\.git$/, '') + .replace(/^git@/, 'https://') + .replace(/:([^/])/, '/$1'); + } + + if (webUrl) { + window.open(webUrl, '_blank'); + } else { + toast.error('Could not parse repository URL'); + } + }; + + return ( + +
    + {/* Search Section */} +
    + +
    + + setSearchTerm(e.target.value)} + data-cy="branch-search-input" + /> +
    +
    + + {/* Branch List */} +
    + {isLoading ? ( +
    +
    + Loading branches... +
    + ) : filteredBranches.length === 0 ? ( +
    +

    No branches found

    +
    + ) : ( + filteredBranches.map((branch) => { + const isCurrentBranch = branch.name === currentBranchName; + return ( +
    handleBranchClick(branch)} + data-cy={`branch-list-item-${branch.name}`} + > +
    + {isCurrentBranch && } +
    +
    +
    {branch.name}
    +
    + Created by {branch.author || branch.created_by || 'default'},{' '} + {getRelativeTime(branch.createdAt || branch.created_at)} +
    +
    +
    + ); + }) + )} +
    + + {/* Footer Actions */} +
    + + +
    +
    + + {/* Create Branch Modal */} + {showCreateModal && ( + setShowCreateModal(false)} + onSuccess={(newBranch) => { + // Optionally switch to the new branch after creation + if (newBranch) { + setCurrentBranch(newBranch); + onClose(); // Close the switch branch modal too + } + }} + /> + )} +
    + ); +} diff --git a/frontend/src/AppBuilder/Header/VersionManager/CreateDraftButton.jsx b/frontend/src/AppBuilder/Header/VersionManager/CreateDraftButton.jsx index 25f8a9e390..54b6f82719 100644 --- a/frontend/src/AppBuilder/Header/VersionManager/CreateDraftButton.jsx +++ b/frontend/src/AppBuilder/Header/VersionManager/CreateDraftButton.jsx @@ -4,11 +4,16 @@ import { ToolTip } from '@/_components/ToolTip'; import { Button } from '@/components/ui/Button/Button'; import './style.scss'; -const CreateDraftButton = ({ onClick, disabled = false, darkMode = false }) => { +const CreateDraftButton = ({ + onClick, + disabled = false, + darkMode = false, + disabledTooltip = 'Draft version can only be created from saved versions.', +}) => { return (
    { developmentVersions, setSelectedVersion, fetchDevelopmentVersions, + orgGit, } = useStore( (state) => ({ appId: state.appStore.modules[moduleId].app.appId, @@ -48,6 +49,7 @@ const VersionManagerDropdown = ({ darkMode = false, ...props }) => { developmentVersions: state.developmentVersions, fetchDevelopmentVersions: state.fetchDevelopmentVersions, setSelectedVersion: state.setSelectedVersion, + orgGit: state.orgGit, }), shallow ); @@ -122,9 +124,27 @@ const VersionManagerDropdown = ({ darkMode = false, ...props }) => { const hasPublished = versions.some((v) => v.status === 'PUBLISHED'); // Check if there's only one draft and no other saved versions - const draftVersions = developmentVersions.filter((v) => v.status === 'DRAFT'); + // draftVersions are versions of type 'version' (not branches) + const draftVersions = developmentVersions.filter((v) => v.versionType === 'version' && v.status === 'DRAFT'); const savedVersions = developmentVersions.filter((v) => v.status !== 'DRAFT'); - const shouldDisableCreateDraft = draftVersions.length > 0 && savedVersions.length === 0; + const isGitSyncEnabled = orgGit?.git_ssh?.is_enabled || orgGit?.git_https?.is_enabled || orgGit?.git_lab?.is_enabled; + + // Disable create draft logic: + // - Git sync enabled: disable if any draft already exists + // - Git sync disabled: disable if no published versions AND a draft exists (need published version to create from) + const shouldDisableCreateDraft = isGitSyncEnabled + ? draftVersions.length > 0 + : savedVersions.length === 0 && draftVersions.length > 0; + + // Determine tooltip message based on why create draft is disabled + let createDraftDisabledTooltip = ''; + if (shouldDisableCreateDraft) { + if (isGitSyncEnabled) { + createDraftDisabledTooltip = 'Draft version already exists.'; + } else if (savedVersions.length === 0) { + createDraftDisabledTooltip = 'Draft version can only be created from saved versions.'; + } + } // Helper to close dropdown and reset UI state const closeDropdown = () => { @@ -352,7 +372,12 @@ const VersionManagerDropdown = ({ darkMode = false, ...props }) => { {/* Divider */}
    - + ); diff --git a/frontend/src/AppBuilder/Header/VersionManager/environment-toggle.scss b/frontend/src/AppBuilder/Header/VersionManager/environment-toggle.scss index 89dc886ac6..747da75990 100644 --- a/frontend/src/AppBuilder/Header/VersionManager/environment-toggle.scss +++ b/frontend/src/AppBuilder/Header/VersionManager/environment-toggle.scss @@ -1,51 +1,51 @@ .environment-toggle { - padding: 8px; + padding: 8px; - .environment-toggle__bar { - display: flex; - align-items: center; - background-color: var(--slate3); - border-radius: 6px; - padding: 2px; - justify-content: space-around; - gap: 4px; + .environment-toggle__bar { + display: flex; + align-items: center; + background-color: var(--slate3); + border-radius: 6px; + padding: 2px; + justify-content: space-around; + gap: 4px; - .environment-toggle__btn { - padding: 6px 12px !important; - border: none; - border-radius: 4px !important; - background-color: transparent; - color: var(--text-placeholder); - font-weight: 400; - transition: all 0.12s ease; - cursor: pointer; - box-shadow: none; - display: inline-flex; - align-items: center; - justify-content: center; - outline: none !important; + .environment-toggle__btn { + padding: 6px 12px !important; + border: none; + border-radius: 4px !important; + background-color: transparent; + color: var(--text-placeholder); + font-weight: 400; + transition: all 0.12s ease; + cursor: pointer; + box-shadow: none; + display: inline-flex; + align-items: center; + justify-content: center; + outline: none !important; - &:hover:not(.disabled) { - background-color: var(--interactive-hover); - color: var(--text-default); - } + &:hover:not(.disabled) { + background-color: var(--interactive-hover); + color: var(--text-default); + } - &.selected { - background-color: var(--background-surface-layer-01); - color: var(--text-default); - font-weight: 500; - box-shadow: var(--elevation-100-box-shadow); - } + &.selected { + background-color: var(--background-surface-layer-01); + color: var(--text-default); + font-weight: 500; + box-shadow: var(--elevation-100-box-shadow); + } - &.disabled { - cursor: not-allowed; - color: var(--text-disabled); - pointer-events: none; - } - } - } + &.disabled { + cursor: not-allowed; + color: var(--text-disabled); + pointer-events: none; + } + } + } } .environment-toggle__btn.btn { - min-width: 0; -} + min-width: 0; +} \ No newline at end of file diff --git a/frontend/src/AppBuilder/Header/VersionManager/style.scss b/frontend/src/AppBuilder/Header/VersionManager/style.scss index 11c8a933c9..912ccbbe1b 100644 --- a/frontend/src/AppBuilder/Header/VersionManager/style.scss +++ b/frontend/src/AppBuilder/Header/VersionManager/style.scss @@ -6,6 +6,7 @@ } .versions-list { + // Custom scrollbar styling &::-webkit-scrollbar { width: 6px; @@ -299,6 +300,7 @@ opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: translateY(0); @@ -306,10 +308,12 @@ } @keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } @@ -323,13 +327,16 @@ .version-item-skeleton { animation: pulse 1.5s ease-in-out infinite; - > div { + >div { pointer-events: none; } } -.create-draft-button-tooltip{ -display: flex; -.tooltip-inner{ - width: 323px !important; + +.create-draft-button-tooltip { + display: flex; + + .tooltip-inner { + max-width: 323px !important; + width: auto !important; } } \ No newline at end of file diff --git a/frontend/src/AppBuilder/Header/VersionManager/version-switcher-button.scss b/frontend/src/AppBuilder/Header/VersionManager/version-switcher-button.scss index ea194a96e4..55e493f13d 100644 --- a/frontend/src/AppBuilder/Header/VersionManager/version-switcher-button.scss +++ b/frontend/src/AppBuilder/Header/VersionManager/version-switcher-button.scss @@ -82,4 +82,4 @@ text-overflow: ellipsis; white-space: nowrap; } -} +} \ No newline at end of file diff --git a/frontend/src/AppBuilder/_stores/slices/branchSlice.js b/frontend/src/AppBuilder/_stores/slices/branchSlice.js new file mode 100644 index 0000000000..21b16dca0d --- /dev/null +++ b/frontend/src/AppBuilder/_stores/slices/branchSlice.js @@ -0,0 +1,565 @@ +import { gitSyncService } from '@/_services'; +import useStore from '@/AppBuilder/_stores/store'; + +const initialState = { + currentBranch: null, + allBranches: [], + pullRequests: [], + branchingEnabled: false, + isDraftVersionActive: false, + isLoadingBranches: false, + isLoadingPRs: false, + branchError: null, +}; + +export const createBranchSlice = (set, get) => ({ + ...initialState, + + /** + * Fetch all branches for the current app + * @param {string} appId - Application ID + * @param {string} organizationId - Organization ID + */ + fetchBranches: async (appId, organizationId) => { + set(() => ({ isLoadingBranches: true, branchError: null }), false, 'fetchBranches:start'); + + try { + const response = await gitSyncService.getAllBranches(appId, organizationId); + const branches = response?.branches || []; + + // Only set default branch if current version is a branch type + // If selectedVersion is a regular version (not a branch), keep currentBranch as null + const selectedVersion = useStore.getState().selectedVersion; + const isOnBranch = selectedVersion?.versionType === 'branch' || selectedVersion?.version_type === 'branch'; + + let defaultBranch = get().currentBranch; + if (isOnBranch) { + const matchingBranch = branches.find((b) => b.name === selectedVersion.name); + if (matchingBranch) { + defaultBranch = matchingBranch; + } else if (!defaultBranch && branches.length) { + defaultBranch = + branches.find((b) => b.name === 'main') || branches.find((b) => b.name === 'master') || branches[0]; + } + } + + set( + () => ({ + allBranches: branches, + isLoadingBranches: false, + currentBranch: isOnBranch ? defaultBranch || null : null, + }), + false, + 'fetchBranches:success' + ); + + return { success: true, branches }; + } catch (error) { + console.error('Error fetching branches:', error); + set( + () => ({ + isLoadingBranches: false, + branchError: error.message || 'Failed to fetch branches', + }), + false, + 'fetchBranches:error' + ); + + return { success: false, error: error.message }; + } + }, + + /** + * Create a new branch + * @param {string} appId - Application ID + * @param {string} organizationId - Organization ID + * @param {object} branchData - { branchName, versionFromId, baseBranch, autoCommit } + */ + createBranch: async (appId, organizationId, branchData) => { + set(() => ({ branchError: null }), false, 'createBranch:start'); + + // Check for draft version before creating + const isDraft = get().checkDraftStatus(); + if (isDraft && !branchData.force) { + return { + success: false, + error: 'DRAFT_EXISTS', + message: 'You can only have one draft version at a time. Please save or release your current draft first.', + }; + } + + try { + const response = await gitSyncService.createBranch(appId, organizationId, { + branchName: branchData.branchName, + versionFromId: branchData.versionFromId, + baseBranch: branchData.baseBranch || 'main', // Default to 'main' if not provided + autoCommit: branchData.autoCommit || false, + }); + + // Refresh branches list after creation + await get().fetchBranches(appId, organizationId); + + // Update current branch if successful + if (response?.branch) { + set( + () => ({ + currentBranch: response.branch, + }), + false, + 'createBranch:success' + ); + } + + return { success: true, branch: response?.branch }; + } catch (error) { + const apiErrorMessage = error?.data?.message || error?.error || error?.message || 'Failed to create branch'; + + set( + () => ({ + branchError: apiErrorMessage, + }), + false, + 'createBranch:error' + ); + + return { success: false, error: apiErrorMessage }; + } + }, + + /** + * Switch to a different branch (changes the editing version to the branch version) + * Branches are represented as versions with versionType === 'branch' + * IMPORTANT: Branches always work in Development environment, so we switch to Development first + * @param {string} appId - Application ID + * @param {string} branchName - Target branch name + */ + switchBranch: async (appId, branchName) => { + set(() => ({ branchError: null }), false, 'switchBranch:start'); + + try { + const state = get(); + + // Get Development environment - branches ALWAYS work in Development + const developmentEnv = state.environments?.find((env) => env.name === 'Development' || env.priority === 1); + if (!developmentEnv) { + throw new Error('Development environment not found'); + } + + // Get development versions to find the branch version + const developmentVersions = state.developmentVersions || []; + const branchVersion = developmentVersions.find( + (version) => + (version.versionType === 'branch' || version.version_type === 'branch') && version.name === branchName + ); + + if (!branchVersion) { + // Check if branch exists in allBranches but not as a version + const branchExists = state.allBranches.find((b) => b.name === branchName); + if (branchExists) { + throw new Error( + `Branch "${branchName}" exists in Git but has no corresponding version. You may need to create this branch in ToolJet first.` + ); + } + + const availableBranches = developmentVersions + .filter((v) => v.versionType === 'branch' || v.version_type === 'branch') + .map((v) => v.name) + .join(', '); + throw new Error( + `Branch version not found: ${branchName}. Available branch versions: ${availableBranches || 'none'}` + ); + } + + // Check if already on this branch version AND in Development environment + const alreadyOnVersion = state.selectedVersion?.id === branchVersion.id; + const alreadyInDevelopment = state.selectedEnvironment?.id === developmentEnv.id; + + if (alreadyOnVersion && alreadyInDevelopment) { + return { success: true, data: state.selectedVersion }; + } + + // Update current branch first + const targetBranch = state.allBranches.find((b) => b.name === branchName) || { name: branchName }; + set( + (state) => ({ + ...state, + currentBranch: targetBranch, + }), + false, + 'switchBranch:updating-branch' + ); + + // Switch to branch version (and Development environment if needed) + return new Promise((resolve, reject) => { + // If not in Development environment, switch to it first + if (!alreadyInDevelopment) { + state.environmentChangedAction(developmentEnv, () => { + // After environment switch, change to the branch version + state.changeEditorVersionAction( + appId, + branchVersion.id, + (data) => { + state.setCurrentVersionId(branchVersion.id); + state.setSelectedVersion(branchVersion); + resolve({ success: true, data }); + }, + (error) => { + console.error('switchBranch - error after environment change:', error); + set( + () => ({ branchError: error.message || 'Failed to switch to branch' }), + false, + 'switchBranch:error' + ); + reject({ success: false, error: error.message }); + } + ); + }); + } else { + // Already in Development, just switch to branch version + state.changeEditorVersionAction( + appId, + branchVersion.id, + (data) => { + state.setCurrentVersionId(branchVersion.id); + state.setSelectedVersion(branchVersion); + resolve({ success: true, data }); + }, + (error) => { + console.error('switchBranch - error switching version:', error); + set(() => ({ branchError: error.message || 'Failed to switch to branch' }), false, 'switchBranch:error'); + reject({ success: false, error: error.message }); + } + ); + } + }); + } catch (error) { + console.error('Error switching branch:', error); + set( + () => ({ + branchError: error.message || 'Failed to switch branch', + }), + false, + 'switchBranch:error' + ); + + throw error; // Re-throw to be caught by the modal + } + }, + + /** + * Switch to the default branch (main/master/configured branch) + * + * This function mimics the behavior of the version dropdown's handleVersionSelect (line 144): + * 1. Switch to Development environment first (if not already there) + * 2. Determine which version to switch to based on PRD scenarios + * 3. Call changeEditorVersionAction to load version data + * 4. Update currentBranch and selectedVersion + * + * Version Selection Logic (Based on PRD Scenarios): + * PRIORITY 1: DRAFT version (latest draft if multiple exist - v3 draft > v2.1 draft) + * PRIORITY 2: RELEASED version (latest released - v2 > v1) + * PRIORITY 3: PUBLISHED/Saved version (latest published) + * + * @param {string} appId - Application ID + * @param {string} defaultBranchName - Name of the default branch (from git config) + */ + switchToDefaultBranch: async (appId, defaultBranchName) => { + set(() => ({ branchError: null }), false, 'switchToDefaultBranch:start'); + + try { + const state = get(); + + // Get feature branch names (exclude default branch) to help with filtering + const featureBranchNames = state.allBranches.filter((b) => b.name !== defaultBranchName).map((b) => b.name); + + // Branches always work in Development environment - ALWAYS use developmentVersions + // This matches the PRD scenarios where all branch work happens in Development + const developmentVersions = state.developmentVersions || []; + + // Filter to get ONLY default branch versions (exclude branch-type versions) + // A version is a default branch version if it does NOT have versionType === 'branch' + // We rely on versionType field to distinguish branch versions from regular versions + const defaultBranchVersions = developmentVersions.filter((v) => { + const hasBranchType = v.versionType === 'branch' || v.version_type === 'branch'; + + // Only exclude if it has branch type - keep all versions with versionType === 'version' + return !hasBranchType; + }); + + // Version selection priority (PRD Scenarios 1-4) + let targetVersion = null; + + // PRIORITY 1: DRAFT version (Scenarios 1, 2, 3, 4) + // Get LATEST draft (most recently created) if multiple exist + const draftVersions = defaultBranchVersions + .filter((v) => v.status === 'DRAFT' || v.isDraft || v.is_draft) + .sort((a, b) => { + const dateA = new Date(a.createdAt || a.created_at || 0); + const dateB = new Date(b.createdAt || b.created_at || 0); + return dateB - dateA; // Descending - latest first + }); + + targetVersion = draftVersions[0]; + + // PRIORITY 2: RELEASED version (Scenario 2 - when no draft exists after v1 released) + if (!targetVersion) { + const releasedVersions = defaultBranchVersions + .filter((v) => v.status === 'RELEASED' || v.isReleased || v.is_released) + .sort((a, b) => { + const dateA = new Date(a.createdAt || a.created_at || 0); + const dateB = new Date(b.createdAt || b.created_at || 0); + return dateB - dateA; // Latest released + }); + + targetVersion = releasedVersions[0]; + } + + // PRIORITY 3: PUBLISHED version (fallback) + if (!targetVersion) { + const publishedVersions = defaultBranchVersions + .filter((v) => v.status === 'PUBLISHED' || v.isPublished || v.is_published) + .sort((a, b) => { + const dateA = new Date(a.createdAt || a.created_at || 0); + const dateB = new Date(b.createdAt || b.created_at || 0); + return dateB - dateA; + }); + + targetVersion = publishedVersions[0]; + } + + // If no version found, error + if (!targetVersion) { + console.error('switchToDefaultBranch - no versions found!'); + console.error('switchToDefaultBranch - developmentVersions:', developmentVersions); + console.error('switchToDefaultBranch - defaultBranchVersions:', defaultBranchVersions); + throw new Error('No versions found for the default branch. Please create a version first.'); + } + + // Get Development environment + const developmentEnv = state.environments?.find((env) => env.name === 'Development' || env.priority === 1); + if (!developmentEnv) { + throw new Error('Development environment not found'); + } + + // Check if already on this version AND in Development environment + const alreadyOnVersion = state.selectedVersion?.id === targetVersion.id; + const alreadyInDevelopment = state.selectedEnvironment?.id === developmentEnv.id; + + if (alreadyOnVersion && alreadyInDevelopment) { + const defaultBranch = state.allBranches.find((b) => b.name === defaultBranchName) || { + name: defaultBranchName, + }; + + set( + (state) => ({ + ...state, + currentBranch: defaultBranch, + }), + false, + 'switchToDefaultBranch:already-on-version' + ); + + return { success: true, data: state.selectedVersion, version: targetVersion }; + } + + // Update current branch first + const defaultBranch = state.allBranches.find((b) => b.name === defaultBranchName) || { + name: defaultBranchName, + }; + + set( + (state) => ({ + ...state, + currentBranch: defaultBranch, + }), + false, + 'switchToDefaultBranch:updating-branch' + ); + + // EXACTLY MATCH handleVersionSelect behavior (line 144 in VersionManagerDropdown.jsx) + return new Promise((resolve, reject) => { + // If not in Development environment, switch to it first (like handleVersionSelect does) + if (!alreadyInDevelopment) { + state.environmentChangedAction(developmentEnv, () => { + // After environment switch, change the version + state.changeEditorVersionAction( + appId, + targetVersion.id, + (data) => { + state.setCurrentVersionId(targetVersion.id); + resolve({ success: true, data, version: targetVersion }); + }, + (error) => { + console.error('switchToDefaultBranch - error after environment change:', error); + set( + () => ({ branchError: error.message || 'Failed to switch version' }), + false, + 'switchToDefaultBranch:error' + ); + reject({ success: false, error: error.message }); + } + ); + }); + } else { + // Already in Development, just switch version (like handleVersionSelect does) + state.changeEditorVersionAction( + appId, + targetVersion.id, + (data) => { + state.setCurrentVersionId(targetVersion.id); + state.setSelectedVersion(targetVersion); + resolve({ success: true, data, version: targetVersion }); + }, + (error) => { + console.error('switchToDefaultBranch - error switching version:', error); + set( + () => ({ branchError: error.message || 'Failed to switch version' }), + false, + 'switchToDefaultBranch:error' + ); + reject({ success: false, error: error.message }); + } + ); + } + }); + } catch (error) { + console.error('Error switching to default branch:', error); + set( + () => ({ + branchError: error.message || 'Failed to switch to default branch', + }), + false, + 'switchToDefaultBranch:error' + ); + + throw error; + } + }, + + /** + * Fetch pull requests for the current app + * @param {string} appId - Application ID + */ + fetchPullRequests: async (appId, organizationId) => { + set(() => ({ isLoadingPRs: true, branchError: null }), false, 'fetchPullRequests:start'); + + try { + const response = await gitSyncService.getPullRequests(appId, organizationId); + const pullRequests = response?.pull_requests || []; + + set( + () => ({ + pullRequests, + isLoadingPRs: false, + }), + false, + 'fetchPullRequests:success' + ); + + return { success: true, pullRequests }; + } catch (error) { + console.error('Error fetching pull requests:', error); + set( + () => ({ + isLoadingPRs: false, + branchError: error.message || 'Failed to fetch pull requests', + }), + false, + 'fetchPullRequests:error' + ); + + return { success: false, error: error.message }; + } + }, + + /** + * Check if a draft version is currently active + * @returns {boolean} True if draft version exists + */ + checkDraftStatus: () => { + const appVersions = get().appVersions || []; + const hasDraft = appVersions.some((version) => version.isDraft || version.is_draft); + + set( + () => ({ + isDraftVersionActive: hasDraft, + }), + false, + 'checkDraftStatus' + ); + + return hasDraft; + }, + + /** + * Update branching enabled status + * @param {boolean} enabled - Whether branching is enabled + */ + updateBranchingEnabled: (enabled) => + set( + () => ({ + branchingEnabled: enabled, + }), + false, + 'updateBranchingEnabled' + ), + + /** + * Set current branch + * @param {object} branch - Branch object + */ + setCurrentBranch: (branch) => + set( + () => ({ + currentBranch: branch, + }), + false, + 'setCurrentBranch' + ), + + /** + * Clear branch error + */ + clearBranchError: () => + set( + () => ({ + branchError: null, + }), + false, + 'clearBranchError' + ), + + /** + * Reset branch slice to initial state + */ + resetBranchSlice: () => + set( + () => ({ + ...initialState, + }), + false, + 'resetBranchSlice' + ), + + /** + * Get PR status for a specific branch + * @param {string} branchName - Branch name + * @returns {object|null} PR object or null + */ + getPRForBranch: (branchName) => { + const pullRequests = get().pullRequests; + return pullRequests.find((pr) => pr.source_branch === branchName || pr.sourceBranch === branchName) || null; + }, + + /** + * Check if branch is readonly (merged or released) + * @param {string} branchName - Branch name + * @returns {boolean} True if branch is readonly + */ + isBranchReadonly: (branchName) => { + const branch = get().allBranches.find((b) => b.name === branchName); + if (!branch) return false; + + return branch.is_merged || branch.isMerged || branch.is_released || branch.isReleased || false; + }, +}); diff --git a/frontend/src/AppBuilder/_stores/slices/environmentsAndVersionsSlice.js b/frontend/src/AppBuilder/_stores/slices/environmentsAndVersionsSlice.js index 9856112f61..a7de4eb716 100644 --- a/frontend/src/AppBuilder/_stores/slices/environmentsAndVersionsSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/environmentsAndVersionsSlice.js @@ -22,6 +22,8 @@ const initialState = { developmentVersions: [], draftVersions: [], publishedVersions: [], + draftVersions: [], + publishedVersions: [], environmentLoadingState: 'completed', isPublicAccess: false, }; @@ -134,16 +136,25 @@ export const createEnvironmentsAndVersionsSlice = (set, get) => ({ ); } - set((state) => ({ - ...state, - selectedEnvironment, - selectedVersion: response.editorVersion, - appVersionEnvironment: response.appVersionEnvironment, - shouldRenderPromoteButton: response.shouldRenderPromoteButton, - shouldRenderReleaseButton: response.shouldRenderReleaseButton, - environments: response.environments, - versionsPromotedToEnvironment: [response.editorVersion], - })); + set((state) => { + const stateUpdate = { + ...state, + selectedEnvironment, + selectedVersion: response.editorVersion, + appVersionEnvironment: response.appVersionEnvironment, + shouldRenderPromoteButton: response.shouldRenderPromoteButton, + shouldRenderReleaseButton: response.shouldRenderReleaseButton, + environments: response.environments, + versionsPromotedToEnvironment: [response.editorVersion], + }; + + // Clear currentBranch if initial version is not a branch + const versionType = response.editorVersion?.versionType || response.editorVersion?.version_type; + if (versionType !== 'branch') { + stateUpdate.currentBranch = null; + } + return stateUpdate; + }); } catch (error) { console.error('❌ DEBUG - Error while initializing the environment dropdown', error); } @@ -223,7 +234,8 @@ export const createEnvironmentsAndVersionsSlice = (set, get) => ({ selectedVersionId, versionDescription = '', onSuccess, - onFailure + onFailure, + versionType = 'version' ) => { try { const editorEnvironment = get().selectedEnvironment.id; @@ -232,7 +244,8 @@ export const createEnvironmentsAndVersionsSlice = (set, get) => ({ versionName, versionDescription, selectedVersionId, - editorEnvironment + editorEnvironment, + versionType ); const editorVersion = { id: newVersion.id, @@ -336,6 +349,8 @@ export const createEnvironmentsAndVersionsSlice = (set, get) => ({ name: data.editing_version.name, current_environment_id: data.editing_version.currentEnvironmentId, status: data.editing_version.status, + // Preserve versionType from API response to distinguish between regular versions and branch versions + versionType: data.editing_version.versionType || data.editing_version.version_type || 'version', }; const appVersionEnvironment = get().environments.find( (environment) => environment.id === selectedVersion.current_environment_id @@ -356,6 +371,12 @@ export const createEnvironmentsAndVersionsSlice = (set, get) => ({ useStore.getState()?.license?.featureAccess ), }; + + // Clear currentBranch if switching to a regular version (not a branch) + if (selectedVersion.versionType !== 'branch') { + optionsToUpdate.currentBranch = null; + } + set((state) => ({ ...state, ...optionsToUpdate })); onSuccess(data); } catch (error) { diff --git a/frontend/src/AppBuilder/_stores/slices/gitSyncSlice.js b/frontend/src/AppBuilder/_stores/slices/gitSyncSlice.js index 1e597d0f0e..05f5630649 100644 --- a/frontend/src/AppBuilder/_stores/slices/gitSyncSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/gitSyncSlice.js @@ -16,9 +16,9 @@ export const createGitSyncSlice = (set, get) => ({ const selectedEnvironment = useStore.getState()?.selectedEnvironment; const isEditorFreezed = useStore.getState()?.isEditorFreezed; - return featureAccess?.gitSync && selectedEnvironment?.priority === 1 && (creationMode === 'GIT' || !isEditorFreezed) + return featureAccess?.gitSync && selectedEnvironment?.priority === 1 ? set((state) => ({ showGitSyncModal: !state.showGitSyncModal }), false, 'toggleGitSyncModal') - : () => { }; + : () => {}; }, fetchAppGit: async (currentOrganizationId, currentAppVersionId) => { set((state) => ({ appLoading: true }), false, 'setAppLoading'); @@ -26,18 +26,23 @@ export const createGitSyncSlice = (set, get) => ({ const data = await gitSyncService.getAppGitConfigs(currentOrganizationId, currentAppVersionId); const allowEditing = data?.app_git?.allow_editing ?? false; const orgGit = data?.app_git?.org_git; + const isBranchingEnabled = orgGit?.is_branching_enabled ?? false; const appGit = data?.app_git; - const isGitSyncConfigured = data?.app_git?.is_git_sync_configured - set((state) => ({ isGitSyncConfigured }), false, 'isGitSyncConfigured') + set((state) => ({ appGit }), false, 'setAppGit'); + const isGitSyncConfigured = data?.app_git?.is_git_sync_configured; + // Update branchingEnabled in branchSlice + get().updateBranchingEnabled?.(isBranchingEnabled); + set((state) => ({ isGitSyncConfigured }), false, 'isGitSyncConfigured'); set((state) => ({ orgGit }), false, 'setOrgGit'); set((state) => ({ appGit }), false, 'setAppGit'); set((state) => ({ allowEditing }), false, 'setAllowEditing'); - console.log('app git', appGit); return allowEditing; } catch (error) { console.error('Failed to fetch app git configs:', error); // Set allowEditing to false on error set((state) => ({ allowEditing: false }), false, 'setAllowEditing'); + // Also reset branching on error + get().updateBranchingEnabled?.(false); return false; } finally { set((state) => ({ appLoading: false }), false, 'setAppLoading'); @@ -45,5 +50,5 @@ export const createGitSyncSlice = (set, get) => ({ }, setAppGit(appGit) { set((state) => ({ appGit: appGit }), false, 'setAppGit'); - } + }, }); diff --git a/frontend/src/AppBuilder/_stores/store.js b/frontend/src/AppBuilder/_stores/store.js index ebb6abcd53..bf68757e42 100644 --- a/frontend/src/AppBuilder/_stores/store.js +++ b/frontend/src/AppBuilder/_stores/store.js @@ -32,6 +32,7 @@ import { createWhiteLabellingSlice } from './slices/whiteLabellingSlice'; import { createFormComponentSlice } from './slices/formComponentSlice'; import { createInspectorSlice } from './slices/inspectorSlice'; import { createModuleSlice } from './slices/moduleSlice'; +import { createBranchSlice } from './slices/branchSlice'; enableMapSet(); export default create( @@ -68,6 +69,7 @@ export default create( ...createFormComponentSlice(...state), ...createInspectorSlice(...state), ...createModuleSlice(...state), + ...createBranchSlice(...state), })), { name: 'App Builder Store', anonymousActionType: 'unknown' } ) diff --git a/frontend/src/HomePage/HomePage.jsx b/frontend/src/HomePage/HomePage.jsx index 4f6f24410d..010fe2868b 100644 --- a/frontend/src/HomePage/HomePage.jsx +++ b/frontend/src/HomePage/HomePage.jsx @@ -108,6 +108,10 @@ class HomePageComponent extends React.Component { selectedAppRepo: null, importingApp: false, importingGitAppOperations: {}, + latestCommitData: null, + tags: [], + fetchingLatestCommitData: false, + selectedVersionOption: null, featuresLoaded: false, showCreateAppModal: false, showCreateAppFromTemplateModal: false, @@ -841,24 +845,55 @@ class HomePageComponent extends React.Component { }; importGitApp = () => { - const { appsFromRepos, selectedAppRepo, orgGit, importedAppName } = this.state; + const { appsFromRepos, selectedAppRepo, orgGit, importedAppName, selectedVersionOption, tags } = this.state; const appToImport = appsFromRepos[selectedAppRepo]; - const { git_app_name, git_version_id, git_version_name, last_commit_message, last_commit_user, lastpush_date } = - appToImport; + const { + git_app_name, + git_version_id, + git_version_name, + last_commit_message, + last_commit_user, + lastpush_date, + app_co_relation_id, + } = appToImport; + + let commitHash = null; + let commitMessage = last_commit_message; + let commitUser = last_commit_user; + let commitDate = lastpush_date; + let gitVersionNameToUse = git_version_name; + + // If a tag is selected (not latest), use tag's commit info + if (selectedVersionOption && selectedVersionOption !== 'latest') { + const selectedTag = tags.find((t) => t.name === selectedVersionOption); + if (selectedTag) { + commitHash = selectedTag.commit?.sha; + commitMessage = selectedTag.message; + commitUser = selectedTag.tagger?.name; + commitDate = selectedTag.tagger?.date; + gitVersionNameToUse = selectedTag.name.split('/').pop(); + } else { + commitMessage = last_commit_message; + commitUser = last_commit_user; + commitDate = lastpush_date; + } + } this.setState({ importingApp: true }); const body = { gitAppId: selectedAppRepo, gitAppName: git_app_name, - gitVersionName: git_version_name, + gitVersionName: gitVersionNameToUse, gitVersionId: git_version_id, - lastCommitMessage: last_commit_message, - lastCommitUser: last_commit_user, - lastPushDate: new Date(lastpush_date), organizationGitId: orgGit?.id, appName: importedAppName?.trim().replace(/\s+/g, ' '), allowEditing: this.state.isAppImportEditable, + ...(commitHash && { commitHash, appCoRelationId: app_co_relation_id }), + ...(commitMessage && { lastCommitMessage: commitMessage }), + ...(commitUser && { lastCommitUser: commitUser }), + ...(commitDate && { lastPushDate: new Date(commitDate) }), }; + gitSyncService .importGitApp(body) .then((data) => { @@ -883,7 +918,7 @@ class HomePageComponent extends React.Component { folderService .addToFolder(appOperations.selectedApp.id, appOperations.selectedFolder) .then(() => { - toast.success('Added to folder.'); + toast.success('Application added to folder successfully!'); this.foldersChanged(); this.setState({ appOperations: {}, showAddToFolderModal: false }); posthogHelper.captureEvent('click_add_to_folder_button', { @@ -910,7 +945,7 @@ class HomePageComponent extends React.Component { folderService .removeAppFromFolder(appOperations.selectedApp.id, appOperations.selectedFolder.id) .then(() => { - toast.success('Removed from folder.'); + toast.success('Application removed from folder successfully!'); this.fetchApps(1, appOperations.selectedFolder.id); this.fetchFolders(); @@ -1008,7 +1043,13 @@ class HomePageComponent extends React.Component { generateOptionsForRepository = () => { const { appsFromRepos } = this.state; - return Object.keys(appsFromRepos).map((gitAppId) => ({ + + // Filter out non-app keys like 'has_latest_changes' and 'tags' + const appIds = Object.keys(appsFromRepos).filter( + (key) => key !== 'has_latest_changes' && key !== 'tags' && appsFromRepos[key]?.git_app_name + ); + + return appIds.map((gitAppId) => ({ name: appsFromRepos[gitAppId].git_app_name, value: gitAppId, })); @@ -1154,7 +1195,7 @@ class HomePageComponent extends React.Component { this.setState({ importingGitAppOperations: validationMessage, }); - return; + return; } this.setState({ importedAppName: newAppName, @@ -1162,6 +1203,44 @@ class HomePageComponent extends React.Component { }); }; + handleAppRepoChange = async (newVal) => { + const { appsFromRepos, orgGit } = this.state; + const selectedApp = appsFromRepos[newVal]; + this.setState({ + selectedAppRepo: newVal, + importedAppName: selectedApp?.git_app_name, + }); + if (selectedApp?.app_name_exist === 'EXIST') { + this.setState({ + importingGitAppOperations: { message: 'App name already exists' }, + fetchingLatestCommitData: true, + latestCommitData: null, + }); + } else { + this.setState({ + importingGitAppOperations: {}, + fetchingLatestCommitData: true, + latestCommitData: null, + selectedVersionOption: null, + }); + } + const selectedBranch = orgGit?.git_https?.github_branch || orgGit?.git_ssh?.git_branch || orgGit?.git_lab_branch; + + try { + const data = await gitSyncService.checkForUpdatesByAppName(selectedApp?.git_app_name, selectedBranch); + this.setState({ + latestCommitData: data?.metaData, + tags: data?.metaData.tags, + fetchingLatestCommitData: false, + selectedVersionOption: 'latest', + }); + // TODO: Handle the response data + } catch (error) { + console.error('Failed to check for updates:', error); + this.setState({ fetchingLatestCommitData: false }); + } + }; + // Helper functions for workflow limit checks hasWorkflowLimitReached = () => { const { workflowInstanceLevelLimit, workflowWorkspaceLevelLimit } = this.state; @@ -1213,6 +1292,82 @@ class HomePageComponent extends React.Component { this.eraseAIOnboardingRelatedCookies(); }; + generateVersionOptions = () => { + const { latestCommitData, tags } = this.state; + const options = []; + + // Add latest commit as first option + if (latestCommitData?.latestCommit?.[0]) { + const gitVersionName = latestCommitData?.gitVersionName; + // Check if the latest commit's version exists in tags (to determine if it's a draft) + const tagVersionNames = (tags || []).map((tag) => { + const [, version] = tag.name.split('/'); + return version; + }); + const isInTags = tagVersionNames.includes(gitVersionName); + + options.push({ + label: isInTags ? gitVersionName : 'Draft version', + value: 'latest', + isLatest: true, + isDraft: !isInTags, + sha: latestCommitData?.latestCommit?.[0]?.commitId, + }); + } + + // Add tags - filter out tags that have the same SHA as the latest commit + if (tags && tags.length > 0) { + const latestCommitSha = latestCommitData?.latestCommit?.[0]?.commitId; + const filteredTags = latestCommitSha ? tags.filter((tag) => tag.commit?.sha !== latestCommitSha) : tags; + + filteredTags.forEach((tag) => { + const [, version] = tag.name.split('/'); + options.push({ + label: version, + value: tag.name, + isLatest: false, + isDraft: false, + }); + }); + } + + return options; + }; + + renderVersionOption = (option) => { + return ( +
    + {option.label} +
    + {option.isLatest && ( + + Latest + + )} +
    +
    + ); + }; + + handleVersionOptionChange = (newVal) => { + this.setState({ selectedVersionOption: newVal }); + }; + render() { const { apps, @@ -1242,7 +1397,10 @@ class HomePageComponent extends React.Component { fetchingAppsFromRepos, selectedAppRepo, appsFromRepos, + latestCommitData, + fetchingLatestCommitData, importingApp, + selectedVersionOption, importingGitAppOperations, featuresLoaded, showCreateAppModal, @@ -1351,7 +1509,6 @@ class HomePageComponent extends React.Component { const threshold = 3; const isLong = missingGroups.length > threshold; const displayedGroups = missingGroupsExpanded ? missingGroups : missingGroups.slice(0, threshold); - return (
    @@ -1536,18 +1693,7 @@ class HomePageComponent extends React.Component {
    + + {/* VERSION/TAG SELECT */} +
    + +
    + -
    -
    -
    - Commit changes + {orgGit?.is_enabled && + modalType !== 'create' && + appType != APP_TYPE.WORKFLOW && + appType != APP_TYPE.MODULE && ( +
    +
    +
    -
    - This action commits the app's creation to the git repository +
    +
    + Commit changes +
    +
    + This action commits the app's creation to the git repository +
    -
    - )} + )}
    {dependentPlugins && dependentPlugins.length >= 1 && (
    e.stopPropagation()}> diff --git a/frontend/src/_services/appVersion.service.js b/frontend/src/_services/appVersion.service.js index c6e38b105a..b7b3879c29 100644 --- a/frontend/src/_services/appVersion.service.js +++ b/frontend/src/_services/appVersion.service.js @@ -46,12 +46,13 @@ function getAppVersionData(appId, versionId, mode) { ); } -function create(appId, versionName, versionDescription, versionFromId, currentEnvironmentId) { +function create(appId, versionName, versionDescription, versionFromId, currentEnvironmentId, versionType = 'version') { const body = { versionName, versionDescription, versionFromId, environmentId: currentEnvironmentId, + versionType, }; const requestOptions = { @@ -150,10 +151,10 @@ function autoSaveApp( const body = !type ? { ...diff } : bodyMappings[type]?.[operation] || { - is_user_switched_version: isUserSwitchedVersion, - pageId, - diff, - }; + is_user_switched_version: isUserSwitchedVersion, + pageId, + diff, + }; if (type === 'components' && operation === 'delete' && isComponentCutProcess) { body['is_component_cut'] = true; diff --git a/frontend/src/_services/git_sync.service.js b/frontend/src/_services/git_sync.service.js index 25df504e10..9fe23b2852 100644 --- a/frontend/src/_services/git_sync.service.js +++ b/frontend/src/_services/git_sync.service.js @@ -13,12 +13,21 @@ export const gitSyncService = { gitPull, importGitApp, checkForUpdates, + checkForUpdatesByAppName, confirmPullChanges, updateStatus, getGitStatus, saveProviderConfigs, updateAppEditState, getAppGitConfigs, + // New branch management methods + getAllBranches, + createBranch, + getPullRequests, + switchBranch, + updateGitConfigs, + getGitConfigs, + createGitTag, }; function create(organizationId, gitUrl, gitType) { @@ -38,11 +47,12 @@ function create(organizationId, gitUrl, gitType) { } function updateConfig(organizationGitId, updateParam, gitType = '') { - const { gitUrl, autoCommit, keyType } = updateParam; + const { gitUrl, autoCommit, keyType, branchingEnabled } = updateParam; const body = { ...(gitUrl && { gitUrl }), ...(autoCommit != null && { autoCommit }), ...(keyType && { keyType }), + ...(branchingEnabled && { branchingEnabled }), }; const requestOptions = { method: 'PUT', @@ -108,6 +118,7 @@ function deleteConfig(organizationGitId, gitType) { } function gitPush(body, appGitId, versionId) { + // body can now include { commitMessage, sourceBranch } when branching is enabled const requestOptions = { method: 'POST', headers: authHeader(), @@ -134,13 +145,27 @@ function getAppConfig(organizationId, versionId) { return response; } -function checkForUpdates(appId) { +function checkForUpdates(appId, branchName = '') { const requestOptions = { method: 'GET', headers: authHeader(), credentials: 'include', }; - return fetch(`${config.apiUrl}/app-git/gitpull/app/${appId}`, requestOptions).then(handleResponse); + return fetch(`${config.apiUrl}/app-git/gitpull/app/${appId}?branch=${branchName}`, requestOptions).then( + handleResponse + ); +} + +function checkForUpdatesByAppName(appName, branchName = '') { + const requestOptions = { + method: 'GET', + headers: authHeader(), + credentials: 'include', + }; + const params = new URLSearchParams(); + if (appName) params.append('appName', appName); + if (branchName) params.append('branch', branchName); + return fetch(`${config.apiUrl}/app-git/gitpull/app?${params.toString()}`, requestOptions).then(handleResponse); } function gitPull() { @@ -221,4 +246,116 @@ function getAppGitConfigs(workspaceId, versionId) { return fetch(`${config.apiUrl}/app-git/${workspaceId}/app/${versionId}/configs`, requestOptions).then(handleResponse); } + +// Branch Management API Methods + +/** + * Get all branches for an app + * @param {string} appId - Application ID + * @param {string} organizationId - Organization ID + * @returns {Promise} Promise resolving to branches array + */ +function getAllBranches(appId, organizationId) { + const requestOptions = { + method: 'GET', + headers: authHeader(), + credentials: 'include', + }; + return fetch(`${config.apiUrl}/app-git/${organizationId}/app/${appId}/branches`, requestOptions).then((response) => + handleResponse(response, false, null, true) + ); +} + +/** + * Create a new branch + * @param {string} appId - Application ID + * @param {string} organizationId - Organization ID + * @param {object} branchData - { branch_name, version_from_id, auto_commit } + * @returns {Promise} Promise resolving to created branch + */ +function createBranch(appId, organizationId, branchData) { + const requestOptions = { + method: 'POST', + headers: authHeader(), + credentials: 'include', + body: JSON.stringify(branchData), + }; + return fetch(`${config.apiUrl}/app-git/${organizationId}/app/${appId}/branches`, requestOptions).then(handleResponse); +} + +/** + * Get pull requests for an app + * @param {string} appId - Application ID + * @returns {Promise} Promise resolving to pull requests array + */ +function getPullRequests(appId, organizationId) { + const requestOptions = { + method: 'GET', + headers: authHeader(), + credentials: 'include', + }; + return fetch(`${config.apiUrl}/app-git/${organizationId}/app/${appId}/pull-requests`, requestOptions).then( + (response) => handleResponse(response, false, null, true) + ); +} + +/** + * Switch to a different branch (pull commits from branch) + * @param {string} appId - Application ID + * @param {string} branchName - Target branch name + * @returns {Promise} Promise resolving to pull result + */ +function switchBranch(appId, branchName) { + const requestOptions = { + method: 'GET', + headers: authHeader(), + credentials: 'include', + }; + return fetch(`${config.apiUrl}/app-git/gitpull/app/${appId}?branch=${branchName}`, requestOptions).then( + handleResponse + ); +} + +/** + * Update git configurations (including branching enabled status) + * @param {string} appId - Application ID + * @param {object} configs - Configuration object { branching_enabled, ...otherConfigs } + * @returns {Promise} Promise resolving to updated configs + */ +function updateGitConfigs(appId, configs) { + const requestOptions = { + method: 'PUT', + headers: authHeader(), + credentials: 'include', + body: JSON.stringify(configs), + }; + return fetch(`${config.apiUrl}/app-git/${appId}/configs`, requestOptions).then(handleResponse); +} + +/** + * Get git configurations for an app version + * @param {string} organizationId - Organization ID + * @param {string} versionId - Version ID + * @returns {Promise} Promise resolving to git configs + */ +function getGitConfigs(organizationId, versionId) { + const requestOptions = { + method: 'GET', + headers: authHeader(), + credentials: 'include', + }; + return fetch(`${config.apiUrl}/app-git/${organizationId}/app/${versionId}/configs`, requestOptions).then( + handleResponse + ); +} + +function createGitTag(appId, versionId, versionDescription) { + const requestOptions = { + method: 'POST', + headers: authHeader(), + credentials: 'include', + body: JSON.stringify({ message: versionDescription }), + }; + return fetch(`${config.apiUrl}/app-git/${appId}/versions/${versionId}/tag`, requestOptions).then(handleResponse); +} // Remove all app-git api's to separate service from here. diff --git a/frontend/src/_stores/environmentsAndVersionsStore.js b/frontend/src/_stores/environmentsAndVersionsStore.js index 40a5f3712d..5f2c9bdb4d 100644 --- a/frontend/src/_stores/environmentsAndVersionsStore.js +++ b/frontend/src/_stores/environmentsAndVersionsStore.js @@ -81,10 +81,24 @@ export const useEnvironmentsAndVersionsStore = create( }, setSelectedVersion: (selectedVersion) => set({ selectedVersion }), setEnvironmentAndVersionsInitStatus: (state) => set({ completedEnvironmentAndVersionsInit: state }), - createNewVersionAction: async (appId, versionName, selectedVersionId, onSuccess, onFailure) => { + createNewVersionAction: async ( + appId, + versionName, + selectedVersionId, + onSuccess, + onFailure, + versionType = 'version' + ) => { try { const editorEnvironment = get().selectedEnvironment.id; - const newVersion = await appVersionService.create(appId, versionName, selectedVersionId, editorEnvironment); + const newVersion = await appVersionService.create( + appId, + versionName, + '', + selectedVersionId, + editorEnvironment, + versionType + ); const editorVersion = { id: newVersion.id, name: newVersion.name, diff --git a/frontend/src/_stores/versionManagerStore.js b/frontend/src/_stores/versionManagerStore.js index 96ed87f4fd..d782011072 100644 --- a/frontend/src/_stores/versionManagerStore.js +++ b/frontend/src/_stores/versionManagerStore.js @@ -39,6 +39,10 @@ export const useVersionManagerStore = create( const { versions, searchQuery } = get(); let filtered = versions; + filtered = filtered.filter((v) => { + const versionType = v.versionType || v.version_type; + return versionType !== 'branch'; + }); // Filter by search query only if (searchQuery) { diff --git a/frontend/src/_styles/branch-dropdown.scss b/frontend/src/_styles/branch-dropdown.scss new file mode 100644 index 0000000000..ad0b2860ec --- /dev/null +++ b/frontend/src/_styles/branch-dropdown.scss @@ -0,0 +1,1153 @@ +// Branch Dropdown Styles +.branch-dropdown-container { + position: relative; + display: inline-flex; + align-items: center; + margin-left: 8px; + user-select: none; + margin-right: 8px; + border-radius: 8px; + + &.selected { + .branch-dropdown-button { + background-color: var(--slate3); + } + } + + &.dark-theme { + .branch-dropdown-button { + border-color: var(--slate7); + background-color: var(--slate2); + } + } +} + +.branch-dropdown-button { + display: flex; + align-items: center; + gap: 6px; + padding: 7px 12px; + border-radius: 6px; + border: 1px solid var(--slate6); + background-color: var(--slate1); + cursor: pointer; + transition: all 0.2s ease; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + outline: none; + outline: 0px !important; + + &:hover { + background-color: var(--slate3); + border-color: var(--slate7); + } + + svg { + flex-shrink: 0; + } + + .branch-name { + color: var(--text-default); + font-weight: 500; + font-size: 12px; + line-height: 18px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +// Old styles - keeping for backward compatibility +.branch-dropdown-header { + display: flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + border-radius: 6px; + border: 1px solid var(--slate6); + background-color: var(--slate2); + cursor: pointer; + transition: all 0.2s ease; + min-width: 160px; + + &:hover { + background-color: var(--slate3); + border-color: var(--slate7); + } + + svg { + flex-shrink: 0; + } + + .branch-label { + color: var(--slate11); + font-weight: 500; + white-space: nowrap; + } + + .current-branch-name { + color: var(--slate12); + font-weight: 500; + font-size: 13px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; + } + + .branch-arrow { + display: flex; + align-items: center; + transition: transform 0.2s ease; + + &.branch-arrow-rotate { + transform: rotate(90deg); + } + } +} + +.branch-dropdown-popover { + position: absolute; + top: calc(100% + 4px); + left: 0; + width: 320px; + max-height: 450px; + background-color: var(--slate1); + border: 1px solid var(--slate6); + border-radius: 10px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + z-index: 1000; + overflow: hidden; + display: flex; + flex-direction: column; + + &.theme-dark { + background-color: var(--slate2); + border-color: var(--slate7); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + } +} + +// Current Branch Header (with lock icon) +.branch-dropdown-current-branch { + display: flex; + align-items: center; + gap: 8px; + padding: 14px 16px 8px 16px; + + &.with-border { + border-bottom: 1px solid var(--slate6); + } + + .branch-icon-container { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 100px; + background-color: var(--indigo3); + flex-shrink: 0; + } + + // Feature branch icon (gitsync) + .branch-icon-container-feature { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 100px; + background-color: var(--indigo3); + flex-shrink: 0; + } + + .branch-info { + display: flex; + flex-direction: column; + gap: 2px; + flex: 1; + min-width: 0; + + .branch-name-title { + font-family: 'Inter', sans-serif; + font-weight: 500; + font-size: 14px; + line-height: 20px; + color: var(--text-default); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .branch-metadata, + .branch-metadata-feature { + display: flex; + align-items: center; + gap: 4px; + font-family: 'Inter', sans-serif; + font-weight: 400; + font-size: 12px; + line-height: 18px; + + .metadata-text { + color: var(--slate11); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .metadata-dot { + color: var(--slate11); + width: 2px; + height: 2px; + flex-shrink: 0; + } + } + } +} + +// Main Content Area +.branch-dropdown-content { + display: flex; + flex-direction: column; + padding: 10px 0; + border-bottom: 1px solid var(--slate6); + + .fetch-prs-section { + display: flex; + align-items: center; + justify-content: center; + padding: 0 16px; + min-height: 94px; + + .fetch-prs-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 5px 10px; + height: 28px; + background-color: var(--slate1); + border: 1px solid var(--slate6); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-weight: 500; + font-size: 12px; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.2s ease; + outline: none; + + &:hover:not(:disabled) { + background-color: var(--slate3); + border-color: var(--slate7); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + + &.loading { + opacity: 0.8; + } + + svg { + flex-shrink: 0; + } + } + } +} + +.branches-list { + flex: 1; + overflow-y: auto; + padding: 8px 0; + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background-color: var(--slate7); + border-radius: 3px; + } + + &::-webkit-scrollbar-track { + background-color: var(--slate3); + } +} + +.branch-section { + margin-bottom: 16px; + + &:last-child { + margin-bottom: 0; + } + + .section-label { + font-size: 11px; + font-weight: 600; + color: var(--slate11); + text-transform: uppercase; + letter-spacing: 0.5px; + padding: 8px 16px 4px; + } +} + +.branch-group { + margin-bottom: 2px; +} + +.branch-item { + padding: 0 8px; + cursor: pointer; + transition: background-color 0.15s ease; + + &:hover { + background-color: var(--slate3); + } + + &.active { + background-color: var(--indigo3); + + .branch-name span { + color: var(--indigo11); + font-weight: 600; + } + + svg { + fill: var(--indigo11); + } + } +} + +.branch-item-content { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 8px; + border-radius: 6px; + + .branch-name { + display: flex; + align-items: center; + gap: 8px; + flex: 1; + min-width: 0; + + span { + font-size: 13px; + color: var(--slate12); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .expand-icon { + display: flex; + align-items: center; + justify-content: center; + background: none; + border: none; + padding: 2px; + cursor: pointer; + border-radius: 4px; + transition: all 0.2s ease; + + &:hover { + background-color: var(--slate5); + } + + svg { + transition: transform 0.2s ease; + + &.expanded { + transform: rotate(180deg); + } + } + } + } +} + +.pr-badge { + display: inline-flex; + align-items: center; + padding: 2px 8px; + border-radius: 12px; + font-size: 11px; + font-weight: 600; + white-space: nowrap; + + &.pr-badge-open { + background-color: var(--green3); + color: var(--green11); + } + + &.pr-badge-merged { + background-color: var(--purple3); + color: var(--purple11); + } + + &.pr-badge-closed { + background-color: var(--red3); + color: var(--red11); + } +} + +.nested-versions { + padding-left: 32px; + margin-top: 4px; +} + +.version-item { + padding: 8px 16px; + cursor: pointer; + transition: background-color 0.15s ease; + + &:hover { + background-color: var(--slate3); + } + + .version-name { + display: flex; + align-items: center; + gap: 8px; + + .version-label { + font-size: 12px; + color: var(--slate11); + } + + .draft-badge { + display: inline-flex; + align-items: center; + padding: 2px 6px; + border-radius: 10px; + font-size: 10px; + font-weight: 600; + background-color: var(--amber3); + color: var(--amber11); + } + } +} + +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 40px 16px; + text-align: center; + min-height: 200px; + + .empty-state-icon { + margin-bottom: 16px; + opacity: 0.4; + + svg { + display: block; + } + } + + .empty-state-text { + font-family: 'Inter', sans-serif; + font-size: 14px; + font-weight: 600; + color: var(--slate12); + margin: 0 0 4px 0; + } + + .empty-state-subtext { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 400; + color: var(--slate11); + margin: 0; + } +} + +.loading-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 32px 16px; + gap: 12px; + + .spinner { + width: 20px; + height: 20px; + border: 2px solid var(--slate6); + border-top-color: var(--indigo9); + border-radius: 50%; + animation: spin 0.6s linear infinite; + } + + span { + font-size: 13px; + color: var(--slate11); + } +} + +// Small spinner for buttons +.spinner-small { + width: 14px; + height: 14px; + border: 2px solid var(--slate6); + border-top-color: var(--indigo9); + border-radius: 50%; + animation: spin 0.6s linear infinite; + flex-shrink: 0; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.branch-dropdown-footer { + display: flex; + flex-direction: column; + gap: 8px; + padding: 16px; + border-top: 1px solid var(--slate6); + + .create-branch-btn, + .switch-branch-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + width: 100%; + padding: 5px 10px; + background-color: var(--slate1); + border: 1px solid var(--slate6); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-weight: 500; + font-size: 12px; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.2s ease; + outline: none; + + &:hover { + background-color: var(--slate3); + border-color: var(--slate7); + } + + &:active { + transform: scale(0.98); + } + + svg { + flex-shrink: 0; + } + } + + .create-branch-btn.accent { + border-color: var(--indigo6); + + &:hover { + border-color: var(--indigo7); + background-color: var(--indigo2); + } + + svg { + fill: var(--indigo9); + } + } +} + +// Branch metadata styles +.branch-metadata { + display: flex; + align-items: center; + gap: 8px; +} + +.branch-updated { + font-size: 11px; + color: var(--slate9); + white-space: nowrap; +} + +.branch-lock-icon { + flex-shrink: 0; +} + +.rotating { + animation: rotate 1s linear infinite; +} + +@keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +// Fetch PRs Section (only shown on default branch at top) +.fetch-prs-section { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + justify-content: center; + padding: 16px 0; + min-height: 94px; + border-bottom: 1px solid var(--slate6); + + .fetch-prs-btn { + display: flex; + align-items: center; + gap: 6px; + padding: 5px 10px; + background: var(--slate1); + border: 1px solid var(--slate7); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.15s ease; + height: 28px; + + &:hover { + background: var(--slate3); + border-color: var(--slate8); + } + + svg { + flex-shrink: 0; + } + } +} + +// Fetch Branch Info Section (only shown on feature branch at top) +.fetch-branch-info-section { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + justify-content: center; + padding: 16px 0; + min-height: 120px; + + .fetch-branch-info-btn { + display: flex; + align-items: center; + gap: 6px; + padding: 5px 10px; + background: var(--slate1); + border: 1px solid var(--slate7); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.15s ease; + height: 28px; + + &:hover:not(:disabled) { + background: var(--slate3); + border-color: var(--slate8); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + + svg { + flex-shrink: 0; + } + } +} + +// PR Tabs Section (only shown on default branch) +.pr-tabs { + display: flex; + gap: 4px; + padding: 0 16px; + border-bottom: 1px solid var(--slate6); + + .pr-tab { + position: relative; + padding: 6px 7px 8px 7px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate11); + background: none; + border: none; + border-bottom: 2px solid transparent; + cursor: pointer; + transition: all 0.2s ease; + outline: none; + + &:hover { + color: var(--slate12); + } + + &.active { + color: var(--slate12); + border-bottom-color: var(--indigo9); + border-radius: 0; + } + } +} + +// PR List Container +.pr-list-container { + padding: 0 16px; + overflow-y: auto; + max-height: 280px; + + .pr-item { + display: flex; + gap: 6px; + padding: 8px; + align-items: flex-start; + cursor: pointer; + transition: background-color 0.15s ease; + border-radius: 6px; + + &:hover { + background-color: var(--slate3); + } + + .pr-icon { + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + margin-top: 2px; + } + + .pr-content { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + gap: 2px; + + .pr-title { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .pr-metadata { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 400; + line-height: 18px; + color: var(--slate11); + white-space: normal; + word-break: break-word; + } + } + } +} + +// Empty PR State (old simple version) +.empty-pr-state { + display: flex; + align-items: center; + justify-content: center; + padding: 32px 16px; + + .empty-pr-text { + font-family: 'Inter', sans-serif; + font-size: 13px; + font-weight: 400; + color: var(--slate11); + margin: 0; + text-align: center; + } +} + +// Empty PR State Box (new Figma design with warning icon) +.empty-pr-state-box { + display: flex; + gap: 6px; + align-items: flex-start; + padding: 8px 12px; + margin: 16px 0px; + height: 70px; + border: 1px dashed var(--slate8); + border-radius: 6px; + background: transparent; + + svg { + color: var(--icon-warning, #BF4F03); + flex-shrink: 0; + } + + .empty-pr-icon { + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + } + + .empty-pr-content { + display: flex; + flex-direction: column; + gap: 4px; + flex: 1; + + .empty-pr-title { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + } + + .empty-pr-description { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 400; + line-height: 18px; + color: var(--slate11); + } + } +} + +// Fetch Branch Section (for non-default branches) +.fetch-branch-section { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 16px 0; + height: 120px; + + .fetch-branch-btn { + display: flex; + align-items: center; + gap: 6px; + padding: 5px 10px; + height: 28px; + background: var(--slate1); + border: 1px solid var(--slate6); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.15s ease; + + &:hover:not(:disabled) { + background: var(--slate3); + border-color: var(--slate7); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + svg { + flex-shrink: 0; + + &.rotating { + animation: spin 1s linear infinite; + } + } + } +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +// Latest Commit Section +.latest-commit-section { + display: flex; + flex-direction: column; + gap: 12px; + padding: 12px 16px 12px 16px; + width: 100%; + + .latest-commit-header { + .section-label { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 20px; + color: var(--slate11); + text-transform: uppercase; + } + } + + .commit-info { + display: flex; + gap: 6px; + align-items: flex-start; + + .commit-icon { + display: flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + flex-shrink: 0; + } + + .commit-content { + display: flex; + flex-direction: column; + gap: 4px; + flex: 1; + min-width: 0; + + .commit-title { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + } + + .commit-metadata { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 400; + line-height: 18px; + color: var(--slate11); + } + } + } +} + +// No Commits Empty State +.no-commits-empty-state { + display: flex; + gap: 6px; + align-items: flex-start; + padding: 8px 12px; + margin: 16px; + border: 1px dashed var(--border-default, #CCD1D5); + border-radius: 6px; + background: transparent; + + svg { + color: var(--icon-warning, #BF4F03); + flex-shrink: 0; + } + + .empty-state-icon-warning { + display: flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + flex-shrink: 0; + margin-top: 2px; + } + + .empty-state-content { + display: flex; + flex-direction: column; + flex: 1; + + .empty-state-title { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + } + + .empty-state-description { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 400; + line-height: 18px; + color: var(--slate11); + } + } +} + +// Loading Commit State +.loading-commit-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 24px 16px; + gap: 12px; + + .spinner { + width: 24px; + height: 24px; + border: 2px solid var(--slate6); + border-top-color: var(--indigo9); + border-radius: 50%; + animation: spin 0.8s linear infinite; + } + + span { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 400; + color: var(--slate11); + } +} + +// Update footer button styles for Create PR +.branch-dropdown-footer { + display: flex; + flex-direction: column; + gap: 8px; + padding: 16px; + width: 100%; + + .create-branch-btn { + display: flex; + align-items: center; + gap: 6px; + padding: 5px 10px; + background: var(--slate1); + border: 1px solid var(--indigo7); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.15s ease; + flex: 1; + + &:hover { + background: var(--indigo2); + } + + svg { + flex-shrink: 0; + } + } + + .fetch-branch-btn { + display: flex; + align-items: center; + gap: 6px; + padding: 5px 10px; + background: var(--slate1); + border: 1px solid var(--slate7); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.15s ease; + flex: 1; + + &:hover:not(:disabled) { + background: var(--slate3); + border-color: var(--slate8); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + + svg { + flex-shrink: 0; + } + } + + .create-pr-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + width: 100%; + padding: 5px 10px; + background: var(--slate1); + border: 1px solid var(--indigo7); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.15s ease; + + &:hover { + background: var(--indigo2); + border-color: var(--indigo8); + } + + svg { + flex-shrink: 0; + } + } + + .switch-branch-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + width: 100%; + padding: 5px 10px; + background: var(--slate1); + border: 1px solid var(--slate7); + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + cursor: pointer; + transition: all 0.15s ease; + + &:hover { + background: var(--slate3); + border-color: var(--slate8); + } + + svg { + flex-shrink: 0; + } + } +} diff --git a/frontend/src/_styles/create-branch-modal.scss b/frontend/src/_styles/create-branch-modal.scss new file mode 100644 index 0000000000..f2531b7f3d --- /dev/null +++ b/frontend/src/_styles/create-branch-modal.scss @@ -0,0 +1,574 @@ +// Create Branch Modal Styles +.create-branch-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; +} + +.create-branch-modal { + width: 404px; + min-height: auto; + background-color: var(--slate1); + border: 1px solid var(--slate6); + border-radius: 6px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); + display: flex; + flex-direction: column; + animation: modalFadeIn 0.2s ease; + + &.theme-dark { + background-color: var(--slate2); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + } +} + +@keyframes modalFadeIn { + from { + opacity: 0; + transform: scale(0.95); + } + + to { + opacity: 1; + transform: scale(1); + } +} + +.create-branch-modal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 24px; + border-bottom: 1px solid var(--slate6); + + .modal-title { + font-size: 16px; + font-weight: 500; + line-height: 24px; + color: var(--slate12); + margin: 0; + } + + .close-button { + display: flex; + align-items: center; + justify-content: center; + background: none; + border: none; + padding: 4px; + cursor: pointer; + border-radius: 4px; + transition: background-color 0.15s ease; + color: var(--slate11); + + &:hover { + background-color: var(--slate4); + color: var(--slate12); + } + + &:active { + transform: scale(0.95); + } + } +} + +.create-branch-modal-body { + flex: 1; + max-height: calc(80vh - 140px); + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background-color: var(--slate7); + border-radius: 3px; + } + + &::-webkit-scrollbar-track { + background-color: var(--slate3); + } +} + +.form-group { + margin-bottom: 16px; + + &:last-child { + margin-bottom: 0; + } +} + +.form-label { + display: block; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + margin-bottom: 2px; + padding-left: 2px; +} + +.form-select { + width: 100%; + height: 52px; + padding: 12px 16px; + font-size: 14px; + color: var(--slate12); + background-color: var(--slate2); + border: 1px solid var(--slate6); + border-radius: 6px; + outline: none; + transition: all 0.15s ease; + cursor: pointer; + + &:hover:not(:disabled) { + border-color: var(--slate7); + } + + &:focus { + border-color: var(--indigo9); + box-shadow: 0 0 0 3px var(--indigo3); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } +} + +.branch-modal-form-input { + width: 100%; + height: 32px; + padding: 6px 10px; + font-size: 12px; + color: var(--slate12); + background-color: var(--slate1); + border: 1px solid var(--slate7); + border-radius: 6px; + outline: none; + transition: all 0.15s ease; + line-height: 20px; + + &::placeholder { + color: var(--slate9); + } + + &:hover:not(:disabled) { + border-color: var(--slate8); + } + + &:focus { + border-color: var(--indigo9); + box-shadow: 0 0 0 3px var(--indigo3); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &.form-input-error { + border-color: var(--red9); + + &:focus { + box-shadow: 0 0 0 3px var(--red3); + } + } +} + +.form-error-message { + margin-top: 8px; + font-size: 12px; + color: var(--red11); + display: flex; + align-items: center; + gap: 4px; +} + +.form-helper-text { + margin-top: 2px; + padding-left: 2px; + font-size: 10px; + line-height: 16px; + color: var(--slate10); +} + +.checkbox-label { + display: flex; + align-items: flex-start; + gap: 8px; + cursor: pointer; + user-select: none; + padding: 4px 0; + + &:hover { + .form-checkbox:not(:disabled) { + border-color: var(--slate8); + } + } +} + +.form-checkbox { + width: 16px; + height: 16px; + min-width: 16px; + border: 1px solid var(--slate7); + border-radius: 4px; + background-color: var(--slate3); + cursor: pointer; + transition: all 0.15s ease; + margin-top: 0; + + &:hover:not(:disabled) { + border-color: var(--slate8); + } + + &:checked { + background-color: var(--indigo9); + border-color: var(--indigo9); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } +} + +.checkbox-text { + display: flex; + flex-direction: column; + gap: 0; + font-size: 12px; + line-height: 20px; + color: var(--slate12); + + .checkbox-helper { + font-size: 10px; + line-height: 16px; + color: var(--slate11); + font-weight: normal; + } +} + +.draft-warning-message { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 12px 16px; + background-color: var(--amber2); + border: 1px solid var(--amber6); + border-radius: 6px; + margin-bottom: 20px; + + svg { + flex-shrink: 0; + color: var(--amber11); + margin-top: 2px; + } + + span { + font-size: 12px; + color: var(--amber12); + line-height: 1.5; + } +} + +.info-message { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 12px 16px; + background-color: var(--blue2); + border: 1px solid var(--blue6); + border-radius: 6px; + + svg { + flex-shrink: 0; + color: var(--blue11); + margin-top: 2px; + } + + span { + font-size: 12px; + color: var(--blue12); + line-height: 1.5; + } +} + +.create-branch-info { + background-color: var(--background-accent-weak); + border: none; + border-radius: 6px; + padding: 12px; + font-size: 12px; + line-height: 18px; + color: var(--slate12); + + img { + width: 18px; + height: 18px; + } +} + +.create-branch-modal-footer { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; + padding: 20px 24px; + border-top: 1px solid var(--slate6); + + .col { + display: flex; + align-items: center; + gap: 8px; + } + + .cancel-button, + button[variant='tertiary'] { + min-width: auto; + height: 32px; + padding: 6px 16px; + font-size: 14px; + line-height: 20px; + } + + .create-button, + button[variant='primary'] { + min-width: auto; + height: 32px; + padding: 6px 16px; + font-size: 14px; + line-height: 20px; + } +} + +// Custom Dropdown Styles (matching Figma design) +.custom-dropdown { + position: relative; + width: 100%; +} + +.custom-dropdown-trigger { + width: 100%; + height: 32px; + padding: 7px 10px; + display: flex; + align-items: center; + justify-content: space-between; + background-color: var(--slate1); + border: 1px solid var(--slate7); + border-radius: 6px; + cursor: pointer; + transition: all 0.15s ease; + font-size: 12px; + color: var(--slate12); + + &:hover:not(:disabled) { + border-color: var(--slate8); + } + + &.is-open { + border-color: var(--indigo9); + border-width: 1.5px; + padding: 6.5px 9.5px; + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + svg { + color: var(--slate11); + transition: transform 0.2s ease; + flex-shrink: 0; + } + + &.is-open svg { + transform: rotate(180deg); + } +} + +.custom-dropdown-value { + display: flex; + align-items: center; + gap: 8px; + flex: 1; + overflow: hidden; + + .version-name { + font-size: 12px; + font-weight: 400; + color: var(--slate12); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +.custom-dropdown-menu { + position: absolute; + top: calc(100% + 4px); + left: 0; + right: 0; + background-color: var(--slate1); + border: 1px solid var(--slate6); + border-radius: 10px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + max-height: 280px; + overflow-y: auto; + z-index: 1000; + padding: 8px; + animation: dropdownFadeIn 0.15s ease; + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background-color: var(--slate7); + border-radius: 3px; + } + + &::-webkit-scrollbar-track { + background-color: var(--slate3); + } +} + +@keyframes dropdownFadeIn { + from { + opacity: 0; + transform: translateY(-4px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +.dropdown-item { + display: flex; + align-items: flex-start; + gap: 8px; + padding: 6px 8px; + border-radius: 6px; + cursor: pointer; + transition: background-color 0.15s ease; + + &:hover { + background-color: var(--slate3); + } + + &.is-selected { + background-color: var(--slate2); + } +} + +.check-icon { + flex-shrink: 0; + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + color: var(--indigo9); + margin-top: 1px; +} + +.check-icon-placeholder { + flex-shrink: 0; + width: 16px; + height: 16px; +} + +.item-content { + flex: 1; + display: flex; + flex-direction: column; + gap: 2px; + min-width: 0; +} + +.item-header { + display: flex; + align-items: center; + gap: 8px; + width: 100%; +} + +.item-name { + font-size: 12px; + font-weight: 500; + color: var(--slate12); + line-height: 18px; + flex-shrink: 0; +} + +.item-description { + font-size: 11px; + font-weight: 400; + color: var(--slate10); + line-height: 16px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.status-badge { + display: inline-flex; + align-items: center; + justify-content: center; + height: 18px; + padding: 0 8px; + border-radius: 4px; + font-size: 11px; + font-weight: 500; + line-height: 16px; + flex-shrink: 0; +} + +.status-badge-draft { + background-color: var(--amber3); + color: var(--amber11); +} + +.status-badge-released { + background-color: var(--green3); + color: var(--green11); +} + +.status-badge-published { + background-color: var(--blue3); + color: var(--blue11); +} + +// Dark mode adjustments +.theme-dark { + .custom-dropdown-trigger { + background-color: var(--slate2); + } + + .custom-dropdown-menu { + background-color: var(--slate2); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); + } + + .dropdown-item { + &:hover { + background-color: var(--slate4); + } + + &.is-selected { + background-color: var(--slate3); + } + } +} \ No newline at end of file diff --git a/frontend/src/_styles/draft-version-warning-modal.scss b/frontend/src/_styles/draft-version-warning-modal.scss new file mode 100644 index 0000000000..3c66452476 --- /dev/null +++ b/frontend/src/_styles/draft-version-warning-modal.scss @@ -0,0 +1,158 @@ +// Draft Version Warning Modal Styles +.draft-warning-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; + backdrop-filter: blur(2px); +} + +.draft-warning-modal { + width: 360px; + min-height: 198px; + background-color: var(--slate1); + border-radius: 8px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); + display: flex; + flex-direction: column; + animation: modalFadeIn 0.2s ease; + + &.theme-dark { + background-color: var(--slate2); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + } +} + +@keyframes modalFadeIn { + from { + opacity: 0; + transform: scale(0.95); + } + to { + opacity: 1; + transform: scale(1); + } +} + +.draft-warning-modal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px 0; + + .warning-icon-container { + display: flex; + align-items: center; + justify-content: center; + width: 48px; + height: 48px; + border-radius: 50%; + background-color: var(--amber3); + + svg { + color: var(--amber11); + } + } + + .close-button { + display: flex; + align-items: center; + justify-content: center; + background: none; + border: none; + padding: 4px; + cursor: pointer; + border-radius: 4px; + transition: background-color 0.15s ease; + color: var(--slate11); + align-self: flex-start; + + &:hover { + background-color: var(--slate4); + color: var(--slate12); + } + + &:active { + transform: scale(0.95); + } + } +} + +.draft-warning-modal-body { + flex: 1; + padding: 16px 24px 20px; + display: flex; + flex-direction: column; + gap: 16px; + + .warning-title { + font-size: 18px; + font-weight: 600; + color: var(--slate12); + margin: 0; + line-height: 1.4; + } + + .warning-message { + font-size: 14px; + color: var(--slate11); + line-height: 1.6; + margin: 0; + } + + .warning-info-box { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 12px 16px; + background-color: var(--blue2); + border: 1px solid var(--blue6); + border-radius: 6px; + + svg { + flex-shrink: 0; + color: var(--blue11); + margin-top: 2px; + } + + .info-text { + display: flex; + flex-direction: column; + gap: 4px; + + strong { + font-size: 13px; + font-weight: 600; + color: var(--blue12); + } + + p { + font-size: 12px; + color: var(--blue11); + line-height: 1.5; + margin: 0; + } + } + } +} + +.draft-warning-modal-footer { + display: flex; + align-items: center; + justify-content: flex-end; + padding: 16px 24px; + border-top: 1px solid var(--slate6); + + .close-action-button { + min-width: 80px; + height: 32px; + padding: 8px 16px; + font-size: 13px; + } +} diff --git a/frontend/src/_styles/locked-branch-banner.scss b/frontend/src/_styles/locked-branch-banner.scss new file mode 100644 index 0000000000..ddd38b3409 --- /dev/null +++ b/frontend/src/_styles/locked-branch-banner.scss @@ -0,0 +1,78 @@ +// LockedBranchBanner - Full-width warning banner for read-only branches +// Displays below the editor navigation when branch is locked + +.locked-branch-banner { + width: 100%; + height: 40px; + background: linear-gradient(90deg, #fef3c7 0%, #fde68a 100%); + border-bottom: 1px solid #fbbf24; + display: flex; + align-items: center; + justify-content: center; + z-index: 100; + position: relative; + + &-content { + display: flex; + align-items: center; + gap: 12px; + max-width: 1200px; + padding: 0 20px; + } + + &-icon { + flex-shrink: 0; + color: #92400e; + width: 16px; + height: 16px; + } + + &-text { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; + } + + &-message { + font-size: 14px; + font-weight: 500; + color: #92400e; + line-height: 20px; + } + + &-branch { + font-size: 13px; + color: #78350f; + line-height: 20px; + + strong { + font-weight: 600; + color: #451a03; + } + } +} + +// Dark mode support +.dark-theme { + .locked-branch-banner { + background: linear-gradient(90deg, #451a03 0%, #78350f 100%); + border-bottom-color: #92400e; + + &-icon { + color: #fbbf24; + } + + &-message { + color: #fde68a; + } + + &-branch { + color: #fef3c7; + + strong { + color: #fef3c7; + } + } + } +} diff --git a/frontend/src/_styles/pages-sidebar.scss b/frontend/src/_styles/pages-sidebar.scss index 81ce7290fe..09500eaf16 100644 --- a/frontend/src/_styles/pages-sidebar.scss +++ b/frontend/src/_styles/pages-sidebar.scss @@ -225,7 +225,7 @@ display: flex; flex-direction: column; box-sizing: content-box; - + &.no-preview-settings { height: 100% !important; } @@ -348,6 +348,7 @@ align-items: center; justify-content: start; gap: 10px; + .page-name { font-family: 'IBM Plex Sans'; font-weight: 500; @@ -604,56 +605,21 @@ height: 61px !important; //1px to account for the border at navbar bottom header { - height: 100% !important; - background-color: var(--nav-menu-bg) !important; - border-bottom-color: var(--nav-menu-border); - max-height: none; - position: static; + height: 100% !important; + background-color: var(--nav-menu-bg) !important; + border-bottom-color: var(--nav-menu-border); + max-height: none; + position: static; - .header-container { - background-color: transparent; - padding: 12px 8px !important; - flex-wrap: nowrap !important; - - .icon-btn { - height: 36px !important; - width: 36px !important; - padding: 10px !important; - } - - .navbar-brand { - height: auto !important; - width: auto !important; - } - - .app-title { - font-size: 16px; - line-height: 24px; - min-width: 0; - } - } - } - } - - .mobile-page-menu-popup { - .mobile-header { - height: 61px !important; //1px to account for the border bottom - - header { - height: 100% !important; - max-height: none; - background-color: var(--nav-menu-bg) !important; - border-bottom-color: var(--nav-menu-border); - position: static; - - .header-container { + .header-container { + background-color: transparent; padding: 12px 8px !important; flex-wrap: nowrap !important; .icon-btn { - height: 36px !important; - width: 36px !important; - padding: 10px !important; + height: 36px !important; + width: 36px !important; + padding: 10px !important; } .navbar-brand { @@ -662,15 +628,50 @@ } .app-title { - font-size: 16px; - line-height: 24px; - min-width: 0; + font-size: 16px; + line-height: 24px; + min-width: 0; } - } } - } + } + } - .mobile-navigation-area { + .mobile-page-menu-popup { + .mobile-header { + height: 61px !important; //1px to account for the border bottom + + header { + height: 100% !important; + max-height: none; + background-color: var(--nav-menu-bg) !important; + border-bottom-color: var(--nav-menu-border); + position: static; + + .header-container { + padding: 12px 8px !important; + flex-wrap: nowrap !important; + + .icon-btn { + height: 36px !important; + width: 36px !important; + padding: 10px !important; + } + + .navbar-brand { + height: auto !important; + width: auto !important; + } + + .app-title { + font-size: 16px; + line-height: 24px; + min-width: 0; + } + } + } + } + + .mobile-navigation-area { width: 100%; z-index: 1; background-color: var(--nav-menu-bg); @@ -678,137 +679,137 @@ flex-direction: column; box-sizing: content-box; padding: 8px 0; - - .pages-wrapper { - width: 100%; - padding: 0 8px; - display: flex; - align-items: center; - flex-direction: column; - gap: 6px; - } - - .tj-list-item { - height: 36px; - justify-content: start; - padding: 8px 12px; - gap: 10px; - margin: 0px !important; - color: var(--nav-item-label-color); - border-radius: var(--nav-item-pill-radius); - - &:hover { - background-color: var(--hovered-nav-item-pill-bg); - } - - &.tj-list-item-selected { - color: var(--selected-nav-item-label-color); - background-color: var(--selected-nav-item-pill-bg); - } - - .page-name { - font-size: 14px; - font-weight: 500; - line-height: 20px; - } - } - - .custom-icon { - line-height: 10px !important; - } - - .accordion-item { - width: 100%; - margin: 0 !important; - border-radius: 0 !important; - border: none; - - .accordion-body{ - padding: 0 0 0 32px !important; - border-bottom: 0px !important; - - .tj-list-item { - margin-top: 6px !important; - } - &.collapsed { - display: none; - } - } - } - - .page-group-wrapper { - height: 36px; - width: 100%; - padding: 8px 12px; - display: flex; - justify-content: space-between; - align-items: center; - gap: 4px; - border: none; - background-color: transparent; - border-radius: var(--nav-item-pill-radius); - color: var(--nav-item-label-color); - text-align: left; - - .group-info { + .pages-wrapper { width: 100%; + padding: 0 8px; display: flex; align-items: center; - justify-content: start; - gap: 10px; - - .page-name { - font-family: 'IBM Plex Sans'; - font-weight: 500; - font-size: 14px; - line-height: 20px; - } - } - - &:hover { - background-color: var(--hovered-nav-item-pill-bg); - } - - &.page-group-selected[data-state="closed"] { - color: var(--selected-nav-item-label-color); - background-color: var(--selected-nav-item-pill-bg); - } - - .tj-list-item { - padding-right: 0px !important; - } + flex-direction: column; + gap: 6px; } - - a.page-link { - border-radius: 0; - border: 0; - } - - a.page-link:hover { - color: white; - background-color: #4D72FA; - } - - a.page-link.active { - color: white; - background-color: #4D72FA; - } - } - .page-dark-mode-btn-wrapper { + .tj-list-item { + height: 36px; + justify-content: start; + padding: 8px 12px; + gap: 10px; + margin: 0px !important; + color: var(--nav-item-label-color); + border-radius: var(--nav-item-pill-radius); + + &:hover { + background-color: var(--hovered-nav-item-pill-bg); + } + + &.tj-list-item-selected { + color: var(--selected-nav-item-label-color); + background-color: var(--selected-nav-item-pill-bg); + } + + .page-name { + font-size: 14px; + font-weight: 500; + line-height: 20px; + } + } + + .custom-icon { + line-height: 10px !important; + } + + .accordion-item { + width: 100%; + margin: 0 !important; + border-radius: 0 !important; + border: none; + + .accordion-body { + padding: 0 0 0 32px !important; + border-bottom: 0px !important; + + .tj-list-item { + margin-top: 6px !important; + } + + &.collapsed { + display: none; + } + } + } + + .page-group-wrapper { + height: 36px; + width: 100%; + padding: 8px 12px; + display: flex; + justify-content: space-between; + align-items: center; + gap: 4px; + border: none; + background-color: transparent; + border-radius: var(--nav-item-pill-radius); + color: var(--nav-item-label-color); + text-align: left; + + .group-info { + width: 100%; + display: flex; + align-items: center; + justify-content: start; + gap: 10px; + + .page-name { + font-family: 'IBM Plex Sans'; + font-weight: 500; + font-size: 14px; + line-height: 20px; + } + } + + &:hover { + background-color: var(--hovered-nav-item-pill-bg); + } + + &.page-group-selected[data-state="closed"] { + color: var(--selected-nav-item-label-color); + background-color: var(--selected-nav-item-pill-bg); + } + + .tj-list-item { + padding-right: 0px !important; + } + } + + a.page-link { + border-radius: 0; + border: 0; + } + + a.page-link:hover { + color: white; + background-color: #4D72FA; + } + + a.page-link.active { + color: white; + background-color: #4D72FA; + } + } + + .page-dark-mode-btn-wrapper { background-color: var(--nav-menu-bg); display: flex; border-top: 1px solid var(--nav-menu-border); height: 57px; padding: 10px; justify-content: center; - } + } - .page-menu-scroll { + .page-menu-scroll { scrollbar-color: var(--interactive-hover) transparent !important; scrollbar-width: thin !important; - + &::-webkit-scrollbar-track { background: transparent !important; } @@ -816,8 +817,8 @@ &::-webkit-scrollbar-thumb { background: var(--interactive-hover) !important; } - } - } + } + } } .viewer { @@ -841,6 +842,7 @@ } } } + &.offset-top-bar-navigation { #sidebar-page-navigation { .navigation-area { @@ -954,10 +956,12 @@ height: 100%; z-index: 1000; - &:hover, &.active { + &:hover, + &.active { .navigation-area.navigation-hover-trigger { box-shadow: 0 0 0 1px #4af !important; } + .mobile-nav-container.navigation-hover-trigger { border: 1px solid #4af; } diff --git a/frontend/src/_styles/switch-branch-modal.scss b/frontend/src/_styles/switch-branch-modal.scss new file mode 100644 index 0000000000..8a5f786551 --- /dev/null +++ b/frontend/src/_styles/switch-branch-modal.scss @@ -0,0 +1,225 @@ +// Switch Branch Modal Styles +.switch-branch-modal { + .modal-dialog { + max-width: 424px; + width: 100%; + } + + .modal-content { + border-radius: 6px; + background: var(--slate1); + box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03); + } + + .modal-header { + border-bottom: 1px solid var(--slate6); + padding: 16px 24px 8px; + + .modal-title { + font-family: 'Inter', sans-serif; + font-size: 16px; + font-weight: 500; + line-height: 24px; + color: #11181c; + } + } + + .modal-body { + padding: 16px 12px; + } +} + +.switch-branch-modal-content { + display: flex; + flex-direction: column; + gap: 12px; + + // Search Section + .search-section { + display: flex; + flex-direction: column; + gap: 8px; + padding: 0 4px; + + .section-label { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate11); + text-transform: uppercase; + letter-spacing: -0.24px; + } + + .search-input-wrapper { + position: relative; + display: flex; + align-items: center; + gap: 12px; + padding: 7px 12px; + background: var(--slate1); + border: 1px solid var(--slate7); + border-radius: 6px; + height: 32px; + + svg { + flex-shrink: 0; + } + + .search-input { + flex: 1; + border: none; + background: none; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + line-height: 18px; + color: var(--slate12); + outline: none; + + &::placeholder { + color: var(--slate11); + } + } + } + } + + // Branch List + .branch-list-section { + display: flex; + flex-direction: column; + gap: 4px; + max-height: 300px; + overflow-y: auto; + + .branch-list-item { + display: flex; + gap: 8px; + padding: 6px 4px; + border-radius: 6px; + cursor: pointer; + transition: background-color 0.15s ease; + + &:hover { + background-color: var(--slate3); + } + + &.active { + .branch-list-name { + font-weight: 500; + } + } + + .branch-checkbox { + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + } + + .branch-list-content { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + gap: 2px; + + .branch-list-name { + font-family: 'Inter', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + color: var(--slate12); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .branch-list-meta { + font-family: 'IBM Plex Sans', sans-serif; + font-size: 11px; + font-weight: 400; + line-height: 16px; + color: var(--slate11); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + } + + .loading-state, + .empty-state { + display: flex; + align-items: center; + justify-content: center; + padding: 32px 16px; + color: var(--slate11); + font-size: 13px; + + .spinner { + width: 20px; + height: 20px; + border: 2px solid var(--slate6); + border-top-color: var(--indigo9); + border-radius: 50%; + animation: spin 0.6s linear infinite; + margin-right: 8px; + } + } + } + + // Modal Footer + .modal-footer-actions { + border-top: 1px solid var(--slate6); + display: flex; + gap: 8px; + padding: 16px 0 0; + + .footer-btn { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 5px 10px; + border-radius: 6px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 18px; + cursor: pointer; + transition: all 0.15s ease; + border: 1px solid var(--slate6); + background: var(--slate1); + color: var(--slate12); + + &:hover { + background: var(--slate3); + } + + &.accent { + border-color: var(--indigo7); + + &:hover { + background: var(--indigo2); + } + + svg { + fill: var(--indigo9); + } + } + + svg { + flex-shrink: 0; + } + } + } +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss index 782cf796eb..076c9058a2 100644 --- a/frontend/src/_styles/theme.scss +++ b/frontend/src/_styles/theme.scss @@ -14516,131 +14516,6 @@ tbody { } } -.git-sync-modal, -.modal-base { - - .create-commit-container, - .commit-info, - .pull-container, - .pushpull-container { - height: 260px !important; - - .form-control { - font-weight: 400; - font-size: 12px; - line-height: 20px; - color: var(--slate12); - } - - .form-group { - .tj-input-error-state { - border: 1px solid var(--tomato9) !important; - } - - .tj-input-error { - color: var(--tomato10) !important; - } - } - - .info-text { - color: var(--slate10); - } - - .tj-input-error { - color: var(--tomato10); - } - - .form-control.disabled { - background-color: var(--slate3) !important; - color: var(--slate9) !important; - } - - .last-commit-info { - background: var(--slate3); - - .message-info { - display: flex; - justify-content: space-between; - } - - .author-info { - font-size: 10px; - color: var(--slate11); - } - } - - .check-for-updates { - display: flex; - align-items: center; - color: var(--indigo9); - - svg { - path { - fill: var(--indigo9); - } - - rect { - fill: none; - } - } - - .loader-container { - height: unset !important; - - .primary-spin-loader { - width: 18px; - height: 18px; - margin-right: 5px; - } - } - } - } - - .modal-footer { - border-top: 1px solid var(--slate5); - padding: 1rem; - - .tj-btn-left-icon { - svg { - width: 20px; - height: 20px; - - path { - fill: var(--indigo1); - } - } - } - - .tj-large-btn { - font-weight: 500; - font-size: 14px; - } - } - - .modal-body { - .loader-container { - display: flex; - justify-content: center; - align-items: center; - height: 180px; - } - } - - .modal-base { - .tj-text-xxsm { - color: var(--slate11); - } - } - - .modal-header { - border-bottom: 1px solid var(--slate5) !important; - - .modal-title { - color: var(--slate12); - } - } -} - .custom-gap-7 { gap: 7px; } @@ -17913,22 +17788,6 @@ section.ai-message-prompt-input-wrapper { } } -.git-sync-modal { - width: 400px !important; - height: 484px !important; -} - -.dark-theme.git-sync-modal { - .modal-header { - border-bottom: 1px solid var(--slate5) !important; - } -} - -.git-sync-modal .modal-header .modal-title .push-pull-tabs .tab-push.active, -.git-sync-modal .modal-header .modal-title .push-pull-tabs .tab-pull.active { - border-bottom: 2px solid var(--indigo9) !important; -} - .custom_fc_frame { left: 40px !important; } diff --git a/frontend/src/_styles/versions.scss b/frontend/src/_styles/versions.scss index fbb7deedcc..f4dcc38488 100644 --- a/frontend/src/_styles/versions.scss +++ b/frontend/src/_styles/versions.scss @@ -18,7 +18,7 @@ background-color: #ffffff; color: var(--text-default); cursor: pointer; - box-shadow: var(--elevation-100-box-shadow); + box-shadow: var(--elevation-100-box-shadow); transition: box-shadow 0.12s ease, transform 0.08s ease; border-radius: 4px !important; outline: none; @@ -293,7 +293,7 @@ border-radius: 8px !important; padding: 0 !important; max-width: 300px !important; - box-shadow: var(--elevation-400-box-shadow) !important; + box-shadow: var(--elevation-400-box-shadow) !important; text-align: left !important; } @@ -309,14 +309,17 @@ .tooltip.version-tooltip.bs-tooltip-start .tooltip-arrow::after { border-left-color: #ffffff !important; } + .tooltip.version-tooltip.bs-tooltip-right .tooltip-arrow::before, .tooltip.version-tooltip.bs-tooltip-right .tooltip-arrow::after { border-right-color: #ffffff !important; } + .tooltip.version-tooltip.bs-tooltip-top .tooltip-arrow::before, .tooltip.version-tooltip.bs-tooltip-top .tooltip-arrow::after { border-top-color: #ffffff !important; } + .tooltip.version-tooltip.bs-tooltip-bottom .tooltip-arrow::before, .tooltip.version-tooltip.bs-tooltip-bottom .tooltip-arrow::after { border-bottom-color: #ffffff !important; diff --git a/frontend/src/_ui/Icon/solidIcons/Check2.jsx b/frontend/src/_ui/Icon/solidIcons/Check2.jsx new file mode 100644 index 0000000000..0596d2b887 --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/Check2.jsx @@ -0,0 +1,23 @@ +import React from 'react'; + +const Check2 = ({ fill = '#3E63DD', width = '16', className = '', viewBox = '0 0 16 16', height }) => { + return ( + + + + ); +}; + +export default Check2; diff --git a/frontend/src/_ui/Icon/solidIcons/ChevronDownSmall.jsx b/frontend/src/_ui/Icon/solidIcons/ChevronDownSmall.jsx new file mode 100644 index 0000000000..0878293daa --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/ChevronDownSmall.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +const ChevronDownSmall = ({ fill = '#C1C8CD', width = '12', className = '', viewBox = '0 0 12 12' }) => ( + + + +); + +export default ChevronDownSmall; diff --git a/frontend/src/_ui/Icon/solidIcons/CircleDot.jsx b/frontend/src/_ui/Icon/solidIcons/CircleDot.jsx new file mode 100644 index 0000000000..677103a680 --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/CircleDot.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +const CircleDot = ({ fill = '#C1C8CD', width = '14', className = '', viewBox = '0 0 16 16' }) => ( + + + +); + +export default CircleDot; diff --git a/frontend/src/_ui/Icon/solidIcons/Commit.jsx b/frontend/src/_ui/Icon/solidIcons/Commit.jsx new file mode 100644 index 0000000000..86e9f4f03a --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/Commit.jsx @@ -0,0 +1,22 @@ +import React from 'react'; + +const Commit = ({ fill = 'var(--icon-default)', width = '25', className = '', viewBox = '0 0 25 25' }) => ( + + + +); + +export default Commit; diff --git a/frontend/src/_ui/Icon/solidIcons/ExternalLinkIcon.jsx b/frontend/src/_ui/Icon/solidIcons/ExternalLinkIcon.jsx new file mode 100644 index 0000000000..d55c7474b8 --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/ExternalLinkIcon.jsx @@ -0,0 +1,28 @@ +import React from 'react'; + +const ExternalLinkIcon = ({ fill = '#C1C8CD', width = '16', className = '', viewBox = '0 0 16 16' }) => ( + + + + +); + +export default ExternalLinkIcon; diff --git a/frontend/src/_ui/Icon/solidIcons/GitBranch.jsx b/frontend/src/_ui/Icon/solidIcons/GitBranch.jsx new file mode 100644 index 0000000000..693d6ebe27 --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/GitBranch.jsx @@ -0,0 +1,19 @@ +import React from 'react'; + +const GitBranch = ({ fill = '#C1C8CD', width = '16', className = '', viewBox = '0 0 16 16' }) => ( + + + +); + +export default GitBranch; diff --git a/frontend/src/_ui/Icon/solidIcons/GitMergeIcon.jsx b/frontend/src/_ui/Icon/solidIcons/GitMergeIcon.jsx new file mode 100644 index 0000000000..a5741a36c1 --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/GitMergeIcon.jsx @@ -0,0 +1,21 @@ +import React from 'react'; + +const GitMergeIcon = ({ fill = '#C1C8CD', width = '16', className = '', viewBox = '0 0 16 16' }) => ( + + + +); + +export default GitMergeIcon; diff --git a/frontend/src/_ui/Icon/solidIcons/LockClosed.jsx b/frontend/src/_ui/Icon/solidIcons/LockClosed.jsx new file mode 100644 index 0000000000..32414b9c6d --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/LockClosed.jsx @@ -0,0 +1,19 @@ +import React from 'react'; + +const LockClosed = ({ fill = '#C1C8CD', width = '16', className = '', viewBox = '0 0 16 16' }) => ( + + + +); + +export default LockClosed; diff --git a/frontend/src/_ui/Icon/solidIcons/PlusIcon.jsx b/frontend/src/_ui/Icon/solidIcons/PlusIcon.jsx new file mode 100644 index 0000000000..5860b5d67e --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/PlusIcon.jsx @@ -0,0 +1,19 @@ +import React from 'react'; + +const PlusIcon = ({ fill = '#C1C8CD', width = '14', className = '', viewBox = '0 0 14 14' }) => ( + + + +); + +export default PlusIcon; diff --git a/frontend/src/_ui/Icon/solidIcons/Refresh.jsx b/frontend/src/_ui/Icon/solidIcons/Refresh.jsx new file mode 100644 index 0000000000..b2bf9ead1f --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/Refresh.jsx @@ -0,0 +1,21 @@ +import React from 'react'; + +const Refresh = ({ fill = 'var(--icon-default)', width = '14', className = '', viewBox = '0 0 14 14' }) => ( + + + +); + +export default Refresh; diff --git a/frontend/src/_ui/Icon/solidIcons/RocketIcon.jsx b/frontend/src/_ui/Icon/solidIcons/RocketIcon.jsx new file mode 100644 index 0000000000..d14fba96e1 --- /dev/null +++ b/frontend/src/_ui/Icon/solidIcons/RocketIcon.jsx @@ -0,0 +1,33 @@ +import React from 'react'; + +const RocketIcon = ({ fill = '#C1C8CD', width = '16', className = '', viewBox = '0 0 16 16' }) => ( + + + + + + +); + +export default RocketIcon; diff --git a/frontend/src/_ui/Icon/solidIcons/index.js b/frontend/src/_ui/Icon/solidIcons/index.js index 2383e1b4d9..f3f1fd82b4 100644 --- a/frontend/src/_ui/Icon/solidIcons/index.js +++ b/frontend/src/_ui/Icon/solidIcons/index.js @@ -27,12 +27,15 @@ import CheveronDown from './CheveronDown.jsx'; import CheveronLeft from './CheveronLeft.jsx'; import CheveronRight from './CheveronRight.jsx'; import CheveronUp from './CheveronUp.jsx'; +import ChevronDownSmall from './ChevronDownSmall.jsx'; +import CircleDot from './CircleDot.jsx'; import ClearRectangle from './ClearRectangle.jsx'; import CaretDown from './CaretDown.jsx'; import CaretUp from './CaretUp.jsx'; import Clock from './Clock.jsx'; import CursorClick from './CursorClick.jsx'; import LockGradient from './LockGradient.jsx'; +import LockClosed from './LockClosed.jsx'; import DatasourceGradient from './DatasourceGradient.jsx'; import CoinIcon from './CoinIcon.jsx'; import Column from './Column.jsx'; @@ -52,6 +55,7 @@ import EnterpriseSmall from './EnterpriseSmall.jsx'; import Eye from './Eye.jsx'; import Eye1 from './Eye1.jsx'; import EyeDisable from './EyeDisable.jsx'; +import ExternalLinkIcon from './ExternalLinkIcon.jsx'; import Expand from './Expand.jsx'; import File01 from './File01.jsx'; import FileDownload from './FileDownload.jsx'; @@ -62,6 +66,8 @@ import Folder from './Folder.jsx'; import FolderDownload from './FolderDownload.jsx'; import FolderUpload from './FolderUpload.jsx'; import GitSync from './GitSync.jsx'; +import GitBranch from './GitBranch.jsx'; +import GitMergeIcon from './GitMergeIcon.jsx'; import FullOuterJoin from './FullOuterJoin.jsx'; import Globe from './Globe.jsx'; import Options from './Options.jsx'; @@ -98,6 +104,7 @@ import Page from './Page.jsx'; import PageAdd from './PageAdd.jsx'; import PageUpload from './PageUpload.jsx'; import Pin from './Pin.jsx'; +import PlusIcon from './PlusIcon.jsx'; import Unpin from './Unpin.jsx'; import AlignRight from './AlignRight'; import Play from './Play.jsx'; @@ -111,6 +118,7 @@ import Remove from './Remove.jsx'; import Remove01 from './Remove01.jsx'; import Remove03 from './Remove03.jsx'; import RemoveRectangle from './RemoveRectangle.jsx'; +import Refresh from './Refresh.jsx'; import RightArrow from './RightArrow.jsx'; import RightOuterJoin from './RightOuterJoin.jsx'; import Row from './Row.jsx'; @@ -170,6 +178,7 @@ import CloudInvalid from './CloudInvalid.jsx'; import CloudValid from './CloudValid.jsx'; import LayersVersion from './LayersVersion.jsx'; import Comments from './Comments'; +import Commit from './Commit'; import Inspect from './Inspect.jsx'; import ArrowForwardUp from './ArrowForwardUp.jsx'; import ArrowBackUp from './ArrowBackUp.jsx'; @@ -177,6 +186,7 @@ import CheveronLeftDouble from './CheveronLeftDouble.jsx'; import CheveronRightDouble from './CheveronRightDouble.jsx'; import Dot from './Dot.jsx'; import Check from './Check.jsx'; +import Check2 from './Check2.jsx'; import Editable from './Editable.jsx'; import Save from './Save.jsx'; import Cross from './Cross.jsx'; @@ -229,6 +239,7 @@ import AITag from './AITag.jsx'; import SectionCollapse from './SectionCollapse.jsx'; import SectionExpand from './SectionExpand.jsx'; import Reset from './Reset.jsx'; +import RocketIcon from './RocketIcon.jsx'; import Outbound from './Outbound.jsx'; import AddPageGroupIcon from './AddPageGroup.jsx'; import PageIcon from './PageIcon.jsx'; @@ -393,6 +404,10 @@ const Icon = (props) => { return ; case 'cheveronup': return ; + case 'chevrondownsmall': + return ; + case 'circledot': + return ; case 'circularToggleDisabled': return ; case 'circularToggleEnabled': @@ -455,6 +470,8 @@ const Icon = (props) => { return ; case 'lockGradient': return ; + case 'lockclosed': + return ; case 'datasourceGradient': return ; case 'enterbutton': @@ -465,6 +482,8 @@ const Icon = (props) => { return ; case 'eyedisable': return ; + case 'externallink': + return ; case 'expand': return ; case 'file-code': @@ -487,6 +506,10 @@ const Icon = (props) => { return ; case 'gitsync': return ; + case 'gitbranch': + return ; + case 'gitmerge': + return ; case 'foreignkey': return ; case 'fullouterjoin': @@ -587,6 +610,8 @@ const Icon = (props) => { return ; case 'plus': return ; + case 'plusicon': + return ; case 'plus01': return ; case 'plusrectangle': @@ -597,6 +622,8 @@ const Icon = (props) => { return ; case 'reload': return ; + case 'refresh': + return ; case 'read': return ; case 'reloaderror': @@ -617,6 +644,8 @@ const Icon = (props) => { return ; case 'reset': return ; + case 'rocket': + return ; case 'retry': return ; case 'sadrectangle': @@ -645,6 +674,8 @@ const Icon = (props) => { return ; case 'comments': return ; + case 'commit': + return ; case 'corners': return ; case 'share': @@ -735,6 +766,8 @@ const Icon = (props) => { return ; case 'check': return ; + case 'check2': + return ; case 'editable': return ; case 'minimize': diff --git a/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx b/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx index 9edd06cb5e..e7441055e6 100644 --- a/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx +++ b/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx @@ -67,6 +67,7 @@ const PromoteConfirmationModal = React.memo(({ data, onClose, editingVersion }) versionId: versionToPromote?.id, lastCommitMessage: ` ${versionToPromote.name} Version of app ${appGit?.git_app_name} promoted from development to staging`, gitVersionName: versionToPromote?.name, + allowMasterPush: true, }; await gitSyncService.gitPush(body, appGit?.id, versionToPromote?.id); toast.success('Changes committed successfully'); diff --git a/server/data-migrations/1769151383974-NormalizeFolderAppsKeepFirstCreatedMappingPerApp.ts b/server/data-migrations/1769151383974-NormalizeFolderAppsKeepFirstCreatedMappingPerApp.ts new file mode 100644 index 0000000000..d3f8ce207f --- /dev/null +++ b/server/data-migrations/1769151383974-NormalizeFolderAppsKeepFirstCreatedMappingPerApp.ts @@ -0,0 +1,30 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class NormalizeFolderAppsKeepFirstCreatedMappingPerApp1769151383974 implements MigrationInterface { + +public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DELETE FROM folder_apps + WHERE id IN ( + SELECT id FROM ( + SELECT id, + ROW_NUMBER() OVER ( + PARTITION BY app_id + ORDER BY created_at ASC + ) AS rn + FROM folder_apps + ) t + WHERE t.rn > 1 + ); + `); + await queryRunner.query(` + CREATE UNIQUE INDEX IF NOT EXISTS uniq_folder_apps_app_id + ON folder_apps (app_id); + `); +} +public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DROP INDEX IF EXISTS uniq_folder_apps_app_id; + `); + } +} diff --git a/server/migrations/1743997765065-AddCoRelationIdToComponents.ts b/server/migrations/1743997765065-AddCoRelationIdToComponents.ts new file mode 100644 index 0000000000..30ad68ca72 --- /dev/null +++ b/server/migrations/1743997765065-AddCoRelationIdToComponents.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddCoRelationIdToAppEntities1743997765065 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE components ADD COLUMN IF NOT EXISTS "co_relation_id" uuid DEFAULT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE components DROP COLUMN IF EXISTS "co_relation_id"`); + } + +} diff --git a/server/migrations/1761828716101-AddBranchingAndSchemaVersionToOrgGitSync.ts b/server/migrations/1761828716101-AddBranchingAndSchemaVersionToOrgGitSync.ts new file mode 100644 index 0000000000..ed434e58f2 --- /dev/null +++ b/server/migrations/1761828716101-AddBranchingAndSchemaVersionToOrgGitSync.ts @@ -0,0 +1,28 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddBranchingAndSchemaVersionToOrgGitSync1761828716101 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + // Add isBranchingEnabled column to organization_git_sync table + await queryRunner.query( + `ALTER TABLE "organization_git_sync" + ADD COLUMN IF NOT EXISTS "is_branching_enabled" boolean NOT NULL DEFAULT true` + ); + // default value is set to true for now, this migration should be changed before releasing for lts and default should be false. + + // Add schema_version column to organization_git_sync table + await queryRunner.query( + `ALTER TABLE "organization_git_sync" + ADD COLUMN IF NOT EXISTS "schema_version" varchar NOT NULL DEFAULT '1.0.0'` + ); + + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "organization_git_sync" DROP COLUMN IF EXISTS "is_branching_enabled"` + ); + + await queryRunner.query( + `ALTER TABLE "organization_git_sync" DROP COLUMN IF EXISTS "schema_version"` + ); + } +} diff --git a/server/migrations/1761828800001-AddVersionTypeColumn.ts b/server/migrations/1761828800001-AddVersionTypeColumn.ts new file mode 100644 index 0000000000..02964422c0 --- /dev/null +++ b/server/migrations/1761828800001-AddVersionTypeColumn.ts @@ -0,0 +1,24 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddVersionTypeColumn1761828800001 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TYPE app_version_type AS ENUM ('version', 'branch') + `); + + await queryRunner.query(` + ALTER TABLE "app_versions" + ADD COLUMN "version_type" app_version_type NOT NULL DEFAULT 'version' + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE "app_versions" + DROP COLUMN IF EXISTS "version_type" + `); + await queryRunner.query(` + DROP TYPE IF EXISTS app_version_type + `); + } +} \ No newline at end of file diff --git a/server/migrations/1762860937123-AddCreatedByToAppVersions.ts b/server/migrations/1762860937123-AddCreatedByToAppVersions.ts new file mode 100644 index 0000000000..6f0b70de06 --- /dev/null +++ b/server/migrations/1762860937123-AddCreatedByToAppVersions.ts @@ -0,0 +1,30 @@ +import { MigrationInterface, QueryRunner, TableColumn, TableForeignKey } from 'typeorm'; + +export class AddCreatedByToAppVersions1762860937123 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn( + 'app_versions', + new TableColumn({ + name: 'created_by', + type: 'uuid', + isNullable: true, + }) + ); + + await queryRunner.createForeignKey( + 'app_versions', + new TableForeignKey({ + name: 'fk_app_versions_created_by', + columnNames: ['created_by'], + referencedColumnNames: ['id'], + referencedTableName: 'users', + onDelete: 'SET NULL', + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropForeignKey('app_versions', 'fk_app_versions_created_by'); + await queryRunner.dropColumn('app_versions', 'created_by'); + } +} diff --git a/server/migrations/1763549159927-AddCoRelationIdToAppEntities.ts b/server/migrations/1763549159927-AddCoRelationIdToAppEntities.ts new file mode 100644 index 0000000000..886945205f --- /dev/null +++ b/server/migrations/1763549159927-AddCoRelationIdToAppEntities.ts @@ -0,0 +1,39 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddCoRelationIdToAppEntities1763549159927 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + const tables = [ + 'pages', + 'data_queries', + 'data_sources', + 'data_source_options', + 'internal_tables', + 'app_versions', + 'event_handlers', + 'layouts' + ]; + + for (const table of tables) { + await queryRunner.query(`ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS "co_relation_id" uuid DEFAULT NULL`); + } + } + + public async down(queryRunner: QueryRunner): Promise { + const tables = [ + 'pages', + 'data_queries', + 'data_sources', + 'data_source_options', + 'internal_tables', + 'app_versions', + 'event_handlers', + 'layouts' + ]; + + for (const table of tables) { + await queryRunner.query(`ALTER TABLE "${table}" DROP COLUMN IF EXISTS "co_relation_id"`); + } + } + +} diff --git a/server/migrations/1765630548010-AddSourceTagToAppVersions.ts b/server/migrations/1765630548010-AddSourceTagToAppVersions.ts new file mode 100644 index 0000000000..78587d5ef1 --- /dev/null +++ b/server/migrations/1765630548010-AddSourceTagToAppVersions.ts @@ -0,0 +1,24 @@ +import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm'; + +export class AddSourceTagToAppVersions1765630548010 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn( + 'app_versions', + new TableColumn({ + name: 'source_tag', + type: 'varchar', + length: '256', + isNullable: true, + default: null, + }) + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('app_versions', 'source_tag'); + } +} +/** + * Adds source_tag column to track version's sync state with GitHub tags: + * - null: Version created locally, not synced → creates GitHub tag on save + * - "{app_name}/{version_name}": Version synced with this tag (updated on every pull) → no tag created on save + */ \ No newline at end of file diff --git a/server/migrations/1768289065973-AddCoRelationIdToApps.ts b/server/migrations/1768289065973-AddCoRelationIdToApps.ts new file mode 100644 index 0000000000..cd65223d6f --- /dev/null +++ b/server/migrations/1768289065973-AddCoRelationIdToApps.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddCoRelationIdToApps1768289065973 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE apps ADD COLUMN IF NOT EXISTS "co_relation_id" uuid DEFAULT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE apps DROP COLUMN IF EXISTS "co_relation_id"`); + } + +} diff --git a/server/src/dto/organization_git.dto.ts b/server/src/dto/organization_git.dto.ts index 876ad5f62f..c36e1a14e1 100644 --- a/server/src/dto/organization_git.dto.ts +++ b/server/src/dto/organization_git.dto.ts @@ -26,17 +26,20 @@ export class OrganizationGitUpdateDto { @IsString() @IsIn(['ed25519', 'rsa']) keyType: 'ed25519' | 'rsa'; + + @IsOptional() + @IsBoolean() + branchingEnabled?: boolean; } -export class OrganizationGitHTTPSUpdateDto { +export class OrganizationGitConfigUpdateDto { @IsOptional() @IsBoolean() - autoCommit: boolean; -} -export class OrganizationGitLabUpdateDto { + autoCommit?: boolean; + @IsOptional() @IsBoolean() - autoCommit: boolean; + branchingEnabled?: boolean; } export class OrganizationGitStatusUpdateDto { diff --git a/server/src/entities/app.entity.ts b/server/src/entities/app.entity.ts index 33b369e7fe..dd1cfdb92b 100644 --- a/server/src/entities/app.entity.ts +++ b/server/src/entities/app.entity.ts @@ -75,6 +75,9 @@ export class App extends BaseEntity { @Column({ name: 'app_generated_from_prompt', default: false }) appGeneratedFromPrompt: boolean; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @Column({ type: 'enum', enumName: 'app_builder_mode', diff --git a/server/src/entities/app_version.entity.ts b/server/src/entities/app_version.entity.ts index 18c12c8345..61e9a12269 100644 --- a/server/src/entities/app_version.entity.ts +++ b/server/src/entities/app_version.entity.ts @@ -22,13 +22,21 @@ import { DataSource } from './data_source.entity'; import { Page } from './page.entity'; import { EventHandler } from './event_handler.entity'; import { WorkflowSchedule } from './workflow_schedule.entity'; +import { User } from './user.entity'; +export enum AppVersionType { + VERSION = 'version', + BRANCH = 'branch', +} @Entity({ name: 'app_versions' }) @Unique(['name', 'appId']) export class AppVersion extends BaseEntity { @PrimaryGeneratedColumn('uuid') id: string; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @Column({ name: 'name' }) name: string; @@ -47,6 +55,14 @@ export class AppVersion extends BaseEntity { @Column({ name: 'home_page_id' }) homePageId: string; + @Column({ + name: 'version_type', + type: 'enum', + enum: AppVersionType, + default: AppVersionType.VERSION, + }) + versionType: AppVersionType; + @Column({ name: 'app_id' }) appId: string; @@ -59,6 +75,14 @@ export class AppVersion extends BaseEntity { @Column({ name: 'parent_version_id', type: 'uuid', nullable: true }) parentVersionId: string; + @Column({ name: 'created_by', type: 'uuid', nullable: true }) + createdBy: string; + + @ManyToOne(() => User, { nullable: true, onDelete: 'SET NULL' }) + @JoinColumn({ name: 'created_by' }) + user: User; + + // need to review if this should be a non-nullable field with default value as DRAFT status @Column({ name: 'status', type: 'enum', diff --git a/server/src/entities/component.entity.ts b/server/src/entities/component.entity.ts index 6ef8d20b0c..c3bd5b09d1 100644 --- a/server/src/entities/component.entity.ts +++ b/server/src/entities/component.entity.ts @@ -19,6 +19,9 @@ export class Component { @PrimaryGeneratedColumn('uuid') id: string; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @Column() name: string; diff --git a/server/src/entities/data_query.entity.ts b/server/src/entities/data_query.entity.ts index 591cdb49b9..e0794a54f9 100644 --- a/server/src/entities/data_query.entity.ts +++ b/server/src/entities/data_query.entity.ts @@ -35,6 +35,9 @@ export class DataQuery extends BaseEntity { @Column({ name: 'app_version_id' }) appVersionId: string; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @CreateDateColumn({ default: () => 'now()', name: 'created_at' }) createdAt: Date; diff --git a/server/src/entities/data_source.entity.ts b/server/src/entities/data_source.entity.ts index a653dd5864..65443eabfc 100644 --- a/server/src/entities/data_source.entity.ts +++ b/server/src/entities/data_source.entity.ts @@ -27,6 +27,9 @@ export class DataSource extends BaseEntity { @PrimaryGeneratedColumn('uuid') id: string; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @Column({ name: 'name' }) name: string; diff --git a/server/src/entities/data_source_options.entity.ts b/server/src/entities/data_source_options.entity.ts index 4341ec9787..76ed1b4994 100644 --- a/server/src/entities/data_source_options.entity.ts +++ b/server/src/entities/data_source_options.entity.ts @@ -17,6 +17,9 @@ export class DataSourceOptions { @PrimaryGeneratedColumn('uuid') id: string; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @Column({ name: 'data_source_id' }) dataSourceId: string; diff --git a/server/src/entities/event_handler.entity.ts b/server/src/entities/event_handler.entity.ts index 6585d640e0..79eee1dcf5 100644 --- a/server/src/entities/event_handler.entity.ts +++ b/server/src/entities/event_handler.entity.ts @@ -49,4 +49,7 @@ export class EventHandler { @ManyToOne(() => AppVersion, (appVersion) => appVersion.pages) @JoinColumn({ name: 'app_version_id' }) appVersion: AppVersion; + + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; } diff --git a/server/src/entities/internal_table.entity.ts b/server/src/entities/internal_table.entity.ts index 832734e322..f1f35d8cdc 100644 --- a/server/src/entities/internal_table.entity.ts +++ b/server/src/entities/internal_table.entity.ts @@ -21,6 +21,9 @@ export class InternalTable extends BaseEntity { @Column({ name: 'table_name' }) tableName: string; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @CreateDateColumn({ default: () => 'now()', name: 'created_at' }) createdAt: Date; diff --git a/server/src/entities/layout.entity.ts b/server/src/entities/layout.entity.ts index d85e4cfa94..e66b67263a 100644 --- a/server/src/entities/layout.entity.ts +++ b/server/src/entities/layout.entity.ts @@ -6,6 +6,9 @@ export class Layout { @PrimaryGeneratedColumn('uuid') id: string; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @Column({ type: 'enum', enumName: 'layout_type', enum: ['desktop', 'mobile'] }) type: string; diff --git a/server/src/entities/organization_git_sync.entity.ts b/server/src/entities/organization_git_sync.entity.ts index df2fea367a..4b2d7ccd7a 100644 --- a/server/src/entities/organization_git_sync.entity.ts +++ b/server/src/entities/organization_git_sync.entity.ts @@ -38,6 +38,12 @@ export class OrganizationGitSync extends BaseEntity { @UpdateDateColumn({ default: () => 'now()', name: 'updated_at' }) updatedAt: Date; + @Column({ name: 'is_branching_enabled', nullable: false, default: true }) + isBranchingEnabled: boolean; + + @Column({ name: 'schema_version', nullable: false, default: '1.0.0' }) + schemaVersion: string; + @OneToMany(() => AppGitSync, (appGitSync) => appGitSync.orgGit, { onDelete: 'CASCADE' }) @JoinTable({ name: 'app_git_sync', diff --git a/server/src/entities/page.entity.ts b/server/src/entities/page.entity.ts index b797493ffb..e08de81282 100644 --- a/server/src/entities/page.entity.ts +++ b/server/src/entities/page.entity.ts @@ -90,6 +90,9 @@ export class Page { @Column({ name: 'app_id', type: 'varchar', nullable: true }) // Assuming appId is a varchar/string appId: string | null; + @Column({ name: 'co_relation_id', nullable: true }) + co_relation_id: string; + @ManyToOne(() => AppVersion, (appVersion) => appVersion.pages) @JoinColumn({ name: 'app_version_id' }) appVersion: AppVersion; diff --git a/server/src/modules/app-environments/service.ts b/server/src/modules/app-environments/service.ts index 2aa1390707..d62dcd1a31 100644 --- a/server/src/modules/app-environments/service.ts +++ b/server/src/modules/app-environments/service.ts @@ -20,7 +20,7 @@ export class AppEnvironmentService implements IAppEnvironmentService { async init(editingVersionId: string, organizationId: string): Promise { return await dbTransactionWrap(async (manager: EntityManager) => { const editorVersion = await manager.findOne(AppVersion, { - select: ['id', 'name', 'description', 'status', 'currentEnvironmentId', 'appId'], + select: ['id', 'name', 'description', 'status', 'versionType', 'currentEnvironmentId', 'appId'], where: { id: editingVersionId }, }); return await this.appEnvironmentUtilService.init(editorVersion, organizationId, false, manager); @@ -221,6 +221,7 @@ export class AppEnvironmentService implements IAppEnvironmentService { 'currentEnvironmentId', 'parentVersionId', 'promotedFrom', + 'versionType', 'createdAt', 'updatedAt', 'publishedAt', diff --git a/server/src/modules/app-git/ability/index.ts b/server/src/modules/app-git/ability/index.ts index 4d3dc8d5f0..57ab4ac07f 100644 --- a/server/src/modules/app-git/ability/index.ts +++ b/server/src/modules/app-git/ability/index.ts @@ -31,6 +31,9 @@ export class FeatureAbilityFactory extends AbilityFactory // Used for public endpoint to get the app configs can(FEATURE_KEY.GIT_FETCH_APP_CONFIGS, AppGitSync); + can(FEATURE_KEY.GET_ALL_BRANCHES, AppGitSync); + can(FEATURE_KEY.CREATE_BRANCH, AppGitSync); + can(FEATURE_KEY.FETCH_PULL_REQUESTS, AppGitSync); // Grant feature-level access based on resource actions if (isAdmin || superAdmin) { // Admin or Super Admin gets full access to all features @@ -38,6 +41,7 @@ export class FeatureAbilityFactory extends AbilityFactory can(FEATURE_KEY.GIT_UPDATE_APP, AppGitSync); can(FEATURE_KEY.GIT_GET_APPS, AppGitSync); can(FEATURE_KEY.GIT_GET_APP, AppGitSync); + can(FEATURE_KEY.GIT_GET_APP_BY_NAME, AppGitSync); can(FEATURE_KEY.GIT_GET_APP_CONFIG, AppGitSync); can(FEATURE_KEY.GIT_SYNC_APP, AppGitSync); can(FEATURE_KEY.GIT_APP_VERSION_RENAME, AppGitSync); @@ -59,6 +63,7 @@ export class FeatureAbilityFactory extends AbilityFactory can(FEATURE_KEY.GIT_APP_VERSION_RENAME, AppGitSync); can(FEATURE_KEY.GIT_APP_CONFIGS_UPDATE, AppGitSync); can(FEATURE_KEY.GIT_GET_APP, AppGitSync); // Used for syncing data from inside the application so only users with edit permission can perform the operation + can(FEATURE_KEY.GIT_GET_APP_BY_NAME, AppGitSync); // Used for syncing data from inside the application using app name can(FEATURE_KEY.GIT_GET_APP_CONFIG, AppGitSync); } diff --git a/server/src/modules/app-git/constants/feature.ts b/server/src/modules/app-git/constants/feature.ts index 277a40be9d..1332ba023c 100644 --- a/server/src/modules/app-git/constants/feature.ts +++ b/server/src/modules/app-git/constants/feature.ts @@ -14,6 +14,10 @@ export const FEATURES: FeaturesConfig = { [FEATURE_KEY.GIT_GET_APP]: { license: LICENSE_FIELD.GIT_SYNC, }, + // Used to fetch the latest git commit data for syncing the application by app name + [FEATURE_KEY.GIT_GET_APP_BY_NAME]: { + license: LICENSE_FIELD.GIT_SYNC, + }, // Used for listing all the application from GIT [FEATURE_KEY.GIT_GET_APPS]: { license: LICENSE_FIELD.GIT_SYNC, @@ -41,6 +45,18 @@ export const FEATURES: FeaturesConfig = { }, // Used for fetching app configs [FEATURE_KEY.GIT_FETCH_APP_CONFIGS]: {}, + + // Used for fetching all branches from remote repo + [FEATURE_KEY.GET_ALL_BRANCHES]: { + license: LICENSE_FIELD.GIT_SYNC, + }, + + [FEATURE_KEY.CREATE_BRANCH]: { + license: LICENSE_FIELD.GIT_SYNC, + }, + [FEATURE_KEY.FETCH_PULL_REQUESTS]: { + license: LICENSE_FIELD.GIT_SYNC, + }, }, }; diff --git a/server/src/modules/app-git/constants/index.ts b/server/src/modules/app-git/constants/index.ts index 51cebdc13f..d3b2aaabca 100644 --- a/server/src/modules/app-git/constants/index.ts +++ b/server/src/modules/app-git/constants/index.ts @@ -3,9 +3,14 @@ export enum FEATURE_KEY { GIT_UPDATE_APP = 'git_update_app', // Corresponds to pullGitAppChanges (POST 'gitpull/app/:appId') GIT_GET_APPS = 'git_get_apps', // Corresponds to getAppsMetaFile (GET 'gitpull') GIT_GET_APP = 'git_get_app', // Corresponds to getAppMetaFile (GET 'gitpull/app/:appId') + GIT_GET_APP_BY_NAME = 'git_get_app_by_name', // Corresponds to getAppMetaFileByName (GET 'gitpull/app/name/:appName') GIT_GET_APP_CONFIG = 'git_get_app_config', // Corresponds to getAppConfig (GET ':workspaceId/app/:versionId') GIT_SYNC_APP = 'git_sync_app', // Corresponds to gitSyncApp (POST 'gitpush/:appGitId/:versionId') GIT_APP_VERSION_RENAME = 'git_app_version_rename', // Corresponds to gitSyncApp (POST 'gitpush/:appGitId/:versionId') GIT_APP_CONFIGS_UPDATE = 'git_app_configs_update', GIT_FETCH_APP_CONFIGS = 'get_app_git_configs', + GET_ALL_BRANCHES = 'get_all_branches', + CREATE_BRANCH = 'create_branch', + FETCH_PULL_REQUESTS = 'fetch_pull_requests', + CREATE_GIT_TAG = 'CREATE_GIT_TAG', } diff --git a/server/src/modules/app-git/dto/index.ts b/server/src/modules/app-git/dto/index.ts index 55cdd31a49..4808fe02a5 100644 --- a/server/src/modules/app-git/dto/index.ts +++ b/server/src/modules/app-git/dto/index.ts @@ -34,6 +34,14 @@ export class AppGitPushDto { @IsString() gitVersionName: string; + + @IsString() + @IsOptional() + gitBranchName?: string; + + @IsBoolean() + @IsOptional() + allowMasterPush?: boolean; } export class AppGitPullDto { @@ -44,13 +52,20 @@ export class AppGitPullDto { gitVersionId: string; @IsString() - lastCommitMessage: string; + @IsOptional() + lastCommitMessage?: string; @IsString() - lastCommitUser: string; + @IsOptional() + appCoRelationId?: string; @IsString() - lastPushDate: string; + @IsOptional() + lastCommitUser?: string; + + @IsString() + @IsOptional() + lastPushDate?: string; @IsString() organizationGitId: string; @@ -67,6 +82,10 @@ export class AppGitPullDto { @IsBoolean() @IsOptional() allowEditing: boolean; + + @IsString() + @IsOptional() + commitHash?: string; } export class AppGitPullUpdateDto { @@ -74,19 +93,40 @@ export class AppGitPullUpdateDto { gitVersionId: string; @IsString() - lastCommitMessage: string; + @IsOptional() + lastCommitMessage?: string; @IsString() - lastCommitUser: string; + @IsOptional() + lastCommitUser?: string; @IsString() - lastPushDate: string; + @IsOptional() + lastPushDate?: string; @IsString() gitAppName: string; @IsString() gitVersionName: string; + + @IsOptional() + gitBranchName?: string; + + @IsString() + @IsOptional() + currentVersionId?: string; + + @IsString() + @IsOptional() + commitHash?: string; + + @IsBoolean() + @IsOptional() + isVersionTag?: boolean; + + @IsOptional() + taggedVersionName?: string; } export class AppGitUpdateDto { @IsBoolean() @@ -109,3 +149,20 @@ export class RenameAppOrVersionDto { @IsOptional() remoteName: string; } +export class AppCommitInfoDto { + @IsString() + @IsNotEmpty() + commitId: string; + + @IsString() + @IsOptional() + message?: string; + + @IsString() + @IsOptional() + author?: string; + + @IsString() + @IsOptional() + date?: string; +} diff --git a/server/src/modules/app-git/module.ts b/server/src/modules/app-git/module.ts index 11634b415a..82f4c06eb7 100644 --- a/server/src/modules/app-git/module.ts +++ b/server/src/modules/app-git/module.ts @@ -10,6 +10,8 @@ import { FeatureAbilityFactory } from '@modules/app-git/ability/index'; import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; import { AppGitRepository } from './repository'; import { SubModule } from '@modules/app/sub-module'; +import { FolderAppsModule } from '@modules/folder-apps/module'; +import { FoldersModule } from '@modules/folders/module'; export class AppGitModule extends SubModule { static async register(configs?: { IS_GET_CONTEXT: boolean }, isMainImport: boolean = false): Promise { const { @@ -38,6 +40,8 @@ export class AppGitModule extends SubModule { return { module: AppGitModule, imports: [ + await FolderAppsModule.register(configs), + await FoldersModule.register(configs), await AppsModule.register(configs), await GitSyncModule.register(configs), await TooljetDbModule.register(configs), @@ -59,7 +63,7 @@ export class AppGitModule extends SubModule { GitLabAppGitUtilityService, VersionRepository, FeatureAbilityFactory, - AppVersionRenameListener, + ...(isMainImport ? [AppVersionRenameListener] : []), ], exports: [SSHAppGitUtilityService, HTTPSAppGitUtilityService, GitLabAppGitUtilityService], }; diff --git a/server/src/modules/app-git/types/index.ts b/server/src/modules/app-git/types/index.ts index c4a718c480..e20fd4fbaa 100644 --- a/server/src/modules/app-git/types/index.ts +++ b/server/src/modules/app-git/types/index.ts @@ -5,6 +5,7 @@ import { MODULES } from '@modules/app/constants/modules'; interface Features { [FEATURE_KEY.GIT_CREATE_APP]: FeatureConfig; [FEATURE_KEY.GIT_GET_APP]: FeatureConfig; + [FEATURE_KEY.GIT_GET_APP_BY_NAME]: FeatureConfig; [FEATURE_KEY.GIT_GET_APPS]: FeatureConfig; [FEATURE_KEY.GIT_GET_APP_CONFIG]: FeatureConfig; [FEATURE_KEY.GIT_SYNC_APP]: FeatureConfig; @@ -12,6 +13,9 @@ interface Features { [FEATURE_KEY.GIT_APP_VERSION_RENAME]: FeatureConfig; [FEATURE_KEY.GIT_APP_CONFIGS_UPDATE]: FeatureConfig; [FEATURE_KEY.GIT_FETCH_APP_CONFIGS]: FeatureConfig; + [FEATURE_KEY.GET_ALL_BRANCHES]: FeatureConfig; + [FEATURE_KEY.CREATE_BRANCH]: FeatureConfig; + [FEATURE_KEY.FETCH_PULL_REQUESTS]: FeatureConfig; } export interface FeaturesConfig { diff --git a/server/src/modules/apps/module.ts b/server/src/modules/apps/module.ts index 34defdc48f..f1c2c157ff 100644 --- a/server/src/modules/apps/module.ts +++ b/server/src/modules/apps/module.ts @@ -27,6 +27,7 @@ import { UserRepository } from '@modules/users/repositories/repository'; import { AppGitRepository } from '@modules/app-git/repository'; import { GroupPermissionsRepository } from '@modules/group-permissions/repository'; import { SubModule } from '@modules/app/sub-module'; +import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; @Module({}) export class AppsModule extends SubModule { static async register(configs: { IS_GET_CONTEXT: boolean }, isMainImport: boolean = false): Promise { @@ -54,7 +55,6 @@ export class AppsModule extends SubModule { 'services/page.util.service', ]); - return { module: AppsModule, imports: [ @@ -77,6 +77,7 @@ export class AppsModule extends SubModule { WorkflowService, VersionRepository, AppsRepository, + OrganizationGitSyncRepository, AppGitRepository, PageService, EventsService, diff --git a/server/src/modules/apps/service.ts b/server/src/modules/apps/service.ts index 9d68c57cb8..22c765e51d 100644 --- a/server/src/modules/apps/service.ts +++ b/server/src/modules/apps/service.ts @@ -27,6 +27,7 @@ import { AppEnvironmentUtilService } from '@modules/app-environments/util.servic import { plainToClass } from 'class-transformer'; import { AppAbility } from '@modules/app/decorators/ability.decorator'; import { VersionRepository } from '@modules/versions/repository'; +import { AppVersionStatus, AppVersionType } from '@entities/app_version.entity'; import { AppsRepository } from './repository'; import { FoldersUtilService } from '@modules/folders/util.service'; import { FolderAppsUtilService } from '@modules/folder-apps/util.service'; @@ -44,6 +45,7 @@ import { MODULES } from '@modules/app/constants/modules'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { AppGitRepository } from '@modules/app-git/repository'; import { WorkflowSchedule } from '@entities/workflow_schedule.entity'; +import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; @Injectable() export class AppsService implements IAppsService { @@ -61,7 +63,8 @@ export class AppsService implements IAppsService { protected readonly aiUtilService: AiUtilService, protected readonly componentsService: ComponentsService, protected readonly eventEmitter: EventEmitter2, - protected readonly appGitRepository: AppGitRepository + protected readonly appGitRepository: AppGitRepository, + protected readonly organizationGitRepository: OrganizationGitSyncRepository ) {} async create(user: User, appCreateDto: AppCreateDto) { const { name, icon, type, prompt } = appCreateDto; @@ -222,6 +225,21 @@ export class AppsService implements IAppsService { const { id: userId, organizationId } = user; const { name } = appUpdateDto; + // Check if name is being changed - require draft version to exist + if (name && name !== app.name) { + const draftVersion = await this.versionRepository.findOne({ + where: { + appId: app.id, + versionType: AppVersionType.VERSION, + status: AppVersionStatus.DRAFT, + }, + }); + + if (!draftVersion) { + throw new BadRequestException('Cannot rename app. Please create a draft version first to rename the app.'); + } + } + const result = await this.appsUtilService.update(app, appUpdateDto, organizationId); if (name && app.creationMode != 'GIT' && name != app.name) { const appRenameDto = { @@ -406,8 +424,13 @@ export class AppsService implements IAppsService { response['editing_version']['current_environment_id'] = appVersionEnvironment.id; } response['should_freeze_editor'] = shouldFreezeEditor; + // Check if editing version is a draft + const editingVersion = response['editing_version']; + const isDraft = editingVersion?.status === 'DRAFT'; + const appGit = await this.appGitRepository.findAppGitByAppId(app.id); - if (appGit) { + if (appGit && !isDraft) { + // Only apply git-based freezing for non-draft versions response['should_freeze_editor'] = !appGit.allowEditing || shouldFreezeEditor; } response['editorEnvironment'] = { diff --git a/server/src/modules/apps/services/app-import-export.service.ts b/server/src/modules/apps/services/app-import-export.service.ts index 38e37f663a..752497e110 100644 --- a/server/src/modules/apps/services/app-import-export.service.ts +++ b/server/src/modules/apps/services/app-import-export.service.ts @@ -2,7 +2,7 @@ import { BadRequestException, HttpException, HttpStatus, Injectable } from '@nes import { isEmpty, set } from 'lodash'; import { App } from 'src/entities/app.entity'; import { AppEnvironment } from 'src/entities/app_environments.entity'; -import { AppVersion } from 'src/entities/app_version.entity'; +import { AppVersion, AppVersionStatus } from 'src/entities/app_version.entity'; import { DataQuery } from 'src/entities/data_query.entity'; import { DataSource } from 'src/entities/data_source.entity'; import { DataSourceOptions } from 'src/entities/data_source_options.entity'; @@ -44,7 +44,7 @@ import { QueryPermission } from '@entities/query_permissions.entity'; import { QueryUser } from '@entities/query_users.entity'; import { ComponentPermission } from '@entities/component_permissions.entity'; import { ComponentUser } from '@entities/component_users.entity'; -import { AppVersionStatus } from '@entities/app_version.entity'; +import { OrganizationGitSync } from '@entities/organization_git_sync.entity'; interface AppResourceMappings { defaultDataSourceIdMapping: Record; dataQueryMapping: Record; @@ -53,6 +53,10 @@ interface AppResourceMappings { appDefaultEnvironmentMapping: Record; pagesMapping: Record; componentsMapping: Record; + dataSourceMapping: Record; + dataSourceOptionsMapping: Record; + layoutMapping: Record; + versionGitIdMapping: Record; } type DefaultDataSourceName = @@ -162,17 +166,29 @@ const INPUT_WIDGET_TYPES = [ 'RangeSliderV2', ]; +const entitiesToRemoveTimestamps = [ + 'components', + 'pages', + 'events', + 'dataQueries', + 'dataSources', + 'appVersions', + 'dataSourcesOptions', + 'appEnvironments', + 'modules', + 'schemaDetails', +]; const SHOW_CLEAR_BTN_COMPONENT_TYPES = [ - 'TextInput', - 'NumberInput', - 'EmailInput', - 'CurrencyInput', - 'PhoneInput', - 'Datepicker', - 'DatePickerV2', - 'DatetimePickerV2', - 'TimePicker', - 'DaterangePicker', + 'TextInput', + 'NumberInput', + 'EmailInput', + 'CurrencyInput', + 'PhoneInput', + 'Datepicker', + 'DatePickerV2', + 'DatetimePickerV2', + 'TimePicker', + 'DaterangePicker', ]; @Injectable() @@ -184,7 +200,7 @@ export class AppImportExportService { protected usersUtilService: UsersUtilService, protected componentsService: ComponentsService, protected entityManager: EntityManager - ) { } + ) {} async export(user: User, id: string, searchParams: any = {}): Promise<{ appV2: App }> { // https://github.com/typeorm/typeorm/issues/3857 @@ -302,10 +318,10 @@ export class AppImportExportService { ...page, permissions: groupPermission ? { - permissionGroup: groupPermission.users - .map((user) => user.permissionGroup?.name) - .filter((name): name is string => Boolean(name)), - } + permissionGroup: groupPermission.users + .map((user) => user.permissionGroup?.name) + .filter((name): name is string => Boolean(name)), + } : undefined, }; }); @@ -317,29 +333,34 @@ export class AppImportExportService { ...query, permissions: groupPermission ? { - permissionGroup: groupPermission.users - .map((user) => user.permissionGroup?.name) - .filter((name): name is string => Boolean(name)), - } + permissionGroup: groupPermission.users + .map((user) => user.permissionGroup?.name) + .filter((name): name is string => Boolean(name)), + } : undefined, }; }); + // Remove updatedAt to avoid unnecessary conflicts during merge in Git Sync + for (const query of queriesWithPermissionGroups) { + delete query.updatedAt; + } + // Added orderBy for layouts as well to maintain consistency -> in the exported file and avoid merge conflicts const components = pages.length > 0 ? await manager - .createQueryBuilder(Component, 'components') - .leftJoinAndSelect('components.layouts', 'layouts') - .leftJoinAndSelect('components.permissions', 'permission') - .leftJoinAndSelect('permission.users', 'componentUser') - .leftJoinAndSelect('componentUser.permissionGroup', 'permissionGroup') - .where('components.pageId IN(:...pageId)', { - pageId: pages.map((v) => v.id), - }) - .orderBy('components.created_at', 'ASC') - .getMany() + .createQueryBuilder(Component, 'components') + .leftJoinAndSelect('components.layouts', 'layouts') + .leftJoinAndSelect('components.permissions', 'permission') + .leftJoinAndSelect('permission.users', 'componentUser') + .leftJoinAndSelect('componentUser.permissionGroup', 'permissionGroup') + .where('components.pageId IN(:...pageId)', { + pageId: pages.map((v) => v.id), + }) + .orderBy('components.created_at', 'ASC') + .addOrderBy('layouts.type', 'ASC') + .getMany() : []; - const appModules = components.filter((c) => c.type === 'ModuleViewer' || c.properties?.moduleAppId); const moduleAppIds = appModules.map((moduleComponent) => ({ moduleId: moduleComponent.properties?.moduleAppId.value, @@ -362,12 +383,13 @@ export class AppImportExportService { return { ...component, + // updatedAt: query?.updatedAt, permissions: groupPermission ? { - permissionGroup: groupPermission.users - .map((user) => user.permissionGroup?.name) - .filter((name): name is string => Boolean(name)), - } + permissionGroup: groupPermission.users + .map((user) => user.permissionGroup?.name) + .filter((name): name is string => Boolean(name)), + } : undefined, }; }); @@ -379,7 +401,6 @@ export class AppImportExportService { }) .orderBy('event_handlers.created_at', 'ASC') .getMany(); - appToExport['components'] = componentsWithPermissionGroups; appToExport['pages'] = pagesWithPermissionGroups; appToExport['events'] = events; @@ -396,7 +417,13 @@ export class AppImportExportService { if (appToExport?.type === APP_TYPES.FRONT_END) { appToExport['modules'] = moduleApps; //Sending all app related modules } - + entitiesToRemoveTimestamps.forEach((entityName) => { + const entity = appToExport[entityName]; + if (entity) { + this.removeTimestamps(entity); // Pass the object/array to removeTimestamps + } + }); + delete (appToExport as any).updatedAt; return { appV2: appToExport }; }); } @@ -422,11 +449,11 @@ export class AppImportExportService { const existingModules = moduleAppNames.length > 0 ? await this.entityManager - .createQueryBuilder(App, 'app') - .where('app.name IN (:...moduleAppNames)', { moduleAppNames }) - .andWhere('app.organizationId = :organizationId', { organizationId: user.organizationId }) - .distinct(true) - .getMany() + .createQueryBuilder(App, 'app') + .where('app.name IN (:...moduleAppNames)', { moduleAppNames }) + .andWhere('app.organizationId = :organizationId', { organizationId: user.organizationId }) + .distinct(true) + .getMany() : []; // Process each module from the import data @@ -474,6 +501,17 @@ export class AppImportExportService { return moduleResourceMappings; } + removeTimestamps = (entity: any) => { + if (Array.isArray(entity)) { + entity.forEach((item) => { + delete item.createdAt; + delete item.updatedAt; + }); + } else if (entity && typeof entity === 'object') { + delete entity.createdAt; + delete entity.updatedAt; + } + }; async import( user: User, appParamsObj: any, @@ -555,13 +593,137 @@ export class AppImportExportService { }, manager); } - async updateEntityReferencesForImportedApp(manager: EntityManager, resourceMapping: AppResourceMappings) { + /** + * Sets co_relation_id on an entity based on the mapping (oldId -> newId) + * Finds the old ID (key) that maps to the entity's current ID (value) + */ + private setCoRelationId( + entity: T, + mapping: Record + ): void { + const co_relation_id = Object.keys(mapping).find((key) => mapping[key] === entity.id); + if (co_relation_id) { + entity.co_relation_id = co_relation_id; + } + } + + private async updateCoRelationIdsForEntities( + manager: EntityManager, + resourceMapping: AppResourceMappings + ): Promise { + const newPageIds = Object.values(resourceMapping.pagesMapping); + const newDataSourceIds = Object.values(resourceMapping.dataSourceMapping); + const newDsoIds = Object.values(resourceMapping.dataSourceOptionsMapping); + const newLayoutIds = Object.values(resourceMapping.layoutMapping); + const appVersionIds = Object.values(resourceMapping.appVersionMapping); + + // Pages + if (newPageIds.length > 0) { + const pages = await manager + .createQueryBuilder(Page, 'pages') + .where('pages.id IN(:...pageIds)', { pageIds: newPageIds }) + .select(['pages.id']) + .getMany(); + + const toUpdatePages = pages.map((page) => { + this.setCoRelationId(page, resourceMapping.pagesMapping); + return page; + }); + + if (!isEmpty(toUpdatePages)) { + await manager.save(toUpdatePages); + } + } + + // DataSources + if (newDataSourceIds.length > 0) { + const dataSources = await manager + .createQueryBuilder(DataSource, 'dataSources') + .where('dataSources.id IN(:...dataSourceIds)', { dataSourceIds: newDataSourceIds }) + .select(['dataSources.id']) + .getMany(); + + const toUpdateDataSources = dataSources.map((dataSource) => { + this.setCoRelationId(dataSource, resourceMapping.dataSourceMapping); + return dataSource; + }); + + if (!isEmpty(toUpdateDataSources)) { + await manager.save(toUpdateDataSources); + } + } + + // DataSourceOptions + if (newDsoIds.length > 0) { + const dataSourceOptions = await manager + .createQueryBuilder(DataSourceOptions, 'dso') + .where('dso.id IN(:...dsoIds)', { dsoIds: newDsoIds }) + .select(['dso.id']) + .getMany(); + + const toUpdateDso = dataSourceOptions.map((dso) => { + this.setCoRelationId(dso, resourceMapping.dataSourceOptionsMapping); + return dso; + }); + + if (!isEmpty(toUpdateDso)) { + await manager.save(toUpdateDso); + } + } + + // Layouts + if (newLayoutIds.length > 0) { + const layouts = await manager + .createQueryBuilder(Layout, 'layouts') + .where('layouts.id IN(:...layoutIds)', { layoutIds: newLayoutIds }) + .select(['layouts.id']) + .getMany(); + + const toUpdateLayouts = layouts.map((layout) => { + this.setCoRelationId(layout, resourceMapping.layoutMapping); + return layout; + }); + + if (!isEmpty(toUpdateLayouts)) { + await manager.save(toUpdateLayouts); + } + } + + if (appVersionIds.length > 0) { + const appVersions = await manager + .createQueryBuilder(AppVersion, 'av') + .where('av.id IN(:...avIds)', { avIds: appVersionIds }) + .select(['av.id']) + .getMany(); + + const toUpdateVersions = appVersions.map((av) => { + this.setCoRelationId(av, resourceMapping.appVersionMapping); + return av; + }); + + if (!isEmpty(toUpdateVersions)) { + await manager.save(toUpdateVersions); + } + } + } + + async updateEntityReferencesForImportedApp( + manager: EntityManager, + resourceMapping: AppResourceMappings, + updateCoRelationIds = false + ) { const mappings = { ...resourceMapping.componentsMapping, ...resourceMapping.dataQueryMapping, + ...resourceMapping.pagesMapping, + ...resourceMapping.dataSourceMapping, + ...resourceMapping.dataSourceOptionsMapping, + ...resourceMapping.layoutMapping, + ...resourceMapping.appVersionMapping, }; const newComponentIds = Object.values(resourceMapping.componentsMapping); const newQueriesIds = Object.values(resourceMapping.dataQueryMapping); + const appVersionIds = Object.values(resourceMapping.appVersionMapping); if (newComponentIds.length > 0) { const components = await manager @@ -580,9 +742,23 @@ export class AppImportExportService { ]) .getMany(); - const toUpdateComponents = components.filter((component) => { - return updateEntityReferences(component, mappings); - }); + let toUpdateComponents; + if (updateCoRelationIds) { + toUpdateComponents = components.map((component) => { + const co_relation_id = Object.keys(resourceMapping.componentsMapping).find( + (key) => resourceMapping.componentsMapping[key] === component.id + ); + if (co_relation_id) { + component.co_relation_id = co_relation_id; // Set the coRelationId + } + updateEntityReferences(component, mappings); + return component; + }); + } else { + toUpdateComponents = components.filter((component) => { + return updateEntityReferences(component, mappings); + }); + } if (!isEmpty(toUpdateComponents)) { await manager.save(toUpdateComponents); @@ -598,16 +774,34 @@ export class AppImportExportService { .select(['dataQueries.id', 'dataQueries.options']) .getMany(); - const toUpdateDataQueries = dataQueries.filter((dataQuery) => { - return updateEntityReferences(dataQuery, mappings); - }); + let toUpdateDataQueries; + if (updateCoRelationIds) { + toUpdateDataQueries = dataQueries.filter((dataQuery) => { + const oldId = Object.keys(resourceMapping.dataQueryMapping).find( + (key) => resourceMapping.dataQueryMapping[key] === dataQuery.id + ); + if (oldId) { + dataQuery.co_relation_id = oldId; // Set the coRelationId to the old ID + } + return updateEntityReferences(dataQuery, mappings); + }); + } else { + toUpdateDataQueries = dataQueries.filter((dataQuery) => { + return updateEntityReferences(dataQuery, mappings); + }); + } if (!isEmpty(toUpdateDataQueries)) { await manager.save(toUpdateDataQueries); } } + + // Handle co_relation_id for Pages, DataSources, DataSourceOptions, Layouts (only when updateCoRelationIds is true) + if (updateCoRelationIds) { + await this.updateCoRelationIdsForEntities(manager, resourceMapping); + } + // update Global settings of created versions - const appVersionIds = Object.values(resourceMapping.appVersionMapping); const newAppVersions = await manager.find(AppVersion, { where: { id: In(appVersionIds), @@ -625,6 +819,7 @@ export class AppImportExportService { await this.updateWorkflowDefinitionQueryReferences(manager, appVersionIds, resourceMapping); } } + async createImportedAppForUser( manager: EntityManager, appParams: any, @@ -643,6 +838,7 @@ export class AppImportExportService { icon: appParams.icon, creationMode: `${isGitApp ? 'GIT' : 'DEFAULT'}`, isPublic: false, + co_relation_id: appParams?.id, createdAt: new Date(), updatedAt: new Date(), }); @@ -726,6 +922,10 @@ export class AppImportExportService { appDefaultEnvironmentMapping: {}, pagesMapping: {}, componentsMapping: {}, + dataSourceMapping: {}, + dataSourceOptionsMapping: {}, + layoutMapping: {}, + versionGitIdMapping: {}, }; const { importingDataSources, @@ -835,11 +1035,16 @@ export class AppImportExportService { const savedComponents = await manager.save(Component, mappedComponents); + const layoutIdToOldIdMap: { layout: Layout; oldId: string }[] = []; + for (const componentId in pageComponents) { const componentLayout = pageComponents[componentId]['layouts']; + const sortedLayoutTypes = Object.keys(componentLayout).sort((a, b) => { + return componentLayout[a].id.localeCompare(componentLayout[b].id); + }); if (componentLayout && appResourceMappings.componentsMapping[componentId]) { - for (const type in componentLayout) { + for (const type of sortedLayoutTypes) { const layout = componentLayout[type]; const newLayout = new Layout(); newLayout.type = type; @@ -854,11 +1059,21 @@ export class AppImportExportService { newLayout.componentId = appResourceMappings.componentsMapping[componentId]; componentLayouts.push(newLayout); + layoutIdToOldIdMap.push({ layout: newLayout, oldId: layout.id }); } } } - await manager.save(Layout, componentLayouts); + // await manager.save(Layout, componentLayouts); + + const savedLayouts = await manager.save(Layout, componentLayouts); + // Populate layoutMapping: oldId -> newId + savedLayouts.forEach((savedLayout, index) => { + const oldId = layoutIdToOldIdMap[index].oldId; + if (oldId) { + appResourceMappings.layoutMapping[oldId] = savedLayout.id; + } + }); //Event handlers @@ -1033,6 +1248,8 @@ export class AppImportExportService { user ); + appResourceMappings.dataSourceMapping[importingDataSource.id] = dataSourceForAppVersion.id; + // TODO: Have version based conditional based on app versions // currently we are checking on existence of keys and handling // imports accordingly. Would be pragmatic to do: @@ -1057,7 +1274,15 @@ export class AppImportExportService { createdAt: new Date(), updatedAt: new Date(), }); - await manager.save(dsOption); + const savedDsOption = await manager.save(dsOption); + + // Find the matching old dataSourceOption ID for this environment + const oldDsOption = importingDataSourceOptions.find( + (dso) => dso.dataSourceId === importingDataSource.id && dso.environmentId === envId + ); + if (oldDsOption) { + appResourceMappings.dataSourceOptionsMapping[oldDsOption.id] = savedDsOption.id; + } }) ); } @@ -1128,6 +1353,7 @@ export class AppImportExportService { isHomePage = importingAppVersion.homePageId === page.id; + // can comment this after testing --> can uncomment this to fix this issue if (isHomePage) { updateHomepageId = pageCreated.id; } @@ -1252,6 +1478,7 @@ export class AppImportExportService { newLayout.width = layout.width; newLayout.height = layout.height; newLayout.component = savedComponent; + newLayout.co_relation_id = layout.id; await manager.save(newLayout); }) @@ -1503,10 +1730,10 @@ export class AppImportExportService { const options = importingDataSource.kind === 'tooljetdb' ? this.replaceTooljetDbTableIds( - importingQuery.options, - externalResourceMappings['tooljet_database'], - organizationId - ) + importingQuery.options, + externalResourceMappings['tooljet_database'], + organizationId + ) : importingQuery.options; const newQuery = manager.create(DataQuery, { @@ -1941,6 +2168,38 @@ export class AppImportExportService { }); let currentEnvironmentId: string; + // Check if git sync is configured for the workspace + const orgGitSync = await manager.findOne(OrganizationGitSync, { + where: { organizationId: user?.organizationId }, + }); + const isGitSyncConfigured = !!orgGitSync; + + // Find the latest draft version + // When git sync is configured, only the latest draft should remain as DRAFT, others become PUBLISHED + let latestDraftId: string | null = null; + if (isGitSyncConfigured) { + const draftVersions = appVersions.filter((v) => v.status === AppVersionStatus.DRAFT || !v.status); + + if (draftVersions.length > 0) { + // Check if createdAt is available on the versions + const hasCreatedAt = draftVersions.some((v) => v.createdAt); + + if (hasCreatedAt) { + // Sort by createdAt descending to find the most recent draft + const sortedDrafts = [...draftVersions].sort((a, b) => { + const dateA = a.createdAt ? new Date(a.createdAt).getTime() : 0; + const dateB = b.createdAt ? new Date(b.createdAt).getTime() : 0; + return dateB - dateA; // Descending order (latest first) + }); + latestDraftId = sortedDrafts[0].id; + } else { + // If no createdAt available (export file), use the last draft in the array + // The editingVersion (most recent) is typically the last one in appVersions array + latestDraftId = draftVersions[draftVersions.length - 1].id; + } + } + } + for (const appVersion of appVersions) { const appEnvIds: string[] = [...organization.appEnvironments.map((env) => env.id)]; @@ -1957,6 +2216,19 @@ export class AppImportExportService { if (importedApp.editingVersion && !createNewVersion) { version = importedApp.editingVersion; } else { + // Determine the version status + // When git sync is configured and there are multiple drafts, only the latest draft stays as DRAFT + let versionStatus: AppVersionStatus; + const isDraftVersion = appVersion.status === AppVersionStatus.DRAFT || !appVersion.status; + + if (isGitSyncConfigured && isDraftVersion) { + // Only the latest draft should remain as DRAFT, others become PUBLISHED + versionStatus = appVersion.id === latestDraftId ? AppVersionStatus.DRAFT : AppVersionStatus.PUBLISHED; + } else { + // Preserve original status or default to DRAFT + versionStatus = appVersion.status || AppVersionStatus.DRAFT; + } + version = await manager.create(AppVersion, { appId: importedApp.id, definition: appVersion.definition, @@ -1964,11 +2236,13 @@ export class AppImportExportService { currentEnvironmentId, createdAt: new Date(), updatedAt: new Date(), - status: AppVersionStatus.DRAFT, + status: versionStatus, + versionType: appVersion.versionType, parent_version_id: appVersion?.id || null, + createdById: user.id, + co_relation_id: appVersion.id, }); } - if (isNormalizedAppDefinitionSchema) { version.showViewerNavigation = appVersion.showViewerNavigation; version.homePageId = appVersion.homePageId; @@ -2234,10 +2508,10 @@ export class AppImportExportService { options: dataSourceId == defaultDataSourceIds['tooljetdb'] ? this.replaceTooljetDbTableIds( - query.options, - externalResourceMappings['tooljet_database'], - user?.organizationId - ) + query.options, + externalResourceMappings['tooljet_database'], + user?.organizationId + ) : query.options, }); await manager.save(newQuery); diff --git a/server/src/modules/apps/util.service.ts b/server/src/modules/apps/util.service.ts index 11bcc3abaf..7e7db06dae 100644 --- a/server/src/modules/apps/util.service.ts +++ b/server/src/modules/apps/util.service.ts @@ -15,7 +15,7 @@ import { DataSource } from '@entities/data_source.entity'; import { EntityManager, MoreThan, SelectQueryBuilder } from 'typeorm'; import { v4 as uuidv4 } from 'uuid'; import { AppsRepository } from './repository'; -import { AppVersion } from '@entities/app_version.entity'; +import { AppVersion, AppVersionStatus, AppVersionType } from '@entities/app_version.entity'; import { AppEnvironmentUtilService } from '@modules/app-environments/util.service'; import { VersionRepository } from '@modules/versions/repository'; import { LicenseTermsService } from '@modules/licensing/interfaces/IService'; @@ -90,6 +90,7 @@ export class AppsUtilService implements IAppsUtilService { appVersionId: appVersion.id, index: 1, autoComputeLayout: true, + appId: app.id, }) ); @@ -702,4 +703,43 @@ export class AppsUtilService implements IAppsUtilService { return this.appRepository.findByAppId(appId, manager); }, manager); } + + /** + * Determines if the editor should be frozen based on version status, type, and git configuration + * @param editingVersion - The app version being edited + * @param environmentPriority - The priority of the current environment (> 1 means production-like) + * @param appGit - The app's git configuration + * @param orgGit - The organization's git configuration + * @returns boolean indicating if editor should be frozen + */ + shouldFreezeEditor(editingVersion: AppVersion, appGit: any, orgGit: any): boolean { + let shouldFreezeEditor = false; + // Check version status and type + if (editingVersion?.status === AppVersionStatus.PUBLISHED) { + // Published versions are always frozen + shouldFreezeEditor = true; + } else if ( + editingVersion?.versionType === AppVersionType.VERSION && + editingVersion?.status === AppVersionStatus.DRAFT && + (!orgGit || !orgGit?.isBranchingEnabled) + ) { + // Draft versions should never be frozen by git config, only by environment + // Keep existing shouldFreezeEditor value from environment priority check + } else if ( + editingVersion?.versionType === AppVersionType.VERSION && + editingVersion?.status !== AppVersionStatus.DRAFT + ) { + // Non-draft version types are frozen + shouldFreezeEditor = true; + } else { + // For branch versions, check git config + if (appGit && editingVersion?.status !== AppVersionStatus.DRAFT) { + shouldFreezeEditor = !appGit?.allowEditing || shouldFreezeEditor; + } else if (orgGit && orgGit?.isBranchingEnabled && editingVersion?.versionType === AppVersionType.VERSION) { + shouldFreezeEditor = orgGit?.isBranchingEnabled || shouldFreezeEditor; + } + } + + return shouldFreezeEditor; + } } diff --git a/server/src/modules/folder-apps/service.ts b/server/src/modules/folder-apps/service.ts index c90e833dfb..214fca80a9 100644 --- a/server/src/modules/folder-apps/service.ts +++ b/server/src/modules/folder-apps/service.ts @@ -1,5 +1,6 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { FolderApp } from '../../entities/folder_app.entity'; +import { AppGitSync } from '../../entities/app_git_sync.entity' import { dbTransactionWrap } from '@helpers/database.helper'; import { EntityManager } from 'typeorm'; import { decamelizeKeys } from 'humps'; @@ -20,32 +21,20 @@ export class FolderAppsService implements IFolderAppsService { ) {} async create(folderId: string, appId: string): Promise { - return dbTransactionWrap(async (manager: EntityManager) => { - const existingFolderApp = await manager.findOne(FolderApp, { - where: { appId, folderId }, - }); - - if (existingFolderApp) { - throw new BadRequestException('App has already been added to the folder'); - } - - // TODO: check if folder under user.organizationId and user has edit permission on app - - const newFolderApp = manager.create(FolderApp, { - folderId, - appId, - createdAt: new Date(), - updatedAt: new Date(), - }); - - const folderApp = await manager.save(FolderApp, newFolderApp); - - return folderApp; - }); + return this.folderAppsUtilService.create(folderId, appId); } async remove(folderId: string, appId: string): Promise { return dbTransactionWrap(async (manager: EntityManager) => { + const gitSyncedApp = await manager.findOne(AppGitSync, { + where: { appId }, + select: ['id'], + }); + if (gitSyncedApp) { + throw new BadRequestException( + "Apps connected to git can't be removed from folders." + ); + } // TODO: folder under user.organizationId return await manager.delete(FolderApp, { folderId, appId }); }); diff --git a/server/src/modules/folder-apps/util.service.ts b/server/src/modules/folder-apps/util.service.ts index f7a50fb18d..a11c6721c9 100644 --- a/server/src/modules/folder-apps/util.service.ts +++ b/server/src/modules/folder-apps/util.service.ts @@ -1,6 +1,6 @@ import { Folder } from '@entities/folder.entity'; import { User } from '@entities/user.entity'; -import { Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; import { EntityManager, SelectQueryBuilder } from 'typeorm'; import { IFolderAppsUtilService } from './interfaces/IUtilService'; import { AppBase } from '@entities/app_base.entity'; @@ -10,6 +10,7 @@ import { MODULES } from '@modules/app/constants/modules'; import { UserAppsPermissions, UserWorkflowPermissions } from '@modules/ability/types'; import { AbilityService } from '@modules/ability/interfaces/IService'; import { APP_TYPES } from '@modules/apps/constants'; +import { AppGitSync } from '../../entities/app_git_sync.entity'; @Injectable() export class FolderAppsUtilService implements IFolderAppsUtilService { @@ -172,6 +173,45 @@ export class FolderAppsUtilService implements IFolderAppsUtilService { }); } + async create(folderId: string, appId: string, skipGitSyncCheck = false): Promise { + return dbTransactionWrap(async (manager: EntityManager) => { + const existingFolderApp = await manager.findOne(FolderApp, { + where: { appId }, + }); + + if (existingFolderApp) { + throw new BadRequestException( + 'Apps can only be in one folder at a time. To add this app here, remove it from its current folder first.' + ); + } + + // Skip this check when called from app import flow + if (!skipGitSyncCheck) { + const gitSyncedApp = await manager.findOne(AppGitSync, { + where: { appId }, + select: ['id'], + }); + + if (gitSyncedApp) { + throw new BadRequestException('Git-synced app cannot be moved to the folder'); + } + } + + // TODO: check if folder under user.organizationId and user has edit permission on app + + const newFolderApp = manager.create(FolderApp, { + folderId, + appId, + createdAt: new Date(), + updatedAt: new Date(), + }); + + const folderApp = await manager.save(FolderApp, newFolderApp); + + return folderApp; + }); + } + protected addViewableFrontendFilter( query: SelectQueryBuilder, folderAppIds: string[], @@ -182,18 +222,18 @@ export class FolderAppsUtilService implements IFolderAppsUtilService { const viewableAppsTotal = isAllEditable ? [null, ...folderAppIds] : hideAll - ? [null, ...userAppPermissions.editableAppsId] - : isAllViewable - ? [null, ...folderAppIds].filter((id) => !userAppPermissions.hiddenAppsId.includes(id)) - : [ - null, - ...Array.from( - new Set([ - ...userAppPermissions.editableAppsId, - ...userAppPermissions.viewableAppsId.filter((id) => !userAppPermissions.hiddenAppsId.includes(id)), - ]) - ), - ]; + ? [null, ...userAppPermissions.editableAppsId] + : isAllViewable + ? [null, ...folderAppIds].filter((id) => !userAppPermissions.hiddenAppsId.includes(id)) + : [ + null, + ...Array.from( + new Set([ + ...userAppPermissions.editableAppsId, + ...userAppPermissions.viewableAppsId.filter((id) => !userAppPermissions.hiddenAppsId.includes(id)), + ]) + ), + ]; const viewableAppIds = [null, ...viewableAppsTotal.filter((id) => folderAppIds.includes(id))]; diff --git a/server/src/modules/folders/service.ts b/server/src/modules/folders/service.ts index 91587b6ba1..842e5bb579 100644 --- a/server/src/modules/folders/service.ts +++ b/server/src/modules/folders/service.ts @@ -1,5 +1,7 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, BadRequestException } from '@nestjs/common'; import { Folder } from '@entities/folder.entity'; +import { FolderApp } from '../../entities/folder_app.entity'; +import { AppGitSync } from '../../entities/app_git_sync.entity' import { decamelizeKeys } from 'humps'; import { CreateFolderDto, UpdateFolderDto } from '@modules/folders/dto'; import { IFoldersService } from './interfaces/IService'; @@ -8,36 +10,31 @@ import { DeleteResult } from 'typeorm'; import { DataBaseConstraints } from '@helpers/db_constraints.constants'; import { dbTransactionWrap } from '@helpers/database.helper'; import { EntityManager } from 'typeorm'; +import { FoldersUtilService } from './util.service'; @Injectable() export class FoldersService implements IFoldersService { + constructor(protected foldersUtilService: FoldersUtilService) {} async createFolder(user, createFolderDto: CreateFolderDto) { - const folderName = createFolderDto.name; - const type = createFolderDto.type; - return await dbTransactionWrap(async (manager: EntityManager) => { - const folder = await catchDbException(async () => { - return await manager.save( - manager.create(Folder, { - name: folderName, - createdAt: new Date(), - updatedAt: new Date(), - organizationId: user?.organizationId, - type, - }) - ); - }, [ - { - dbConstraint: DataBaseConstraints.FOLDER_NAME_UNIQUE, - message: 'This folder name is already taken.', - }, - ]); - - return decamelizeKeys(folder); - }); + return this.foldersUtilService.createFolder(user, createFolderDto); } async updateFolder(user, id, updateFolderDto: UpdateFolderDto) { const folderId = id; const folderName = updateFolderDto.name; return dbTransactionWrap(async (manager: EntityManager) => { + + const gitSyncedAppInFolder = await manager + .createQueryBuilder(AppGitSync, 'ags') + .innerJoin(FolderApp, 'fa', 'fa.app_id = ags.app_id') + .where('fa.folder_id = :folderId', { folderId }) + .select('ags.id') + .getOne(); + + if (gitSyncedAppInFolder) { + throw new BadRequestException( + 'Folders with git-synced apps cannot be edited' + ); + } + const folder = await catchDbException(async () => { return manager.update(Folder, { id: folderId }, { name: folderName }); }, [ @@ -54,6 +51,24 @@ export class FoldersService implements IFoldersService { const folder = await manager.findOneOrFail(Folder, { where: { id, organizationId: user.organizationId }, }); + + const gitSyncedAppInFolder = await manager + .createQueryBuilder(AppGitSync, 'ags') + .innerJoin( + FolderApp, + 'fa', + 'fa.app_id = ags.app_id' + ) + .where('fa.folder_id = :folderId', { folderId: folder.id }) + .select('ags.id') + .getOne(); + + if (gitSyncedAppInFolder) { + throw new BadRequestException( + "Folders with apps synced to git can't be deleted. Delete the git apps and try again." + ); + } + return manager.delete(Folder, { id: folder.id, organizationId: user.organizationId }); }); } diff --git a/server/src/modules/folders/util.service.ts b/server/src/modules/folders/util.service.ts index 1dac8aa0f6..d7587fe793 100644 --- a/server/src/modules/folders/util.service.ts +++ b/server/src/modules/folders/util.service.ts @@ -3,6 +3,11 @@ import { EntityManager, SelectQueryBuilder } from 'typeorm'; import { User } from '@entities/user.entity'; import { Folder } from '@entities/folder.entity'; import { IFoldersUtilService } from './interfaces/IUtilService'; +import { CreateFolderDto } from './dto'; +import { dbTransactionWrap } from '@helpers/database.helper'; +import { catchDbException } from '@helpers/utils.helper'; +import { DataBaseConstraints } from '@helpers/db_constraints.constants'; +import { decamelizeKeys } from 'humps'; @Injectable() export class FoldersUtilService implements IFoldersUtilService { async allFolders(user: User, manager: EntityManager, type = 'front-end'): Promise { @@ -12,6 +17,37 @@ export class FoldersUtilService implements IFoldersUtilService { return await manager.findOneOrFail(Folder, { where: { id: folderId } }); } + async findByName(folderName: string, organizationId: string): Promise { + return await dbTransactionWrap(async (manager: EntityManager) => { + return await manager.findOne(Folder, { where: { name: folderName, organizationId } }); + }); + } + + async createFolder(user, createFolderDto: CreateFolderDto) { + const folderName = createFolderDto.name; + const type = createFolderDto.type; + return await dbTransactionWrap(async (manager: EntityManager) => { + const folder = await catchDbException(async () => { + return await manager.save( + manager.create(Folder, { + name: folderName, + createdAt: new Date(), + updatedAt: new Date(), + organizationId: user?.organizationId, + type, + }) + ); + }, [ + { + dbConstraint: DataBaseConstraints.FOLDER_NAME_UNIQUE, + message: 'This folder name is already taken.', + }, + ]); + + return decamelizeKeys(folder); + }); + } + private getAllFoldersQuery( organizationId: string, manager: EntityManager, diff --git a/server/src/modules/git-sync/base-git-util.service.ts b/server/src/modules/git-sync/base-git-util.service.ts index 742ae9dbd6..1c31bf6a87 100644 --- a/server/src/modules/git-sync/base-git-util.service.ts +++ b/server/src/modules/git-sync/base-git-util.service.ts @@ -28,7 +28,14 @@ export class BaseGitUtilService { throw new Error('Method not implemented.'); } - async WriteAppFile(user: User, repoPath: string, appGit: AppGitSync, version: AppVersion, app: App): Promise { + async WriteAppFile( + user: User, + appGit: AppGitSync, + version: AppVersion, + app: App, + appPath: string, + parentDir: string + ): Promise { throw new Error('Method not implemented.'); } diff --git a/server/src/modules/git-sync/dto/index.ts b/server/src/modules/git-sync/dto/index.ts index 6bc1204fd8..96f65449b7 100644 --- a/server/src/modules/git-sync/dto/index.ts +++ b/server/src/modules/git-sync/dto/index.ts @@ -29,9 +29,3 @@ export class OrganizationGitStatusUpdateDto { @IsBoolean() isEnabled: boolean; } - -export class OrganizationGitHTTPSUpdateDto { - @IsOptional() - @IsBoolean() - autoCommit: boolean; -} diff --git a/server/src/modules/git-sync/git-sync-adapter.ts b/server/src/modules/git-sync/git-sync-adapter.ts new file mode 100644 index 0000000000..17e8636e27 --- /dev/null +++ b/server/src/modules/git-sync/git-sync-adapter.ts @@ -0,0 +1,3 @@ +import { Injectable } from '@nestjs/common'; +@Injectable() +export class GitSyncAdapter {} \ No newline at end of file diff --git a/server/src/modules/git-sync/module.ts b/server/src/modules/git-sync/module.ts index 0867a307cd..90e70aa9b0 100644 --- a/server/src/modules/git-sync/module.ts +++ b/server/src/modules/git-sync/module.ts @@ -23,6 +23,7 @@ export class GitSyncModule extends SubModule { GitLabGitSyncUtilityService, BaseGitUtilService, BaseGitSyncService, + GitSyncAdapter, } = await this.getProviders(configs, 'git-sync', [ 'controller', 'service', @@ -35,6 +36,7 @@ export class GitSyncModule extends SubModule { 'providers/gitlab/util.service', 'base-git-util.service', 'base-git.service', + 'git-sync-adapter', ]); return { @@ -61,6 +63,7 @@ export class GitSyncModule extends SubModule { GitLabGitSyncUtilityService, SourceControlProviderService, FeatureAbilityFactory, + GitSyncAdapter, ], exports: [ HTTPSGitSyncUtilityService, @@ -68,6 +71,8 @@ export class GitSyncModule extends SubModule { GitLabGitSyncUtilityService, BaseGitSyncService, BaseGitUtilService, + GitSyncAdapter, + OrganizationGitSyncRepository, ], }; } diff --git a/server/src/modules/group-permissions/repository.ts b/server/src/modules/group-permissions/repository.ts index d4fe715da6..4e4d23e9b8 100644 --- a/server/src/modules/group-permissions/repository.ts +++ b/server/src/modules/group-permissions/repository.ts @@ -156,8 +156,7 @@ export class GroupPermissionsRepository extends Repository { type: type as ResourceType, }; } - - return manager.find(GranularPermissions, findOptions); + return await manager.find(GranularPermissions, findOptions); }, manager || this.manager); } diff --git a/server/src/modules/import-export-resources/service.ts b/server/src/modules/import-export-resources/service.ts index 4e89de8fa6..6f19ac8a4f 100644 --- a/server/src/modules/import-export-resources/service.ts +++ b/server/src/modules/import-export-resources/service.ts @@ -95,13 +95,13 @@ export class ImportExportResourcesService { const pages = appParams?.pages; const queries = appParams?.dataQueries; const components = appParams?.components; - (pages?.length || queries?.length || components?.length) && - (await this.appImportExportService.checkIfGroupPermissionsExist( + if (pages?.length || queries?.length || components?.length) + await this.appImportExportService.checkIfGroupPermissionsExist( pages, queries, components, user.organizationId - )); + ); } } } diff --git a/server/src/modules/modules/module.ts b/server/src/modules/modules/module.ts index 985520df21..112880f92c 100644 --- a/server/src/modules/modules/module.ts +++ b/server/src/modules/modules/module.ts @@ -17,6 +17,7 @@ import { ImportExportResourcesModule } from '@modules/import-export-resources/mo import { RolesRepository } from '@modules/roles/repository'; import { AppGitRepository } from '@modules/app-git/repository'; import { GroupPermissionsRepository } from '@modules/group-permissions/repository'; +import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; import { AppHistoryModule } from '@modules/app-history/module'; @Module({}) export class ModulesModule { @@ -60,6 +61,7 @@ export class ModulesModule { RolesRepository, AppGitRepository, GroupPermissionsRepository, + OrganizationGitSyncRepository, ], }; } diff --git a/server/src/modules/versions/dto/index.ts b/server/src/modules/versions/dto/index.ts index 9b92ecee8c..93590b9189 100644 --- a/server/src/modules/versions/dto/index.ts +++ b/server/src/modules/versions/dto/index.ts @@ -1,6 +1,7 @@ import { IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator'; import { Transform } from 'class-transformer'; import { sanitizeInput } from '@helpers/utils.helper'; +import { AppVersionType } from '@entities/app_version.entity'; export class VersionCreateDto { @IsString() @@ -19,6 +20,9 @@ export class VersionCreateDto { @IsOptional() versionDescription: string; + + @IsOptional() + versionType?: AppVersionType; } export class PromoteVersionDto { @@ -36,4 +40,7 @@ export class DraftVersionDto { @IsOptional() versionDescription: string; + + @IsOptional() + versionType?: AppVersionType; } diff --git a/server/src/modules/versions/find-relations.util.ts b/server/src/modules/versions/find-relations.util.ts new file mode 100644 index 0000000000..4c6ac99d55 --- /dev/null +++ b/server/src/modules/versions/find-relations.util.ts @@ -0,0 +1,212 @@ +import { AppVersion } from '@entities/app_version.entity'; +import { DataSource, EntityManager } from 'typeorm'; +import { dbTransactionWrap } from '@helpers/database.helper'; +import { App } from '@entities/app.entity'; +import { AppEnvironment } from '@entities/app_environments.entity'; +import { Component } from '@entities/component.entity'; +import { DataQuery } from '@entities/data_query.entity'; +import { DataSourceOptions } from '@entities/data_source_options.entity'; +import { EventHandler } from '@entities/event_handler.entity'; +import { Page } from '@entities/page.entity'; +import { User } from '@entities/user.entity'; +import { DataSourceScopes } from '@modules/data-sources/constants'; + +export async function findAllRelationsForVersion(versionId: string, manager?: EntityManager): Promise { + // this.getUuidFieldsForExport() + return await dbTransactionWrap(async (manager: EntityManager) => {}, manager); +} +async function getUuidFieldsForExport( + user: User, + id: string, + searchParams: any = {} +): Promise<{ + appId: string; + versionIds: string[]; + dataSourceIds: string[]; + dataQueryIds: string[]; + dataSourceOptionIds: string[]; + pageIds: string[]; + componentIds: string[]; + layoutIds: string[]; + eventHandlerIds: string[]; + environmentIds: string[]; + permissionIds: string[]; +}> { + const versionId = searchParams?.version_id; + + return await dbTransactionWrap(async (manager: EntityManager) => { + // Get App ID only + const app = await manager + .createQueryBuilder(App, 'apps') + .select('apps.id') + .where('apps.id = :id AND apps.organization_id = :organizationId', { + id, + organizationId: user?.organizationId, + }) + .getOne(); + + if (!app) { + throw new Error('App not found'); + } + + // Get App Version IDs only + const queryAppVersions = manager + .createQueryBuilder(AppVersion, 'app_versions') + .select('app_versions.id') + .where('app_versions.appId = :appId', { appId: app.id }); + + if (versionId) { + queryAppVersions.andWhere('app_versions.id = :versionId', { versionId }); + } + + const appVersions = await queryAppVersions.getMany(); + const versionIds = appVersions.map((v) => v.id); + + // Get Legacy Local Data Source IDs only + // const legacyLocalDataSources = versionIds.length + // ? await manager + // .createQueryBuilder(DataSource, 'data_sources') + // .select('data_sources.id') + // .where('data_sources.appVersionId IN(:...versionId)', { versionId: versionIds }) + // .andWhere('data_sources.scope != :scope', { scope: DataSourceScopes.GLOBAL }) + // .getMany() + // : []; + + // Get Environment IDs only + const appEnvironments = await manager + .createQueryBuilder(AppEnvironment, 'app_environments') + .select('app_environments.id') + .where('app_environments.organizationId = :organizationId', { + organizationId: user?.organizationId, + }) + .getMany(); + + const environmentIds = appEnvironments.map((env) => env.id); + + // Get Global Data Source IDs from queries + const globalQueries = await manager + .createQueryBuilder(DataQuery, 'data_query') + .select(['data_query.dataSourceId']) + .innerJoin('data_query.dataSource', 'dataSource') + .where('data_query.appVersionId IN(:...versionId)', { versionId: versionIds }) + .andWhere('dataSource.scope = :scope', { scope: DataSourceScopes.GLOBAL }) + .getMany(); + + const globalDataSourceIds = [...new Set(globalQueries.map((gq) => gq.dataSourceId))]; + + // Combine all data source IDs + // const allDataSourceIds = [...legacyLocalDataSources.map((ds) => ds.id), ...globalDataSourceIds]; + const allDataSourceIds = [...globalDataSourceIds]; + + // Get Data Query IDs only + const dataQueries = allDataSourceIds.length + ? await manager + .createQueryBuilder(DataQuery, 'data_queries') + .select('data_queries.id') + .where('data_queries.dataSourceId IN(:...dataSourceId)', { + dataSourceId: allDataSourceIds, + }) + .andWhere('data_queries.appVersionId IN(:...versionId)', { versionId: versionIds }) + .getMany() + : []; + + const dataQueryIds = dataQueries.map((dq) => dq.id); + + // Get Data Source Option IDs only + const dataSourceOptions = allDataSourceIds.length + ? await manager + .createQueryBuilder(DataSourceOptions, 'data_source_options') + .select('data_source_options.id') + .where( + 'data_source_options.environmentId IN(:...environmentId) AND data_source_options.dataSourceId IN(:...dataSourceId)', + { + environmentId: environmentIds, + dataSourceId: allDataSourceIds, + } + ) + .getMany() + : []; + + const dataSourceOptionIds = dataSourceOptions.map((dso) => dso.id); + + // Get Page IDs only + const pages = await manager + .createQueryBuilder(Page, 'page') + .select('page.id') + .where('page.appVersionId IN(:...versionId)', { versionId: versionIds }) + .getMany(); + + const pageIds = pages.map((p) => p.id); + + // Get Page Permission IDs + // const pagePermissions = pageIds.length + // ? await manager + // .createQueryBuilder(Permissions, 'permission') + // .select('permission.id') + // .where('permission.pageId IN(:...pageId)', { pageId: pageIds }) + // .getMany() + // : []; + + // Get Component IDs and Layout IDs + const components = pageIds.length + ? await manager + .createQueryBuilder(Component, 'components') + .select(['components.id']) + .leftJoin('components.layouts', 'layouts') + .addSelect('layouts.id') + .where('components.pageId IN(:...pageId)', { pageId: pageIds }) + .getMany() + : []; + + const componentIds = components.map((c) => c.id); + const layoutIds = components.flatMap((c) => c.layouts?.map((l) => l.id) || []); + + // Get Component Permission IDs + // const componentPermissions = componentIds.length + // ? await manager + // .createQueryBuilder(Permissions, 'permission') + // .select('permission.id') + // .where('permission.componentId IN(:...componentId)', { componentId: componentIds }) + // .getMany() + // : []; + + // // Get Data Query Permission IDs + // const queryPermissions = dataQueryIds.length + // ? await manager + // .createQueryBuilder(Permissions, 'permission') + // .select('permission.id') + // .where('permission.dataQueryId IN(:...dataQueryId)', { dataQueryId: dataQueryIds }) + // .getMany() + // : []; + + // Get Event Handler IDs only + const events = await manager + .createQueryBuilder(EventHandler, 'event_handlers') + .select('event_handlers.id') + .where('event_handlers.appVersionId IN(:...versionId)', { versionId: versionIds }) + .getMany(); + + const eventHandlerIds = events.map((e) => e.id); + + // Combine all permission IDs + // const allPermissionIds = [ + // ...pagePermissions.map((p) => p.id), + // ...componentPermissions.map((p) => p.id), + // ...queryPermissions.map((p) => p.id), + // ]; + + return { + appId: app.id, + versionIds, + dataSourceIds: allDataSourceIds, + dataQueryIds, + dataSourceOptionIds, + pageIds, + componentIds, + layoutIds, + eventHandlerIds, + environmentIds, + // permissionIds: allPermissionIds, + }; + }); +} diff --git a/server/src/modules/versions/module.ts b/server/src/modules/versions/module.ts index acd5d47ee7..c52d7d6181 100644 --- a/server/src/modules/versions/module.ts +++ b/server/src/modules/versions/module.ts @@ -12,6 +12,7 @@ import { FeatureAbilityFactory } from './ability'; import { AppPermissionsModule } from '@modules/app-permissions/module'; import { GroupPermissionsRepository } from '@modules/group-permissions/repository'; import { SubModule } from '@modules/app/sub-module'; +import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; import { AppHistoryModule } from '@modules/app-history/module'; export class VersionModule extends SubModule { @@ -64,6 +65,7 @@ export class VersionModule extends SubModule { DataQueryRepository, DataSourcesRepository, VersionRepository, + OrganizationGitSyncRepository, AppsRepository, AppGitRepository, VersionsCreateService, diff --git a/server/src/modules/versions/repository.ts b/server/src/modules/versions/repository.ts index 8659cd2aa4..24d94ea51f 100644 --- a/server/src/modules/versions/repository.ts +++ b/server/src/modules/versions/repository.ts @@ -275,4 +275,14 @@ export class VersionRepository extends Repository { return appVersions; }, manager || this.manager); } + + async getAllVersions(appId: string, manager?: EntityManager): Promise { + return dbTransactionWrap(async (manager: EntityManager) => { + const appVersions = await manager.find(AppVersion, { + where: { appId: appId }, + relations: ['user'], + }); + return appVersions; + }, manager || this.manager); + } } diff --git a/server/src/modules/versions/service.ts b/server/src/modules/versions/service.ts index 8af0ec4269..7ecb47575c 100644 --- a/server/src/modules/versions/service.ts +++ b/server/src/modules/versions/service.ts @@ -8,7 +8,7 @@ import { AppEnvironmentUtilService } from '@modules/app-environments/util.servic import { EntityManager, MoreThan } from 'typeorm'; import { dbTransactionWrap } from '@helpers/database.helper'; import { VersionsCreateService } from './services/create.service'; -import { camelizeKeys, decamelizeKeys } from 'humps'; +import { camelizeKeys } from 'humps'; import { PageService } from '@modules/apps/services/page.service'; import { EventsService } from '@modules/apps/services/event.service'; import { AppsUtilService } from '@modules/apps/util.service'; @@ -24,7 +24,7 @@ import { AUDIT_LOGS_REQUEST_CONTEXT_KEY } from '@modules/app/constants'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { AppGitRepository } from '@modules/app-git/repository'; import { AppHistoryUtilService } from '@modules/app-history/util.service'; -import { ACTION_TYPE } from '@modules/app-history/constants'; +import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; @Injectable() export class VersionService implements IVersionService { @@ -40,7 +40,8 @@ export class VersionService implements IVersionService { protected readonly versionsUtilService: VersionUtilService, protected readonly eventEmitter: EventEmitter2, protected readonly appGitRepository: AppGitRepository, - protected readonly appHistoryUtilService: AppHistoryUtilService + protected readonly appHistoryUtilService: AppHistoryUtilService, + protected readonly organizationGitRepository: OrganizationGitSyncRepository ) {} async getAllVersions(app: App): Promise<{ versions: Array }> { const result = await this.versionRepository.getVersionsInApp(app.id); @@ -52,76 +53,7 @@ export class VersionService implements IVersionService { } async createVersion(app: App, user: User, versionCreateDto: VersionCreateDto) { - const { versionName, versionFromId, versionDescription } = versionCreateDto; - if (!versionName || versionName.trim().length === 0) { - // need to add logic to get the version name -> from the version created at from - throw new BadRequestException('Version name cannot be empty.'); - } - const { organizationId } = user; - - const result = await dbTransactionWrap(async (manager: EntityManager) => { - const versionFrom = await manager.findOneOrFail(AppVersion, { - where: { id: versionFromId, appId: app.id }, - relations: ['dataSources', 'dataSources.dataQueries', 'dataSources.dataSourceOptions'], - }); - - const firstPriorityEnv = await this.appEnvironmentUtilService.get(organizationId, null, true, manager); - - const appVersion = await manager.save( - AppVersion, - manager.create(AppVersion, { - name: versionName, - appId: app.id, - definition: versionFrom?.definition, - currentEnvironmentId: firstPriorityEnv?.id, - createdAt: new Date(), - updatedAt: new Date(), - status: AppVersionStatus.DRAFT, - parentVersionId: versionCreateDto.versionFromId ? versionFromId : null, - description: versionDescription ? versionDescription : null, - }) - ); - - await this.createVersionService.setupNewVersion(appVersion, versionFrom, organizationId, manager); - - //APP_VERSION_CREATE audit - RequestContext.setLocals(AUDIT_LOGS_REQUEST_CONTEXT_KEY, { - userId: user.id, - organizationId: user.organizationId, - resourceId: app.id, - resourceName: app.name, - metadata: { - data: { - updatedAppVersionName: versionCreateDto.versionName, - updatedAppVersionFrom: versionCreateDto.versionFromId, - updatedAppVersionEnvironment: versionCreateDto.environmentId, - }, - }, - }); - - return decamelizeKeys(appVersion); - }); - - // Queue initial history capture for the created version - try { - await this.appHistoryUtilService.queueHistoryCapture( - result.id, - ACTION_TYPE.INITIAL_SNAPSHOT, - { - operation: 'version_create', - versionName: versionCreateDto.versionName, - versionFromId: versionCreateDto.versionFromId, - appId: app.id, - appName: app.name, - }, - false, - user.id - ); - } catch (error) { - console.error('Failed to queue initial history capture for version creation:', error); - } - - return result; + return await this.versionsUtilService.createVersion(app, user, versionCreateDto); } async deleteVersion(app: App, user: User, manager?: EntityManager): Promise { @@ -208,6 +140,7 @@ export class VersionService implements IVersionService { response['modules'] = await Promise.all(modules.map((module) => prepareResponse(module, undefined))); + // need to add freeze version logic here // need to add freeze version logic here return response; } @@ -218,7 +151,10 @@ export class VersionService implements IVersionService { await this.versionsUtilService.updateVersion(appVersion, appVersionUpdateDto); if (app.type === 'workflow') { await this.appUtilService.updateWorflowVersion(appVersion, appVersionUpdateDto, app); - } else if (appVersion.name !== appVersionUpdateDto.name) { + } else if ( + appVersion.name !== appVersionUpdateDto.name && + appVersionUpdateDto.status !== AppVersionStatus.PUBLISHED + ) { const versionRenameDto = { user: user, appVersion: appVersion, @@ -333,8 +269,8 @@ export class VersionService implements IVersionService { user: User, draftVersionDto: DraftVersionDto, manager?: EntityManager - ): Promise { - const { versionFromId } = draftVersionDto; + ): Promise { + const { versionFromId, versionType } = draftVersionDto; const parentVersion = await this.versionRepository.findVersion(versionFromId); const childVersionApps = await this.versionRepository.findParentVersionApps(versionFromId); const childVersionAppsCount = childVersionApps.length; @@ -342,6 +278,7 @@ export class VersionService implements IVersionService { ...draftVersionDto, versionName: `${parentVersion?.name}_${childVersionAppsCount + 1}`, versionDescription: '', + versionType: versionType, }; const draftVersion = await this.createVersion(app, user, createVersionDto); return draftVersion; diff --git a/server/src/modules/versions/services/create.service.ts b/server/src/modules/versions/services/create.service.ts index f765f7548f..d5016950d7 100644 --- a/server/src/modules/versions/services/create.service.ts +++ b/server/src/modules/versions/services/create.service.ts @@ -38,9 +38,9 @@ export class VersionsCreateService implements IVersionsCreateService { manager: EntityManager ): Promise { await dbTransactionWrap(async (manager: EntityManager) => { - (appVersion.showViewerNavigation = versionFrom.showViewerNavigation), - (appVersion.globalSettings = versionFrom.globalSettings), - (appVersion.pageSettings = versionFrom.pageSettings); + appVersion.showViewerNavigation = versionFrom.showViewerNavigation; + appVersion.globalSettings = versionFrom.globalSettings; + appVersion.pageSettings = versionFrom.pageSettings; await manager.save(appVersion); const oldDataQueryToNewMapping = await this.createNewDataSourcesAndQueriesForVersion( @@ -118,6 +118,7 @@ export class VersionsCreateService implements IVersionsCreateService { name: dataSource.name, kind: dataSource.kind, type: dataSource.type, + co_relation_id: dataSource?.co_relation_id, appVersionId: appVersion.id, }; const newDataSource = await manager.save(manager.create(DataSource, dataSourceParams)); @@ -131,6 +132,7 @@ export class VersionsCreateService implements IVersionsCreateService { options: dataQuery.options, dataSourceId: newDataSource.id, appVersionId: appVersion.id, + co_relation_id: dataQuery?.co_relation_id, }; const newQuery = await manager.save(manager.create(DataQuery, dataQueryParams)); @@ -146,6 +148,7 @@ export class VersionsCreateService implements IVersionsCreateService { newEvent.event = event.event; newEvent.index = event.index ?? index; newEvent.appVersionId = appVersion.id; + newEvent.co_relation_id = event?.co_relation_id; await manager.save(newEvent); }); @@ -163,6 +166,7 @@ export class VersionsCreateService implements IVersionsCreateService { options: globalQuery.options, dataSourceId: globalQuery.dataSourceId, appVersionId: appVersion.id, + co_relation_id: globalQuery?.co_relation_id, }; const newQuery = await manager.save(manager.create(DataQuery, dataQueryParams)); @@ -178,6 +182,7 @@ export class VersionsCreateService implements IVersionsCreateService { newEvent.event = event.event; newEvent.index = event.index ?? index; newEvent.appVersionId = appVersion.id; + newEvent.co_relation_id = event?.co_relation_id; await manager.save(newEvent); }); @@ -211,6 +216,7 @@ export class VersionsCreateService implements IVersionsCreateService { options: newOptions, dataSourceId: dataSourceMapping[dataSource.id], environmentId: appEnvironment.id, + // co_relation_id: dataSourceOption?.co_relation_id, need to review if we need this }) ); } @@ -401,6 +407,7 @@ export class VersionsCreateService implements IVersionsCreateService { disabled: page.disabled, hidden: page.hidden, appVersionId: appVersion.id, + co_relation_id: page.co_relation_id, }) ); oldPageToNewPageMapping[page.id] = savedPage.id; @@ -420,6 +427,7 @@ export class VersionsCreateService implements IVersionsCreateService { newEvent.event = event.event; newEvent.index = event.index ?? index; newEvent.appVersionId = appVersion.id; + newEvent.co_relation_id = event?.co_relation_id; await manager.save(newEvent); }); @@ -428,6 +436,7 @@ export class VersionsCreateService implements IVersionsCreateService { for (const component of page.components) { const newComponent = new Component(); newComponent.id = uuid.v4(); + newComponent.co_relation_id = component?.co_relation_id; oldComponentToNewComponentMapping[component.id] = newComponent.id; tempNewComponents.push(newComponent); } @@ -495,6 +504,7 @@ export class VersionsCreateService implements IVersionsCreateService { originalComponent.layouts.forEach((layout) => { const newLayout = new Layout(); newLayout.id = uuid.v4(); + newLayout.co_relation_id = layout?.co_relation_id; newLayout.type = layout.type; newLayout.top = layout.top; newLayout.left = layout.left; @@ -511,8 +521,8 @@ export class VersionsCreateService implements IVersionsCreateService { const componentEvents = allEvents.filter((event) => event.sourceId === originalComponent.id); componentEvents.forEach(async (event, index) => { const newEvent = new EventHandler(); - newEvent.id = uuid.v4(); + newEvent.co_relation_id = event?.co_relation_id; newEvent.name = event.name; newEvent.sourceId = newComponent.id; newEvent.target = event.target; @@ -617,7 +627,6 @@ export class VersionsCreateService implements IVersionsCreateService { eventDefinition.table = oldComponentToNewComponentMapping[eventDefinition.table]; } event.event = eventDefinition; - await manager.save(event); } } diff --git a/server/src/modules/versions/util.service.ts b/server/src/modules/versions/util.service.ts index 7c925de122..b88bc360f5 100644 --- a/server/src/modules/versions/util.service.ts +++ b/server/src/modules/versions/util.service.ts @@ -1,16 +1,31 @@ -import { AppVersion } from '@entities/app_version.entity'; +import { AppVersion, AppVersionStatus, AppVersionType } from '@entities/app_version.entity'; import { VersionRepository } from './repository'; import { AppVersionUpdateDto } from '@dto/app-version-update.dto'; import { BadRequestException, ForbiddenException, Injectable } from '@nestjs/common'; import { IVersionUtilService } from './interfaces/IUtilService'; import { dbTransactionWrap } from '@helpers/database.helper'; -import { EntityManager } from 'typeorm'; +import { EntityManager, Not } from 'typeorm'; import { App } from '@entities/app.entity'; import { User } from '@entities/user.entity'; +import { VersionsCreateService } from './services/create.service'; +import { AUDIT_LOGS_REQUEST_CONTEXT_KEY } from '@modules/app/constants'; +import { RequestContext } from '@modules/request-context/service'; +import { VersionCreateDto } from './dto'; +import { decamelizeKeys } from 'humps'; +import { AppEnvironmentUtilService } from '@modules/app-environments/util.service'; +import { AppHistoryUtilService } from '@modules/app-history/util.service'; +import { ACTION_TYPE } from '@modules/app-history/constants'; +import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; @Injectable() export class VersionUtilService implements IVersionUtilService { - constructor(protected readonly versionRepository: VersionRepository) {} + constructor( + protected readonly versionRepository: VersionRepository, + protected readonly createVersionService: VersionsCreateService, + protected readonly appEnvironmentUtilService: AppEnvironmentUtilService, + protected readonly organizationGitSyncRepository: OrganizationGitSyncRepository, + protected readonly appHistoryUtilService: AppHistoryUtilService + ) {} protected mergeDeep(target, source, seen = new WeakMap()) { if (!this.isObject(target)) { target = {}; @@ -97,6 +112,138 @@ export class VersionUtilService implements IVersionUtilService { }); } + private async validateDraftVersionConstraints( + app: App, + versionType: AppVersionType, + organizationId: string, + manager?: EntityManager + ): Promise { + const organizationGit = await this.organizationGitSyncRepository.findOrgGitByOrganizationId( + organizationId, + manager + ); + + if (organizationGit && organizationGit.isBranchingEnabled) { + // Only allow one draft version of type 'version' (not branch) + // Branch versions can have multiple drafts + // If versionType is not provided or is not BRANCH, check for existing draft + const isCreatingBranchVersion = versionType === AppVersionType.BRANCH; + + if (!isCreatingBranchVersion) { + const existingDraftVersion = await this.versionRepository.findOne({ + where: { + appId: app.id, + status: AppVersionStatus.DRAFT, + versionType: Not(AppVersionType.BRANCH), + }, + }); + + if (existingDraftVersion) { + throw new BadRequestException('Only one draft version is allowed when branching is enabled.'); + } + } + } + } + + async createVersion(app: App, user: User, versionCreateDto: VersionCreateDto, manager?: EntityManager) { + const { versionName, versionFromId, versionDescription, versionType } = versionCreateDto; + if (!versionName || versionName.trim().length === 0) { + // need to add logic to get the version name -> from the version created at from + throw new BadRequestException('Version name cannot be empty.'); + } + const { organizationId } = user; + const organizationGit = await this.organizationGitSyncRepository.findOrgGitByOrganizationId( + organizationId, + manager + ); + if (organizationGit && organizationGit.isBranchingEnabled) { + // Only allow one draft version of type 'version' (not branch) + // Branch versions can have multiple drafts + // If versionType is not provided or is not BRANCH, check for existing draft + const isCreatingBranchVersion = versionType === AppVersionType.BRANCH; + + if (!isCreatingBranchVersion) { + const existingDraftVersion = await this.versionRepository.findOne({ + where: { + appId: app.id, + status: AppVersionStatus.DRAFT, + versionType: Not(AppVersionType.BRANCH), + }, + }); + if (existingDraftVersion) { + throw new BadRequestException('Only one draft version is allowed when branching is enabled.'); + } + } + } + + const result = await dbTransactionWrap(async (manager: EntityManager) => { + const versionFrom = await manager.findOneOrFail(AppVersion, { + where: { id: versionFromId, appId: app.id }, + relations: ['dataSources', 'dataSources.dataQueries', 'dataSources.dataSourceOptions'], + }); + + const firstPriorityEnv = await this.appEnvironmentUtilService.get(organizationId, null, true, manager); + + const appVersion = await manager.save( + AppVersion, + manager.create(AppVersion, { + name: versionName, + appId: app.id, + definition: versionFrom?.definition, + currentEnvironmentId: firstPriorityEnv?.id, + createdAt: new Date(), + updatedAt: new Date(), + status: AppVersionStatus.DRAFT, + parentVersionId: versionCreateDto.versionFromId ? versionFromId : null, + description: versionDescription ? versionDescription : null, + versionType: versionType ? versionType : AppVersionType.VERSION, + createdBy: user.id, + co_relation_id: versionFrom.co_relation_id, + }) + ); + + await this.createVersionService.setupNewVersion(appVersion, versionFrom, organizationId, manager); + + //APP_VERSION_CREATE audit + RequestContext.setLocals(AUDIT_LOGS_REQUEST_CONTEXT_KEY, { + userId: user.id, + organizationId: user.organizationId, + resourceId: app.id, + resourceName: app.name, + metadata: { + data: { + updatedAppVersionName: versionCreateDto.versionName, + updatedAppVersionFrom: versionCreateDto.versionFromId, + updatedAppVersionEnvironment: versionCreateDto.environmentId, + }, + }, + }); + + return decamelizeKeys(appVersion); + }); + + // Queue initial history capture for the created version + try { + await this.appHistoryUtilService.queueHistoryCapture( + result.id, + ACTION_TYPE.INITIAL_SNAPSHOT, + { + operation: 'version_create', + versionName: versionCreateDto.versionName, + versionFromId: versionCreateDto.versionFromId, + appId: app.id, + appName: app.name, + }, + false, + user.id + ); + } catch (error) { + console.error('Failed to queue initial history capture for version creation:', error); + } + + return result; + } + async deleteVersion(app: App, user: User, manager?: EntityManager): Promise { return await dbTransactionWrap(async (manager: EntityManager) => { const numVersions = await this.versionRepository.getCount(app.id); diff --git a/server/src/modules/workflows/module.ts b/server/src/modules/workflows/module.ts index d11ceecea3..027bc51478 100644 --- a/server/src/modules/workflows/module.ts +++ b/server/src/modules/workflows/module.ts @@ -39,6 +39,7 @@ import { GroupPermissionsRepository } from '@modules/group-permissions/repositor import { WorkflowAccessGuard } from './guards/workflow-access.guard'; import { SubModule } from '@modules/app/sub-module'; import { UsersModule } from '@modules/users/module'; +import { OrganizationGitSyncRepository } from '@modules/git-sync/repository'; import { AppHistoryModule } from '@modules/app-history/module'; const WORKFLOW_SCHEDULE_QUEUE = 'workflow-schedule-queue'; @@ -180,6 +181,7 @@ export class WorkflowsModule extends SubModule { OrganizationConstantRepository, VersionRepository, AppGitRepository, + OrganizationGitSyncRepository, OrganizationRepository, AppsService, PageService, @@ -205,17 +207,17 @@ export class WorkflowsModule extends SubModule { WorkflowAccessGuard, RolesRepository, GroupPermissionsRepository, - ...(isMainImport ? [ - WorkflowStreamService, - AppsActionsListener, - // Only register BullMQ processors and schedule bootstrap when WORKER=true - // This allows running dedicated HTTP-only instances and worker instances - ...(process.env.WORKER === 'true' ? [ - WorkflowScheduleProcessor, - WorkflowExecutionProcessor, - ScheduleBootstrapService, - ] : []), - ] : []), + ...(isMainImport + ? [ + WorkflowStreamService, + AppsActionsListener, + // Only register BullMQ processors and schedule bootstrap when WORKER=true + // This allows running dedicated HTTP-only instances and worker instances + ...(process.env.WORKER === 'true' + ? [WorkflowScheduleProcessor, WorkflowExecutionProcessor, ScheduleBootstrapService] + : []), + ] + : []), ], controllers: [ WorkflowsController, From f5f380af6137151ee4020dfe9b062ee67595f61a Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Fri, 20 Feb 2026 23:56:54 +0530 Subject: [PATCH 09/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15327)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> --- frontend/ee | 2 +- server/ee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/ee b/frontend/ee index 2a21dc5fa3..84ef386f87 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 2a21dc5fa3c3706c3efb85082da2d41f749ee6cf +Subproject commit 84ef386f87d7917c78c12a15c85ebc95fad25dad diff --git a/server/ee b/server/ee index fda51bc8a4..07695453cb 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit fda51bc8a43d3019158dde608882f29b3d076e02 +Subproject commit 07695453cb0d5bca83327a0af8ab38d977a09490 From 1d2bbd7e62d58dcd15a588541770cbd87691f4f8 Mon Sep 17 00:00:00 2001 From: Midhun G S Date: Mon, 23 Feb 2026 21:07:02 +0530 Subject: [PATCH 10/22] chore: update version to 3.21.0-beta across all components (#15345) --- .version | 2 +- frontend/.version | 2 +- server/.version | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.version b/.version index b5c5dbe8d0..3d0446a0dc 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -3.20.101-lts +3.21.0-beta diff --git a/frontend/.version b/frontend/.version index b5c5dbe8d0..3d0446a0dc 100644 --- a/frontend/.version +++ b/frontend/.version @@ -1 +1 @@ -3.20.101-lts +3.21.0-beta diff --git a/server/.version b/server/.version index b5c5dbe8d0..3d0446a0dc 100644 --- a/server/.version +++ b/server/.version @@ -1 +1 @@ -3.20.101-lts +3.21.0-beta From d3eed2a8f35150a99321ece8dbb2eed2beab27bc Mon Sep 17 00:00:00 2001 From: Adish M Date: Tue, 24 Feb 2026 10:55:58 +0530 Subject: [PATCH 11/22] feat: enhance Dockerfile with nsjail and Python runtime setup --- .../pre-release/ee/ee-production.Dockerfile | 108 +++++++++++++++--- 1 file changed, 92 insertions(+), 16 deletions(-) diff --git a/docker/pre-release/ee/ee-production.Dockerfile b/docker/pre-release/ee/ee-production.Dockerfile index fb39eaa921..586a3d19a9 100644 --- a/docker/pre-release/ee/ee-production.Dockerfile +++ b/docker/pre-release/ee/ee-production.Dockerfile @@ -5,6 +5,50 @@ ENV NODE_OPTIONS="--max-old-space-size=4096" RUN npm i -g npm@10.9.2 && npm cache clean --force +# Build nsjail for Python sandboxing +RUN apt-get update && apt-get install -y --no-install-recommends \ + autoconf \ + bison \ + flex \ + gcc \ + g++ \ + libprotobuf-dev \ + libnl-route-3-dev \ + libtool \ + make \ + pkg-config \ + protobuf-compiler \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /build-nsjail +RUN git clone --depth 1 --branch 3.4 https://github.com/google/nsjail.git && \ + cd nsjail && \ + make && \ + strip nsjail + +# Build Python runtime with pre-installed packages +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3.11 \ + python3.11-venv \ + python3-pip \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +# Create isolated Python environment +RUN python3.11 -m venv /opt/python-runtime + +# Upgrade pip and install common packages +RUN /opt/python-runtime/bin/pip install --no-cache-dir --upgrade pip setuptools wheel && \ + /opt/python-runtime/bin/pip install --no-cache-dir \ + numpy==1.26.4 \ + pandas==2.2.1 \ + requests==2.31.0 \ + httpx==0.27.0 \ + python-dateutil==2.9.0 \ + pytz==2024.1 \ + pydantic==2.6.4 \ + typing-extensions==4.10.0 + RUN mkdir -p /app WORKDIR /app @@ -39,9 +83,10 @@ COPY ./package.json ./package.json # Build plugins COPY ./plugins/package.json ./plugins/package-lock.json ./plugins/ -RUN npm --prefix plugins ci --omit=dev +RUN npm --prefix plugins install COPY ./plugins/ ./plugins/ -RUN NODE_ENV=production npm --prefix plugins run build && npm --prefix plugins prune --omit=dev +RUN NODE_ENV=production npm --prefix plugins run build +RUN npm --prefix plugins prune --production ENV TOOLJET_EDITION=ee @@ -78,19 +123,25 @@ FROM debian:12-slim RUN apt-get update && \ apt-get install -y --no-install-recommends \ - curl \ - wget \ - gnupg \ - unzip \ - ca-certificates \ - xz-utils \ - tar \ - postgresql-client \ - redis \ - libaio1 \ - git \ - openssh-client \ - freetds-dev \ + curl \ + wget \ + gnupg \ + unzip \ + ca-certificates \ + xz-utils \ + tar \ + postgresql-client \ + redis \ + libaio1 \ + git \ + openssh-client \ + freetds-dev \ + python3.11 \ + python3.11-venv \ + libprotobuf32 \ + libnl-route-3-200 \ + procps \ + libcap2-bin \ && apt-get upgrade -y -o Dpkg::Options::="--force-confold" \ && apt-get autoremove -y \ && apt-get clean && rm -rf /var/lib/apt/lists/* @@ -102,7 +153,7 @@ RUN curl -O https://nodejs.org/dist/v22.15.1/node-v22.15.1-linux-x64.tar.xz \ && echo 'export PATH="/usr/local/lib/nodejs/bin:$PATH"' >> /etc/profile.d/nodejs.sh \ && /bin/bash -c "source /etc/profile.d/nodejs.sh" \ && rm node-v22.15.1-linux-x64.tar.xz -ENV PATH=/usr/local/lib/nodejs/bin:$PATH +ENV PATH=/usr/local/lib/nodejs/bin:/opt/python-runtime/bin:$PATH ENV NODE_ENV=production ENV TOOLJET_EDITION=ee @@ -130,6 +181,24 @@ RUN mkdir -p /app RUN useradd --create-home --home-dir /home/appuser appuser +# Copy nsjail and Python runtime from builder +COPY --from=builder /build-nsjail/nsjail/nsjail /usr/local/bin/nsjail +RUN chmod 4755 /usr/local/bin/nsjail + +# Copy Python runtime with pre-installed packages +COPY --from=builder /opt/python-runtime /opt/python-runtime + +# Copy nsjail configuration file +RUN mkdir -p /etc/nsjail +COPY --from=builder /app/server/ee/workflows/nsjail/python-execution.cfg /etc/nsjail/python-execution.cfg + +# Create Python execution directories +RUN mkdir -p \ + /tmp/python-execution \ + /tmp/python-bundles \ + && chmod 1777 /tmp/python-execution \ + && chmod 1777 /tmp/python-bundles + # Use the PostgREST binary from the builder stage COPY --from=builder --chown=appuser:0 /postgrest /usr/local/bin/postgrest @@ -156,6 +225,8 @@ COPY --from=builder --chown=appuser:0 /app/server/dist ./app/server/dist COPY --from=builder --chown=appuser:0 /app/server/ee/ai/assets ./app/server/ee/ai/assets COPY ./docker/pre-release/ee/ee-entrypoint.sh ./app/server/ee-entrypoint.sh +# Set group write permissions for frontend build files to support RedHat arbitrary user assignment +RUN chmod -R g+w /app/frontend/build # Create directory /home/appuser and set ownership to appuser RUN mkdir -p /home/appuser \ @@ -164,6 +235,11 @@ RUN mkdir -p /home/appuser \ && chmod -R g=u /home/appuser \ && npm cache clean --force +# Create gitsync directory with proper permissions for RedHat/OpenShift arbitrary UID support +RUN mkdir -p /app/server/tooljet/gitsync \ + && chown -R appuser:0 /app/server/tooljet \ + && chmod -R 2770 /app/server/tooljet/gitsync + # Create rsyslog directory for audit logs with proper permissions RUN mkdir -p /home/appuser/rsyslog \ && chown -R appuser:0 /home/appuser/rsyslog \ From fb009f86cf08b983129d0f81357d655d5672db01 Mon Sep 17 00:00:00 2001 From: Adish M Date: Tue, 24 Feb 2026 16:49:46 +0530 Subject: [PATCH 12/22] fix: update submodule checkout fallback branch to main --- cypress-tests/cypress-lts.Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cypress-tests/cypress-lts.Dockerfile b/cypress-tests/cypress-lts.Dockerfile index d4f3800466..5ae5eb8a65 100644 --- a/cypress-tests/cypress-lts.Dockerfile +++ b/cypress-tests/cypress-lts.Dockerfile @@ -24,14 +24,14 @@ RUN git checkout ${BRANCH_NAME} RUN git submodule update --init --recursive -# Checkout the same branch in submodules if it exists, otherwise fallback to lts-3.16 +# Checkout the same branch in submodules if it exists, otherwise fallback to main RUN git submodule foreach " \ if git show-ref --verify --quiet refs/heads/${BRANCH_NAME} || \ git ls-remote --exit-code --heads origin ${BRANCH_NAME}; then \ git checkout ${BRANCH_NAME}; \ else \ - echo 'Branch ${BRANCH_NAME} not found in submodule \$name, falling back to lts-3.16'; \ - git checkout lts-3.16; \ + echo 'Branch ${BRANCH_NAME} not found in submodule \$name, falling back to main'; \ + git checkout main; \ fi" # Scripts for building From 77d64d2845c8f3abc6cb2fc14a771acf64973bc8 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Mon, 2 Mar 2026 11:03:52 +0530 Subject: [PATCH 13/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15395)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> --- frontend/ee | 2 +- server/ee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/ee b/frontend/ee index 84ef386f87..e102ff435e 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 84ef386f87d7917c78c12a15c85ebc95fad25dad +Subproject commit e102ff435e1e81e01492101846298c117ea7a240 diff --git a/server/ee b/server/ee index 07695453cb..9971656e87 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit 07695453cb0d5bca83327a0af8ab38d977a09490 +Subproject commit 9971656e87d1018b38a543ae77814e0b328f5f6f From 18b1d748cdb14ab5ff6a5c7c0d8b738db1066a72 Mon Sep 17 00:00:00 2001 From: Sahil Dewangan <123866478+sahil7303@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:22:57 +0530 Subject: [PATCH 14/22] feat: Implement createGroup external api (#15353) * feat: Implement createGroup external api * feat: Refactor group permissions DTOs and validators for improved clarity and functionality * feat: Enhance external API group creation with security guard and feature initialization * feat: Update exports in module.ts to include GranularPermissionsUtilService * feat: Separate WorkflowPermissionsDto with validation and update exports in index.ts --------- Co-authored-by: Shantanu Mane Co-authored-by: gsmithun4 --- .../modules/external-apis/ability/index.ts | 1 + .../external-apis/constants/feature.ts | 4 + .../modules/external-apis/constants/index.ts | 1 + .../controllers/groups.controller.ts | 21 ++ .../modules/external-apis/dto/groups.dto.ts | 231 ++++++++++++++++++ server/src/modules/external-apis/dto/index.ts | 12 + server/src/modules/external-apis/module.ts | 24 +- .../src/modules/external-apis/types/index.ts | 1 + .../src/modules/group-permissions/module.ts | 2 +- 9 files changed, 288 insertions(+), 9 deletions(-) create mode 100644 server/src/modules/external-apis/controllers/groups.controller.ts create mode 100644 server/src/modules/external-apis/dto/groups.dto.ts diff --git a/server/src/modules/external-apis/ability/index.ts b/server/src/modules/external-apis/ability/index.ts index 31892cf749..047489076c 100644 --- a/server/src/modules/external-apis/ability/index.ts +++ b/server/src/modules/external-apis/ability/index.ts @@ -31,6 +31,7 @@ export class FeatureAbilityFactory extends AbilityFactory FEATURE_KEY.AUTO_RELEASE_APP, FEATURE_KEY.GENERATE_PAT, FEATURE_KEY.VALIDATE_PAT_SESSION, + FEATURE_KEY.CREATE_GROUP, ], User ); diff --git a/server/src/modules/external-apis/constants/feature.ts b/server/src/modules/external-apis/constants/feature.ts index 4746d59301..bf1be82228 100644 --- a/server/src/modules/external-apis/constants/feature.ts +++ b/server/src/modules/external-apis/constants/feature.ts @@ -77,5 +77,9 @@ export const FEATURES: FeaturesConfig = { license: LICENSE_FIELD.EXTERNAL_API, isPublic: true, }, + [FEATURE_KEY.CREATE_GROUP]: { + license: LICENSE_FIELD.EXTERNAL_API, + isPublic: true, + }, }, }; diff --git a/server/src/modules/external-apis/constants/index.ts b/server/src/modules/external-apis/constants/index.ts index 6d59bd5496..2013aee208 100644 --- a/server/src/modules/external-apis/constants/index.ts +++ b/server/src/modules/external-apis/constants/index.ts @@ -17,6 +17,7 @@ export enum FEATURE_KEY { EXPORT_APP = 'EXPORT_APP', GENERATE_PAT = 'GENERATE_PAT', VALIDATE_PAT_SESSION = 'VALIDATE_PAT_SESSION', + CREATE_GROUP = 'CREATE_GROUP', } export type DefaultDataSourceKind = 'restapi' | 'runjs' | 'runpy' | 'tooljetdb' | 'workflows'; diff --git a/server/src/modules/external-apis/controllers/groups.controller.ts b/server/src/modules/external-apis/controllers/groups.controller.ts new file mode 100644 index 0000000000..8fc3dc1396 --- /dev/null +++ b/server/src/modules/external-apis/controllers/groups.controller.ts @@ -0,0 +1,21 @@ +import { Controller, Param, Body, NotFoundException, UseGuards, Post, HttpCode, HttpStatus } from '@nestjs/common'; +import { CreateGroupExternalDto } from '../dto/groups.dto'; +import { InitFeature } from '@modules/app/decorators/init-feature.decorator'; +import { FEATURE_KEY } from '@modules/external-apis/constants'; +import { ExternalApiSecurityGuard } from '@ee/auth/guards/external-api-security.guard'; + +@Controller('ext') +export class ExternalApisGroupsController { + constructor() {} + + @InitFeature(FEATURE_KEY.CREATE_GROUP) + @UseGuards(ExternalApiSecurityGuard) + @Post('workspace/:workspaceId/groups') + @HttpCode(HttpStatus.CREATED) + async createGroup( + @Param('workspaceId') workspaceId: string, + @Body() createGroupDto: CreateGroupExternalDto + ): Promise { + throw new NotFoundException(); + } +} diff --git a/server/src/modules/external-apis/dto/groups.dto.ts b/server/src/modules/external-apis/dto/groups.dto.ts new file mode 100644 index 0000000000..ff9615681a --- /dev/null +++ b/server/src/modules/external-apis/dto/groups.dto.ts @@ -0,0 +1,231 @@ +import { + IsString, + IsNotEmpty, + IsBoolean, + IsOptional, + IsArray, + ValidateNested, + IsEnum, + Validate, + ValidatorConstraint, + ValidatorConstraintInterface, + ValidationArguments, + Matches, + MaxLength, +} from 'class-validator'; +import { Type, Transform } from 'class-transformer'; + +// Environment types for app permissions +export enum AppEnvironment { + DEVELOPMENT = 'development', + STAGING = 'staging', + PRODUCTION = 'production', + RELEASED = 'released', +} + +// Resource types for granular permissions +export enum GranularPermissionResourceType { + APP = 'app', + DATA_SOURCE = 'data_source', + WORKFLOW = 'workflow', +} + +// Custom validator for hideFromDashboard - can only be true when canEdit is false (view mode) +@ValidatorConstraint({ name: 'hideFromDashboardRequiresViewMode', async: false }) +class HideFromDashboardRequiresViewModeConstraint implements ValidatorConstraintInterface { + validate(_: any, args: ValidationArguments) { + const obj = args.object as AppPermissionsDto; + // hideFromDashboard is only configurable when canEdit is false + return !(obj.hideFromDashboard === true && obj.canEdit === true); + } + + defaultMessage() { + return 'hideFromDashboard can only be true when canEdit is false'; + } +} + +// App-specific permissions. +// canEdit is the single flag that drives view/edit mode: +// canEdit = true → internal: can_edit=true, can_view=false +// canEdit = false → internal: can_edit=false, can_view=true (hideFromDashboard is configurable) +export class AppPermissionsDto { + @IsBoolean() + @IsNotEmpty() + canEdit: boolean; + + @IsBoolean() + @IsOptional() + @Validate(HideFromDashboardRequiresViewModeConstraint) + hideFromDashboard?: boolean; + + @IsArray() + @IsEnum(AppEnvironment, { each: true }) + @IsOptional() + environments?: AppEnvironment[]; +} + +// Workflow-specific permissions +// canEdit = true → internal: can_edit=true, can_view=false +// canEdit = false → internal: can_edit=false, can_view=true +export class WorkflowPermissionsDto { + @IsBoolean() + @IsNotEmpty() + canEdit: boolean; +} + +@ValidatorConstraint({ name: 'mutuallyExclusive', async: false }) +class MutuallyExclusiveConstraint implements ValidatorConstraintInterface { + validate(_: any, args: ValidationArguments) { + const obj = args.object as DataSourcePermissionsDto; + if (obj.canUse === true && obj.canConfigure === true) { + return false; + } + return !(obj.canUse === false && obj.canConfigure === false); + } + + defaultMessage() { + return 'canUse and canConfigure are mutually exclusive - exactly one must be true'; + } +} + +// Data source-specific permissions +export class DataSourcePermissionsDto { + @IsBoolean() + @IsOptional() + canUse?: boolean; + + @IsBoolean() + @IsOptional() + @Validate(MutuallyExclusiveConstraint) + canConfigure?: boolean; +} + +// Custom validator: each entry must be either a valid UUID v4 or a non-empty string name +@ValidatorConstraint({ name: 'uuidOrName', async: false }) +class UuidOrNameConstraint implements ValidatorConstraintInterface { + validate(value: any) { + return typeof value === 'string' && value.trim().length > 0; + } + + defaultMessage() { + return 'each resource must be a valid UUID or a non-empty name string'; + } +} + +// Custom validator for resources array based on applyToAll flag +@ValidatorConstraint({ name: 'resourcesValidation', async: false }) +class ResourcesValidationConstraint implements ValidatorConstraintInterface { + validate(resources: string[], args: ValidationArguments) { + const obj = args.object as GranularPermissionDto; + if (obj.applyToAll === false && (!resources || resources.length === 0)) { + return false; + } + return !(obj.applyToAll === true && resources && resources.length > 0); + } + + defaultMessage(args: ValidationArguments) { + const obj = args.object as GranularPermissionDto; + if (obj.applyToAll === false) { + return 'resources must not be empty when applyToAll is false'; + } + return 'resources must be empty when applyToAll is true'; + } +} + +// Granular permission item in the request +export class GranularPermissionDto { + @IsEnum(GranularPermissionResourceType) + @IsNotEmpty() + type: GranularPermissionResourceType; + + @IsBoolean() + @IsNotEmpty() + applyToAll: boolean; + + @IsArray() + @Validate(UuidOrNameConstraint, { each: true }) + @Validate(ResourcesValidationConstraint) + resources: string[]; + + @ValidateNested() + @Type((opts) => { + const type = opts?.object?.type; + if (type === GranularPermissionResourceType.DATA_SOURCE) { + return DataSourcePermissionsDto; + } + if (type === GranularPermissionResourceType.WORKFLOW) { + return WorkflowPermissionsDto; + } + return AppPermissionsDto; + }) + @IsNotEmpty() + permissions: AppPermissionsDto | WorkflowPermissionsDto | DataSourcePermissionsDto; +} + +// Workspace-level permissions +export class WorkspacePermissionsDto { + @IsBoolean() + @IsOptional() + appCreate?: boolean; + + @IsBoolean() + @IsOptional() + appDelete?: boolean; + + @IsBoolean() + @IsOptional() + folderCRUD?: boolean; + + @IsBoolean() + @IsOptional() + orgConstantCRUD?: boolean; + + @IsBoolean() + @IsOptional() + workflowCreate?: boolean; + + @IsBoolean() + @IsOptional() + workflowDelete?: boolean; + + @IsBoolean() + @IsOptional() + dataSourceCreate?: boolean; + + @IsBoolean() + @IsOptional() + dataSourceDelete?: boolean; + + @IsBoolean() + @IsOptional() + appPromote?: boolean; + + @IsBoolean() + @IsOptional() + appRelease?: boolean; +} + +// Main request DTO for creating a group +export class CreateGroupExternalDto { + @IsString() + @IsNotEmpty() + @Transform(({ value }) => value?.trim()) + @MaxLength(50, { + message: 'Group name cannot exceed 50 characters', + }) + @Matches(/^[a-zA-Z0-9_ -]+$/, { + message: 'Group name can only contain letters, numbers, underscores, spaces and hyphens', + }) + name: string; + + @ValidateNested() + @Type(() => WorkspacePermissionsDto) + @IsOptional() + permissions?: WorkspacePermissionsDto; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => GranularPermissionDto) + @IsOptional() + granularPermissions?: GranularPermissionDto[]; +} diff --git a/server/src/modules/external-apis/dto/index.ts b/server/src/modules/external-apis/dto/index.ts index f93b9e22bf..25f56ae0e1 100644 --- a/server/src/modules/external-apis/dto/index.ts +++ b/server/src/modules/external-apis/dto/index.ts @@ -289,3 +289,15 @@ export class ValidatePATSessionDto { @IsString() accessToken: string; } + +// Export groups DTOs +export { + CreateGroupExternalDto, + GranularPermissionDto, + GranularPermissionResourceType, + AppEnvironment, + AppPermissionsDto, + DataSourcePermissionsDto, + WorkspacePermissionsDto, + WorkflowPermissionsDto, +} from './groups.dto'; diff --git a/server/src/modules/external-apis/module.ts b/server/src/modules/external-apis/module.ts index 4d2e657906..ca10a53db4 100644 --- a/server/src/modules/external-apis/module.ts +++ b/server/src/modules/external-apis/module.ts @@ -23,13 +23,19 @@ import { UserRepository } from '@modules/users/repositories/repository'; export class ExternalApiModule extends SubModule { static async register(configs?: { IS_GET_CONTEXT: boolean }, isMainImport: boolean = false): Promise { - const { ExternalApisController, ExternalApisService, ExternalApiUtilService, ExternalApisAppsController } = - await this.getProviders(configs, 'external-apis', [ - 'controller', - 'service', - 'util.service', - 'controllers/apps.controller', - ]); + const { + ExternalApisController, + ExternalApisService, + ExternalApiUtilService, + ExternalApisAppsController, + ExternalApisGroupsController, + } = await this.getProviders(configs, 'external-apis', [ + 'controller', + 'service', + 'util.service', + 'controllers/apps.controller', + 'controllers/groups.controller', + ]); return { module: ExternalApiModule, @@ -61,7 +67,9 @@ export class ExternalApiModule extends SubModule { UserRepository, AppsRepository, ], - controllers: isMainImport ? [ExternalApisController, ExternalApisAppsController] : [], + controllers: isMainImport + ? [ExternalApisController, ExternalApisAppsController, ExternalApisGroupsController] + : [], exports: [ExternalApiUtilService], }; } diff --git a/server/src/modules/external-apis/types/index.ts b/server/src/modules/external-apis/types/index.ts index 6970352ff2..e5d2229b19 100644 --- a/server/src/modules/external-apis/types/index.ts +++ b/server/src/modules/external-apis/types/index.ts @@ -21,6 +21,7 @@ interface Features { [FEATURE_KEY.EXPORT_APP]: FeatureConfig; [FEATURE_KEY.GENERATE_PAT]: FeatureConfig; [FEATURE_KEY.VALIDATE_PAT_SESSION]: FeatureConfig; + [FEATURE_KEY.CREATE_GROUP]: FeatureConfig; } export interface FeaturesConfig { diff --git a/server/src/modules/group-permissions/module.ts b/server/src/modules/group-permissions/module.ts index 6c8d478242..4a349389de 100644 --- a/server/src/modules/group-permissions/module.ts +++ b/server/src/modules/group-permissions/module.ts @@ -46,7 +46,7 @@ export class GroupPermissionsModule extends SubModule { GroupPermissionsRepository, FeatureAbilityFactory, ], - exports: [GroupPermissionsUtilService], + exports: [GroupPermissionsUtilService, GranularPermissionsUtilService], }; } } From 29369bd7d858e2dc336fa5d0700c8c45577198b8 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:24:53 +0530 Subject: [PATCH 15/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15430)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> --- server/ee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/ee b/server/ee index 9971656e87..db269e881c 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit 9971656e87d1018b38a543ae77814e0b328f5f6f +Subproject commit db269e881cf9ec4595344cfffc54d0ac5c35dd2d From d987e4e3ccc7542b729eb0ecd8a65d374e6f1237 Mon Sep 17 00:00:00 2001 From: Parth <108089718+parthy007@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:29:28 +0530 Subject: [PATCH 16/22] Feature/git sync multi branching support phase - 2.1 (#15361) * added app_versions fields * added data migration for backward compatibility * added ce specific logic * fixed ce migration (need to dev-test) * moved to data migration * migration changes * added endpoint to create draft version * backend changes * added draft to app_import scenario * added version description * minor changes (needs improvement) * fixed breaking dropdown in editor * updated submodule commits * revert package.json * revert ui not used changes * submodule changes * reverting non used files * ui changes * ui changes * ui changes * ui changes * ui changes * copywriting changes * ui changes * ui changes * edit version modal changes * ui integration changes * added button solid and removed unused css * removed commented code from create version modal * updated button size to use large * ui changes * draft version modal changes * added sub-module commits to main * draft version endpoint changes * ui changes for draft version modal * fix breaking ui * ui changes for banner * minor ui changes * remove scss changes from themes file * removed unused components (cleanup) * removed unused components (pr cleanup) * draft version changes * create version modal changes * canvas banner fixes * comment creation logic * refactor: version dropdown * update endpoint changes * fix: promote logic * update submodule * fix: released version and create version modal * fix draft version creation * minor ui changes * minor backend fixes * tooltip changes * added all components in same folder * added minor comments * import fixes * refactor files * fix: overlay issues * fix: on version creation * fix ce bugs * bug fixes * bug fixes * bug fixes * add migrations * splitting changes for import export * minor fixes * draft version of adapter for import -export * git sync minor changes * removed updatedAt from data queries * bug fixes * backend changes * made field optional * added get all branch endpoint (pending to test) * migration changes * branch creation endpoint and dto changes * app_version util service changes * fixed version type changes * branching related changes * chore: Update submodule hash * added logic to allow only single draft version for branching feature * added default value as true for branching * added feature keys * minor changes * minor changes * minor fixes * initial branching support * minor changes * added created by field in app_versions table * minor changes * branching api fixes * bug fixes * minor fix * fix: auto-commit during version creation * chore: update frontend submodule hash * pull changes * fix: include organisationId in fetchPr * chore: update server submodule hash * minor fix (pending to dev test) * scss changes * remove git sync css from themes file * minor change * fix styling * fix: add copy-writing for main branch lockedbanner * chore: update frontend submodule hash * fix: version listing * chore: Update server submodule hash * fix banner lock * base merge * chore: update frontend submodule hash * fix: version listing * merge base * fix: add new prop in AppGitPushDto * chore: update frontend & server submodule hash * fix: auto-commit on promoting the default branch * fix: dropdown states * fix: dropdown states * fix: hide pull commit button from promoted environments * fix: enhance git sync handling for draft versions and improve version creation logic * fix: remove unnecessary whitespace in VersionManagerDropdown component * freeze state fixes * fix: correctly read branch author * chore: update frontend and backend submodule * fixes * fix: atomic changes during branch creation * fix: error propagation * fixed freeze state * refactor methods * submodule update * fix: update autoCommit default state and disable checkbox in CreateBranchModal; remove tooltips in LifecycleCTAButton * feat: enhance BranchDropdown and LifecycleCTAButton; update icons and styles; add Check2 icon * minor fixes * feat: update BranchDropdown to always show Create PR button; enhance CreateBranchModal to refresh versions and include releasedVersionId; improve CreateDraftVersionModal to refresh versions after creating a draft * chore: update subproject commit reference in server/ee * feat: enhance CreateDraftVersionModal to improve version selection logic and add debugging logs * chore: update server submodule * chore: update subproject commit reference in frontend/ee * update submodule * update submodule * chore: comment out import option label in BaseImportAppMenu * ce build fix * fixes * minor fixes * fixes build issues * Git Sync Phase2 Changes (#14886) * Feature: Adding co-relation-id mapping (#14621) * feat: add migration for co_relation_id column * minor cleanup * added entities and dummy util file * fix: Add co-relation column for events * fixed compilation issues * added fields * minor changes * added timestamp cleanups * modified existing migration t * minor updates in co_relation id changes * fix: update migration script * feat: map co-relation-id during pull * chore: update server submodule * fixed layout co_relation id issue * fixed migration changes * revert * timestamp fixes * minor fixes * minor fix * chore: update server submodule (#14755) --------- Co-authored-by: rohanlahori * resolved merge conflicts * fixed app crashing * Feature/version tagging (#14903) * feat: add migration for co_relation_id column * minor cleanup * added entities and dummy util file * fix: Add co-relation column for events * fixed compilation issues * added fields * minor changes * added timestamp cleanups * modified existing migration t * minor updates in co_relation id changes * fix: update migration script * feat: map co-relation-id during pull * chore: update server submodule * fixed layout co_relation id issue * fixed migration changes * revert * timestamp fixes * minor fixes * minor fix * added migration * minor changes * migration fix * dto changes * fixes * feature: api call for github tags post saving version * chore: update frontend & server submodule hash * fix for sub-branch pull * minor fix * feat: send message in api call * chore: update frontend & server submodule hash * chore: update frontend submodule hash * chore: update frontend submodule hash * minor fixes in import flow * fix: remove await from createGit tag * chore: Update server & frontend submodule hash * save version before committing * removed all logs * removed unused console logs * removed logs * fixes * minor fixes * fixes * removed commit changes flow from draft versions * version id fix * minor fixes * added latest changes endpoint using app Name * co_relation_id fix * added co_relation id changes * fixed co_relation id import issue * minor ui fix * fixes for tag flow * version tag fixes * submodule commits --------- Co-authored-by: parthy007 * fixed appId issue * commented not used entity field * minor co_relation_id fix * auto-commit on app creation changes * normalize(folder-apps): enforce single folder per app using created_at * Changed message * feat: enhance branch and version management UI with improved styles and functionality * Toast message copywritin * git sync related things * feat: Add tooljet folder architecture to gitsync * fix: remove autocommit on app creation * chore: Update server and frontend submodules * git sync apps & folder restriction * chore: Update server and frontend submodules * fix: restrict app rename * feat: Add version dropdown on app import * chore: Update server submodule hash * moved some logic to util.service.ts * fix branch dropdown and draft button status * feat: Support saved version import on app name change * chore: Update server & frontend submodule hash * chore: Update server and frontend server submodule * fix: add flag to skip folder check * chore: Update server and frontend submodules * chore: Update frontend submodule hash * chore: Update frontend & server submodule hash * fix: version name in version dropdown of import modal * fix: sub module * chore: update server and frontend submodule hashes * fix: send correct version name * fix: retriggering of renaming listner * chore: Update frontend & server submodule hash * fix: latest commit on pull tab * rebase submodule * fix imported app version status * remove draft tag on version dropdown in modal * version desc. optional & app removel message & empty version push err message * fix: restrict app rename without draft version * chore: Update frontend & server submodule hash * fix: latest commit on pull modal * fixed the folder success toast (#15272) * fix: git commit on version creation * fix commit button states on valid/invalid license * chore: Update frontend & server submodule hash * fix: pull error text --------- Co-authored-by: Parth <108089718+parthy007@users.noreply.github.com> Co-authored-by: parthy007 Co-authored-by: Pratush Co-authored-by: Vijaykant Yadav Co-authored-by: Pratush Co-authored-by: YuktiGoyal02 <100783212+YuktiGoyal02@users.noreply.github.com> * refactor: remove commits to main fix: check for tag existense before creation * chore: Update frontend & server submodule hash * enable: folder rename and sync * fix: check for released version correctly before deleting * chore: Update server submodule hash * fix: update error & tooltip message * chore: added frontend submodule hash * Chnaged version name to branch name in createBranchModal && display tag specific message in import from git modal * fix: app renaming on org git disabled * fix app rename logic * fix linting * fix: allow rename for local apps * fix: folder rename * fix:version dropdown search box in dark mode * fix: allow rename push for sub-branches * fix: app moving inside folder * fix: remove app from folder * chore: Update server and frontend submodule hash * fix: push to main on app creation, cloning & template is disabled * fix: allow rename when for local app without draft * fix: allow app renaming if git is disabled * fix: stop filtering tags & commit * chore: update frontend submodule hash * fix: change label fix: add error for saving empty version * chore: Update submodule hashes * fix: show search field only when actual versions exceed 5, excluding branche * fix: push to sub-branch * chore: update submodule hash * fix: override versionType to VERSION during git pull import * fix: revert the change made to app-import-export chore: update submodule hash * chore: Update server submodule hash * fix: module freezing issue * fix: unfreeze module * fix: allow component deletion in git-synced workspace * fix: bypass editor freeze for modules in git-enabled workspaces * chore: update frontend submodule hash --------- Co-authored-by: rohanlahori Co-authored-by: Vijaykant Yadav Co-authored-by: gsmithun4 Co-authored-by: Rohan Lahori <64496391+rohanlahori@users.noreply.github.com> Co-authored-by: Pratush Co-authored-by: Pratush Co-authored-by: YuktiGoyal02 <100783212+YuktiGoyal02@users.noreply.github.com> --- frontend/ee | 2 +- .../AppCanvas/ConfigHandle/ConfigHandle.jsx | 6 +- .../AppCanvas/DeleteWidgetConfirmation.jsx | 3 +- .../src/AppBuilder/AppCanvas/Grid/Grid.jsx | 2 +- .../AppBuilder/AppCanvas/HotkeyProvider.jsx | 4 +- .../AppCanvas/NoComponentCanvasContainer.jsx | 4 +- .../Elements/DropdownMenu/AddQueryBtn.jsx | 4 +- .../AppBuilder/Header/CreateBranchModal.jsx | 4 +- .../AppBuilder/Header/CreateVersionModal.jsx | 90 ++++++++++++++----- .../src/AppBuilder/Header/EditAppName.jsx | 27 +++++- .../AppBuilder/Header/FreezeVersionInfo.jsx | 4 +- .../src/AppBuilder/Header/HeaderActions.jsx | 6 +- .../VersionManager/VersionManagerDropdown.jsx | 5 +- .../VersionManager/VersionSearchField.jsx | 1 - .../useCallbackActions.js | 4 +- .../Components/QueryManagerBody.jsx | 4 +- .../Components/QueryManagerHeader.jsx | 7 +- .../src/AppBuilder/QueryPanel/QueryCard.jsx | 4 +- .../AppBuilder/QueryPanel/QueryDataPane.jsx | 7 +- .../ComponentsManagerTab.jsx | 2 +- .../RightSideBar/Inspector/Inspector.jsx | 6 +- .../AppBuilder/RightSideBar/RightSideBar.jsx | 2 +- .../_stores/slices/appVersionSlice.js | 3 +- .../_stores/slices/componentsSlice.js | 8 +- frontend/src/HomePage/HomePage.jsx | 74 +++++++-------- frontend/src/_components/AppModal.jsx | 5 +- .../_components/SortableList/SortableList.jsx | 4 +- frontend/src/_services/git_sync.service.js | 20 +++++ .../PromoteConfirmationModal.jsx | 73 ++++++++------- server/ee | 2 +- server/src/modules/apps/dto/index.ts | 4 + server/src/modules/apps/service.ts | 32 ++++++- server/src/modules/folder-apps/service.ts | 11 +-- .../src/modules/folder-apps/util.service.ts | 20 +---- server/src/modules/folders/service.ts | 44 +++------ server/src/modules/versions/util.service.ts | 3 +- 36 files changed, 300 insertions(+), 201 deletions(-) diff --git a/frontend/ee b/frontend/ee index e102ff435e..36dc07f486 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit e102ff435e1e81e01492101846298c117ea7a240 +Subproject commit 36dc07f486a5fac781fe244a9ac2dbe5b76af2a9 diff --git a/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx b/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx index 607a6cda07..eced23acd4 100644 --- a/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx +++ b/frontend/src/AppBuilder/AppCanvas/ConfigHandle/ConfigHandle.jsx @@ -36,9 +36,9 @@ export const ConfigHandle = ({ subContainerIndex, isDynamicHeightEnabled, }) => { - const { moduleId } = useModuleContext(); + const { moduleId, isModuleEditor } = useModuleContext(); const isModulesEnabled = useStore((state) => state.license.featureAccess?.modulesEnabled, shallow); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const componentName = useStore((state) => state.getComponentDefinition(id, moduleId)?.component?.name || '', shallow); const isMultipleComponentsSelected = useStore( (state) => (findHighestLevelofSelection(state?.selectedComponents)?.length > 1 ? true : false), @@ -86,7 +86,7 @@ export const ConfigHandle = ({ const deleteComponents = () => { const selectedComponents = getSelectedComponents(); if (selectedComponents.length > 0) { - setWidgetDeleteConfirmation(true); + setWidgetDeleteConfirmation(true, isModuleEditor); } }; diff --git a/frontend/src/AppBuilder/AppCanvas/DeleteWidgetConfirmation.jsx b/frontend/src/AppBuilder/AppCanvas/DeleteWidgetConfirmation.jsx index c7741ebb89..17aab95ea7 100644 --- a/frontend/src/AppBuilder/AppCanvas/DeleteWidgetConfirmation.jsx +++ b/frontend/src/AppBuilder/AppCanvas/DeleteWidgetConfirmation.jsx @@ -7,9 +7,10 @@ export const DeleteWidgetConfirmation = ({ darkMode }) => { const showWidgetDeleteConfirmation = useStore((state) => state.showWidgetDeleteConfirmation, shallow); const setWidgetDeleteConfirmation = useStore((state) => state.setWidgetDeleteConfirmation, shallow); const deleteComponents = useStore((state) => state.deleteComponents, shallow); + const deleteTargetIsModuleEditor = useStore((state) => state.deleteTargetIsModuleEditor, shallow); const handleConfirmDelete = () => { - deleteComponents(); + deleteComponents(undefined, 'canvas', { isModuleEditor: deleteTargetIsModuleEditor }); }; return ( diff --git a/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx b/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx index 743b51ff1b..a95d839cc4 100644 --- a/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx +++ b/frontend/src/AppBuilder/AppCanvas/Grid/Grid.jsx @@ -176,7 +176,7 @@ export default function Grid({ gridWidth, currentLayout, mainCanvasWidth }) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [noOfBoxs, triggerCanvasUpdater, menuPosition, hideLogo, hideHeader, isPageMenuHidden]); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const handleResizeStop = useCallback( (boxList) => { diff --git a/frontend/src/AppBuilder/AppCanvas/HotkeyProvider.jsx b/frontend/src/AppBuilder/AppCanvas/HotkeyProvider.jsx index fc1930c69a..c70aa0ed6b 100644 --- a/frontend/src/AppBuilder/AppCanvas/HotkeyProvider.jsx +++ b/frontend/src/AppBuilder/AppCanvas/HotkeyProvider.jsx @@ -14,7 +14,7 @@ export const HotkeyProvider = ({ children, mode, currentLayout, canvasMaxWidth, const handleRedo = useStore((state) => state.handleRedo); const setWidgetDeleteConfirmation = useStore((state) => state.setWidgetDeleteConfirmation); const moveComponentPosition = useStore((state) => state.moveComponentPosition, shallow); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const enableReleasedVersionPopupState = useStore((state) => state.enableReleasedVersionPopupState, shallow); const clearSelectedComponents = useStore((state) => state.clearSelectedComponents, shallow); const getSelectedComponents = useStore((state) => state.getSelectedComponents, shallow); @@ -53,7 +53,7 @@ export const HotkeyProvider = ({ children, mode, currentLayout, canvasMaxWidth, const deleteComponents = () => { const selectedComponents = getSelectedComponents(); if (selectedComponents.length > 0) { - setWidgetDeleteConfirmation(true); + setWidgetDeleteConfirmation(true, isModuleEditor); } }; diff --git a/frontend/src/AppBuilder/AppCanvas/NoComponentCanvasContainer.jsx b/frontend/src/AppBuilder/AppCanvas/NoComponentCanvasContainer.jsx index 9da4e300ec..bcec8d6c56 100644 --- a/frontend/src/AppBuilder/AppCanvas/NoComponentCanvasContainer.jsx +++ b/frontend/src/AppBuilder/AppCanvas/NoComponentCanvasContainer.jsx @@ -5,12 +5,14 @@ import BulkIcon from '@/_ui/Icon/BulkIcons'; import { getSubpath } from '@/_helpers/routes'; import useStore from '@/AppBuilder/_stores/store'; import { shallow } from 'zustand/shallow'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; const NoComponentCanvasContainer = () => { + const { isModuleEditor } = useModuleContext(); const sampleDataSource = useStore((state) => state.sampleDataSource, shallow); const createDataQuery = useStore((state) => state.dataQuery.createDataQuery, shallow); const setPreviewData = useStore((state) => state.queryPanel.setPreviewData, shallow); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const expandQueryPaneIfNeeded = useStore((state) => state.queryPanel.expandQueryPaneIfNeeded); const queryBoxText = sampleDataSource diff --git a/frontend/src/AppBuilder/CodeBuilder/Elements/DropdownMenu/AddQueryBtn.jsx b/frontend/src/AppBuilder/CodeBuilder/Elements/DropdownMenu/AddQueryBtn.jsx index 1ea8a4e175..3358445587 100644 --- a/frontend/src/AppBuilder/CodeBuilder/Elements/DropdownMenu/AddQueryBtn.jsx +++ b/frontend/src/AppBuilder/CodeBuilder/Elements/DropdownMenu/AddQueryBtn.jsx @@ -1,13 +1,15 @@ import React, { useRef, useEffect } from 'react'; import useStore from '@/AppBuilder/_stores/store'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; import { OverlayTrigger, Popover } from 'react-bootstrap'; import DataSourceSelect from '@/AppBuilder/QueryManager/Components/DataSourceSelect'; import SolidIcon from '@/_ui/Icon/SolidIcons'; import { FileCode2 } from 'lucide-react'; const AddQueryBtn = ({ darkMode, disabled: _disabled, onQueryCreate, showMenu, setShowMenu }) => { + const { isModuleEditor } = useModuleContext(); const selectRef = useRef(); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const disabled = _disabled || shouldFreeze; useEffect(() => { diff --git a/frontend/src/AppBuilder/Header/CreateBranchModal.jsx b/frontend/src/AppBuilder/Header/CreateBranchModal.jsx index 46be9f9d16..21933be537 100644 --- a/frontend/src/AppBuilder/Header/CreateBranchModal.jsx +++ b/frontend/src/AppBuilder/Header/CreateBranchModal.jsx @@ -336,7 +336,7 @@ export function CreateBranchModal({ onClose, onSuccess, appId, organizationId }) id="branch-name-input" type="text" className={`branch-modal-form-input ${validationError ? 'form-input-error' : ''}`} - placeholder="Enter version name" + placeholder="Enter branch name" value={branchName} onChange={handleBranchNameChange} onKeyDown={handleKeyDown} @@ -344,7 +344,7 @@ export function CreateBranchModal({ onClose, onSuccess, appId, organizationId }) autoFocus /> {validationError &&
    {validationError}
    } -
    Version name must be unique and max 50 characters
    +
    Branch name must be unique and max 50 characters
    {/* Auto-commit checkbox */} diff --git a/frontend/src/AppBuilder/Header/CreateVersionModal.jsx b/frontend/src/AppBuilder/Header/CreateVersionModal.jsx index 4079d9543f..16bc266487 100644 --- a/frontend/src/AppBuilder/Header/CreateVersionModal.jsx +++ b/frontend/src/AppBuilder/Header/CreateVersionModal.jsx @@ -42,6 +42,7 @@ const CreateVersionModal = ({ currentEnvironment, environments, setIsEditorFreezed, + appGit, } = useStore( (state) => ({ changeEditorVersionAction: state.changeEditorVersionAction, @@ -58,6 +59,7 @@ const CreateVersionModal = ({ currentEnvironment: state.selectedEnvironment, environments: state.environments, setIsEditorFreezed: state.setIsEditorFreezed, + appGit: state.appGit, }), shallow ); @@ -149,6 +151,32 @@ const CreateVersionModal = ({ setIsCreatingVersion(true); try { + if (isGitSyncEnabled && isBranchingEnabled) { + if (!appGit?.git_app_name || !appGit?.id) { + toast.error( + "Empty apps can't be versioned. Build your app first and then save your work through version control." + ); + setIsCreatingVersion(false); + return; + } + + try { + const tagCheck = await gitSyncService.checkTagExists(appId, versionName.trim()); + if (tagCheck.exists) { + toast.error( + `Cannot save: Tag '${tagCheck.tagName}' already exists. ` + + `Please rename your version to a unique name before saving.` + ); + setIsCreatingVersion(false); + return; + } + } catch (error) { + // If check fails, log warning but allow save to proceed + // (tag creation will fail separately if there's an issue) + console.warn('Tag existence check failed, proceeding with save', error); + } + } + // Only call git-related APIs if git sync is enabled await appVersionService.save(appId, selectedVersionForCreation.id, { name: versionName, @@ -156,29 +184,41 @@ const CreateVersionModal = ({ // need to add commit changes logic here status: 'PUBLISHED', }); - if (isGitSyncEnabled) { - // The backend's version-rename-commit event is suppressed when the status is - // also changing to PUBLISHED (save-version flow), so there's no competing push. - // We always handle the commit here with the correct "Version Created" message. - const updatedVersionData = { - ...selectedVersionForCreation, - name: versionName, - description: versionDescription, - }; - handleCommitOnVersionCreation(updatedVersionData, selectedVersion) - .then((commitDone) => { - if (!commitDone) return; - if (isBranchingEnabled) { - return gitSyncService.createGitTag( - appId, - selectedVersionForCreation.id, - versionDescription || `Version ${versionName.trim()} created` - ); - } - }) + // if (isGitSyncEnabled) { + // // The backend's version-rename-commit event is suppressed when the status is + // // also changing to PUBLISHED (save-version flow), so there's no competing push. + // // We always handle the commit here with the correct "Version Created" message. + // const updatedVersionData = { + // ...selectedVersionForCreation, + // name: versionName, + // description: versionDescription, + // }; + // handleCommitOnVersionCreation(updatedVersionData, selectedVersion) + // .then((commitDone) => { + // if (!commitDone) return; + // if (isBranchingEnabled) { + // return gitSyncService.createGitTag( + // appId, + // selectedVersionForCreation.id, + // versionDescription || `Version ${versionName.trim()} created` + // ); + // } + // }) + // .catch((error) => { + // console.error('Commit or tag failed:', error); + // toast.error(error?.data?.message || 'Commit or tag failed'); + // }); + // } + + if (isGitSyncEnabled && isBranchingEnabled) { + gitSyncService + .createGitTag( + appId, + selectedVersionForCreation.id, + versionDescription || `Version ${versionName.trim()} created` + ) .catch((error) => { - console.error('Commit or tag failed:', error); - toast.error(error?.data?.message || 'Commit or tag failed'); + toast.error(error?.data?.message || 'Tag creation failed'); }); } @@ -349,7 +389,8 @@ const CreateVersionModal = ({
    */} - {isGitSyncEnabled && ( + {/* Disabling autoCommit */} + {/* {isGitSyncEnabled && (
    - )} + )} */} +
    [ state.appStore.modules[moduleId].app.appId, state.appStore.modules[moduleId].app.appName, state.setAppName, state.appStore.modules[moduleId].app.creationMode, state.selectedVersion, + state.orgGit, + state.appGit, ], shallow ); const isDraftVersion = selectedVersion?.status === 'DRAFT'; - const isRenameDisabled = !isDraftVersion; + const isGitSyncEnabled = orgGit?.git_ssh?.is_enabled || orgGit?.git_https?.is_enabled || orgGit?.git_lab?.is_enabled; + const isAppCommittedToGit = !!appGit?.id; + const isOnDefaultBranch = selectedVersion?.versionType !== 'branch'; + const isRenameDisabled = !isGitSyncEnabled + ? false + : !isAppCommittedToGit + ? !isDraftVersion + : !isDraftVersion || isOnDefaultBranch; + + const getDisabledTooltipMessage = () => { + if (isGitSyncEnabled && isAppCommittedToGit && isOnDefaultBranch) { + return "Renaming isn't allowed on master. Switch branch to update name."; + } + if (!isDraftVersion && isGitSyncEnabled) { + return 'Renaming of app is only allowed on draft versions'; + } + return appName; + }; const [showRenameModal, setShowRenameModal] = useState(false); @@ -35,7 +54,7 @@ function EditAppName() { return true; } try { - await appsService.saveApp(appId, { name: sanitizedName }); + await appsService.saveApp(appId, { name: sanitizedName, editingVersionId: selectedVersion?.id }); setAppName(sanitizedName); toast.success('App name has been updated!'); return true; @@ -53,7 +72,7 @@ function EditAppName() { <>
    diff --git a/frontend/src/AppBuilder/Header/FreezeVersionInfo.jsx b/frontend/src/AppBuilder/Header/FreezeVersionInfo.jsx index 92480d19e9..c0f8cea18e 100644 --- a/frontend/src/AppBuilder/Header/FreezeVersionInfo.jsx +++ b/frontend/src/AppBuilder/Header/FreezeVersionInfo.jsx @@ -2,12 +2,14 @@ import React from 'react'; import cx from 'classnames'; import Branch from '@assets/images/icons/branch.svg'; import useStore from '@/AppBuilder/_stores/store'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; const FreezeVersionInfo = ({ info = 'App cannot be edited after promotion. Please create a new version from Development to make any changes.', hide = false, }) => { - const isViewOnly = useStore((state) => state.getShouldFreeze()); + const { isModuleEditor } = useModuleContext(); + const isViewOnly = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const isAiOperationInProgress = useStore((state) => state?.ai?.isLoading); if (!isViewOnly || hide || isAiOperationInProgress) return null; diff --git a/frontend/src/AppBuilder/Header/HeaderActions.jsx b/frontend/src/AppBuilder/Header/HeaderActions.jsx index 5101b3ea4b..1f1a9218fb 100644 --- a/frontend/src/AppBuilder/Header/HeaderActions.jsx +++ b/frontend/src/AppBuilder/Header/HeaderActions.jsx @@ -10,8 +10,10 @@ import { Link } from 'react-router-dom'; import { useAppPreviewLink } from '@/_hooks/useAppPreviewLink'; import { ToggleLayoutButtons } from './ToggleLayoutButtons'; import { Button as ButtonComponent } from '@/components/ui/Button/Button'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; const HeaderActions = function HeaderActions ({ darkMode, showFullWidth, showPreviewBtn = true }) { + const { isModuleEditor } = useModuleContext(); const { currentLayout, canUndo, @@ -25,8 +27,8 @@ const HeaderActions = function HeaderActions ({ darkMode, showFullWidth, showPre } = useStore( (state) => ({ currentLayout: state.currentLayout, - canUndo: state.canUndo && !(state.isEditorFreezed || state.isVersionReleased), - canRedo: state.canRedo && !(state.isEditorFreezed || state.isVersionReleased), + canUndo: state.canUndo && !state.getShouldFreeze(false, isModuleEditor), + canRedo: state.canRedo && !state.getShouldFreeze(false, isModuleEditor), toggleCurrentLayout: state.toggleCurrentLayout, showToggleLayoutBtn: state.showToggleLayoutBtn, showUndoRedoBtn: state.showUndoRedoBtn, diff --git a/frontend/src/AppBuilder/Header/VersionManager/VersionManagerDropdown.jsx b/frontend/src/AppBuilder/Header/VersionManager/VersionManagerDropdown.jsx index 64b7112a7f..ad11c2fe8f 100644 --- a/frontend/src/AppBuilder/Header/VersionManager/VersionManagerDropdown.jsx +++ b/frontend/src/AppBuilder/Header/VersionManager/VersionManagerDropdown.jsx @@ -275,6 +275,9 @@ const VersionManagerDropdown = ({ darkMode = false, ...props }) => { ); }; + // Count only actual versions, not sub-branches + const versionOnlyCount = versions.filter((v) => v.versionType === 'version').length; + const renderPopover = (overlayProps) => ( {
    {/* Search Field - Only show if more than 5 versions */} - {versions.length > 5 && ( + {versionOnlyCount > 5 && (
    diff --git a/frontend/src/AppBuilder/Header/VersionManager/VersionSearchField.jsx b/frontend/src/AppBuilder/Header/VersionManager/VersionSearchField.jsx index 49f21eb82c..12096e58e2 100644 --- a/frontend/src/AppBuilder/Header/VersionManager/VersionSearchField.jsx +++ b/frontend/src/AppBuilder/Header/VersionManager/VersionSearchField.jsx @@ -7,7 +7,6 @@ const VersionSearchField = ({ value, onChange, placeholder = 'Search versions by
    { + const { isModuleEditor } = useModuleContext(); const deleteComponents = useStore((state) => state.deleteComponents, shallow); const setSelectedComponents = useStore((state) => state.setSelectedComponents, shallow); const currentPageComponents = useStore((state) => state?.getCurrentPageComponents(), shallow); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const runQuery = useStore((state) => state.queryPanel.runQuery); const getComponentIdToAutoScroll = useStore((state) => state.getComponentIdToAutoScroll); const setSelectedQuery = useStore((state) => state.queryPanel.setSelectedQuery, shallow); diff --git a/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx b/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx index 15c0f66b5d..b5cf3bc781 100644 --- a/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx +++ b/frontend/src/AppBuilder/QueryManager/Components/QueryManagerBody.jsx @@ -22,9 +22,11 @@ import { EventManager } from '@/AppBuilder/RightSideBar/Inspector/EventManager'; import NotificationBanner from '@/_components/NotificationBanner'; import { withEditionSpecificComponent } from '@/modules/common/helpers/withEditionSpecificComponent'; import CodeHinter from '@/AppBuilder/CodeEditor'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; export const BaseQueryManagerBody = ({ darkMode, activeTab, renderCopilot = () => null }) => { const { t } = useTranslation(); + const { isModuleEditor } = useModuleContext(); const dataSources = useStore((state) => state.dataSources); const globalDataSources = useStore((state) => state.globalDataSources); const sampleDataSource = useStore((state) => state.sampleDataSource); @@ -51,7 +53,7 @@ export const BaseQueryManagerBody = ({ darkMode, activeTab, renderCopilot = () = const ElementToRender = selectedDataSource?.plugin_id ? source : allSources[sourcecomponentName]; const defaultOptions = useRef({}); - const isFreezed = useStore((state) => state.getShouldFreeze()); + const isFreezed = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); useEffect(() => { setDataSourceMeta( diff --git a/frontend/src/AppBuilder/QueryManager/Components/QueryManagerHeader.jsx b/frontend/src/AppBuilder/QueryManager/Components/QueryManagerHeader.jsx index 8d018f9eb4..7cb5cc9db8 100644 --- a/frontend/src/AppBuilder/QueryManager/Components/QueryManagerHeader.jsx +++ b/frontend/src/AppBuilder/QueryManager/Components/QueryManagerHeader.jsx @@ -17,7 +17,7 @@ import posthogHelper from '@/modules/common/helpers/posthogHelper'; import { useAppDataStore } from '@/_stores/appDataStore'; export const QueryManagerHeader = forwardRef(({ darkMode, setActiveTab, activeTab }, ref) => { - const { moduleId } = useModuleContext(); + const { moduleId, isModuleEditor } = useModuleContext(); const updateQuerySuggestions = useStore((state) => state.queryPanel.updateQuerySuggestions); const previewQuery = useStore((state) => state.queryPanel.previewQuery); const renameQuery = useStore((state) => state.dataQuery.renameQuery); @@ -27,7 +27,7 @@ export const QueryManagerHeader = forwardRef(({ darkMode, setActiveTab, activeTa const showCreateQuery = useStore((state) => state.queryPanel.showCreateQuery); const setShowCreateQuery = useStore((state) => state.queryPanel.setShowCreateQuery); const queryName = selectedQuery?.name ?? ''; - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); useEffect(() => { if (selectedQuery?.name) { @@ -154,7 +154,8 @@ export const QueryManagerHeader = forwardRef(({ darkMode, setActiveTab, activeTa }); const NameInput = ({ onInput, value, darkMode, isDiabled, selectedQuery }) => { - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const { isModuleEditor } = useModuleContext(); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const isFocused = useStore((state) => state.queryPanel.nameInputFocused, shallow); const setIsFocused = useStore((state) => state.queryPanel.setNameInputFocused, shallow); const [name, setName] = useState(value); diff --git a/frontend/src/AppBuilder/QueryPanel/QueryCard.jsx b/frontend/src/AppBuilder/QueryPanel/QueryCard.jsx index 36d83ff913..242da1a4ed 100644 --- a/frontend/src/AppBuilder/QueryPanel/QueryCard.jsx +++ b/frontend/src/AppBuilder/QueryPanel/QueryCard.jsx @@ -8,6 +8,7 @@ import DataSourceIcon from '../QueryManager/Components/DataSourceIcon'; import { isQueryRunnable, decodeEntities } from '@/_helpers/utils'; import { canDeleteDataSource, canReadDataSource, canUpdateDataSource } from '@/_helpers'; import useStore from '@/AppBuilder/_stores/store'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; //TODO: Remove this import { Confirm } from '@/AppBuilder/Viewer/Confirm'; // TODO: enable delete query confirmation popup @@ -16,6 +17,7 @@ import SolidIcon from '@/_ui/Icon/SolidIcons'; import { QueryRenameInput } from './QueryRenameInput'; export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => { + const { isModuleEditor } = useModuleContext(); const queryNameEleRef = useRef(null); const isQuerySelected = useStore((state) => state.queryPanel.isQuerySelected(dataQuery.id), shallow); @@ -26,7 +28,7 @@ export const QueryCard = ({ dataQuery, darkMode = false, localDs }) => { const renameQuery = useStore((state) => state.dataQuery.renameQuery); const deleteDataQueries = useStore((state) => state.dataQuery.deleteDataQueries); const setPreviewData = useStore((state) => state.queryPanel.setPreviewData); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const renamingQueryId = useStore((state) => state.queryPanel.renamingQueryId); const deletingQueryId = useStore((state) => state.queryPanel.deletingQueryId); diff --git a/frontend/src/AppBuilder/QueryPanel/QueryDataPane.jsx b/frontend/src/AppBuilder/QueryPanel/QueryDataPane.jsx index 1854779627..09a0b75db6 100644 --- a/frontend/src/AppBuilder/QueryPanel/QueryDataPane.jsx +++ b/frontend/src/AppBuilder/QueryPanel/QueryDataPane.jsx @@ -17,6 +17,7 @@ import DataSourceSelect from '../QueryManager/Components/DataSourceSelect'; import { OverlayTrigger, Popover } from 'react-bootstrap'; import FolderEmpty from '@/_ui/Icon/solidIcons/FolderEmpty'; import useStore from '@/AppBuilder/_stores/store'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; import AppPermissionsModal from '@/modules/Appbuilder/components/AppPermissionsModal'; import { shallow } from 'zustand/shallow'; import { appPermissionService } from '@/_services'; @@ -45,7 +46,8 @@ export const QueryDataPane = ({ darkMode }) => { const showQueryPermissionModal = useStore((state) => state.queryPanel.showQueryPermissionModal); const toggleQueryPermissionModal = useStore((state) => state.queryPanel.toggleQueryPermissionModal); const setQueries = useStore((state) => state.dataQuery.setQueries); - const isFreezed = useStore((state) => state.getShouldFreeze()); + const { isModuleEditor } = useModuleContext(); + const isFreezed = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); useEffect(() => { setQueryPanelSearchTerm(searchTermForFilters); @@ -241,9 +243,10 @@ const EmptyDataSource = () => ( ); const AddDataSourceButton = ({ darkMode, disabled: _disabled }) => { + const { isModuleEditor } = useModuleContext(); const [showMenu, setShowMenu] = useShowPopover(false, '#query-add-ds-popover', '#query-add-ds-popover-btn'); const selectRef = useRef(); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); // const { isVersionReleased, isEditorFreezed } = useStore( // (state) => ({ // isVersionReleased: state.isVersionReleased, diff --git a/frontend/src/AppBuilder/RightSideBar/ComponentManagerTab/ComponentsManagerTab.jsx b/frontend/src/AppBuilder/RightSideBar/ComponentManagerTab/ComponentsManagerTab.jsx index 12207aa80c..ddeb3e035e 100644 --- a/frontend/src/AppBuilder/RightSideBar/ComponentManagerTab/ComponentsManagerTab.jsx +++ b/frontend/src/AppBuilder/RightSideBar/ComponentManagerTab/ComponentsManagerTab.jsx @@ -66,7 +66,7 @@ export const ComponentsManagerTab = ({ darkMode, isModuleEditor }) => { const [searchQuery, setSearchQuery] = useState(''); const [moduleError, setModuleError] = useState(false); const [activeTab, setActiveTab] = useState('components'); - const _shouldFreeze = useStore((state) => state.getShouldFreeze()); + const _shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const isAutoMobileLayout = useStore((state) => state.currentLayout === 'mobile' && state.getIsAutoMobileLayout()); const shouldFreeze = _shouldFreeze || isAutoMobileLayout; const edition = fetchEdition(); diff --git a/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx b/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx index 822175ec04..129bdfe1ca 100644 --- a/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx +++ b/frontend/src/AppBuilder/RightSideBar/Inspector/Inspector.jsx @@ -55,6 +55,7 @@ import { KeyValuePair } from './Components/KeyValuePair/KeyValuePair.jsx'; import { Navigation } from './Components/Navigation'; import { v4 as uuidv4 } from 'uuid'; import { Button } from '@/components/ui/Button/Button'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; import '../ComponentManagerTab/styles.scss'; const INSPECTOR_HEADER_OPTIONS = [ @@ -154,10 +155,11 @@ export const Inspector = ({ selectedComponentId, handleRightSidebarToggle, }) => { + const { isModuleEditor } = useModuleContext(); const allComponents = useStore((state) => state.getCurrentPageComponents()); const setComponentProperty = useStore((state) => state.setComponentProperty, shallow); const setComponentName = useStore((state) => state.setComponentName, shallow); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const clearSelectedComponents = useStore((state) => state.clearSelectedComponents, shallow); const isVersionReleased = useStore((state) => state.isVersionReleased); const setWidgetDeleteConfirmation = useStore((state) => state.setWidgetDeleteConfirmation); @@ -445,7 +447,7 @@ export const Inspector = ({ setTimeout(() => setInputFocus(), 0); } if (value === 'delete') { - setWidgetDeleteConfirmation(true); + setWidgetDeleteConfirmation(true, isModuleEditor); } if (value === 'permission') { if (!hasAppPermissionComponent) return; diff --git a/frontend/src/AppBuilder/RightSideBar/RightSideBar.jsx b/frontend/src/AppBuilder/RightSideBar/RightSideBar.jsx index 631a49844e..060f6f8df3 100644 --- a/frontend/src/AppBuilder/RightSideBar/RightSideBar.jsx +++ b/frontend/src/AppBuilder/RightSideBar/RightSideBar.jsx @@ -9,7 +9,7 @@ import { RIGHT_SIDE_BAR_TAB } from './rightSidebarConstants'; export const RightSideBar = ({ darkMode }) => { const { isModuleEditor } = useModuleContext(); - const shouldFreeze = useStore((state) => state.getShouldFreeze()); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const activeTab = useStore((state) => state.activeRightSideBarTab); const isRightSidebarOpen = useStore((state) => state.isRightSidebarOpen); diff --git a/frontend/src/AppBuilder/_stores/slices/appVersionSlice.js b/frontend/src/AppBuilder/_stores/slices/appVersionSlice.js index 784f3c3a9a..f42ca90ba8 100644 --- a/frontend/src/AppBuilder/_stores/slices/appVersionSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/appVersionSlice.js @@ -59,7 +59,8 @@ export const createAppVersionSlice = (set, get) => ({ setAppVersionPromoted: (value) => set(() => ({ isAppVersionPromoted: value }), false, 'setAppVersionPromoted'), - getShouldFreeze: (skipIsEditorFreezedCheck = false) => { + getShouldFreeze: (skipIsEditorFreezedCheck = false, isModuleEditor = false) => { + if (isModuleEditor) return false; return ( get().isVersionReleased || (!skipIsEditorFreezedCheck && get().isEditorFreezed) || diff --git a/frontend/src/AppBuilder/_stores/slices/componentsSlice.js b/frontend/src/AppBuilder/_stores/slices/componentsSlice.js index 8a6ee72c9e..30281d3b40 100644 --- a/frontend/src/AppBuilder/_stores/slices/componentsSlice.js +++ b/frontend/src/AppBuilder/_stores/slices/componentsSlice.js @@ -43,6 +43,7 @@ const initialState = { }, selectedComponents: [], showWidgetDeleteConfirmation: false, + deleteTargetIsModuleEditor: false, focusedParentId: null, modalsOpenOnCanvas: [], showComponentPermissionModal: false, @@ -1179,7 +1180,7 @@ export const createComponentsSlice = (set, get) => ({ deleteComponents: ( selected, moduleId = 'canvas', - { skipUndoRedo = false, saveAfterAction = true, isCut = false, skipFormUpdate = false } = {} + { skipUndoRedo = false, saveAfterAction = true, isCut = false, skipFormUpdate = false, isModuleEditor = false } = {} ) => { const { saveComponentChanges, @@ -1198,7 +1199,7 @@ export const createComponentsSlice = (set, get) => ({ getCurrentPageIndex, } = get(); const isAppBeingEditedByAI = get().ai?.isLoading ?? false; - const shouldFreeze = getShouldFreeze(isAppBeingEditedByAI); + const shouldFreeze = getShouldFreeze(isAppBeingEditedByAI, isModuleEditor); const currentPageId = getCurrentPageId(moduleId); const appEvents = get().eventsSlice.getModuleEvents(moduleId); const componentNames = []; @@ -1991,9 +1992,10 @@ export const createComponentsSlice = (set, get) => ({ await savePageChanges(app.appId, currentVersionId, currentPageId, { autoComputeLayout: false }); }, - setWidgetDeleteConfirmation: (value) => { + setWidgetDeleteConfirmation: (value, isModuleEditor = false) => { set((state) => { state.showWidgetDeleteConfirmation = value; + if (value) state.deleteTargetIsModuleEditor = isModuleEditor; }); }, diff --git a/frontend/src/HomePage/HomePage.jsx b/frontend/src/HomePage/HomePage.jsx index d57a9f699a..a7777448be 100644 --- a/frontend/src/HomePage/HomePage.jsx +++ b/frontend/src/HomePage/HomePage.jsx @@ -1296,31 +1296,19 @@ class HomePageComponent extends React.Component { const { latestCommitData, tags } = this.state; const options = []; - // Add latest commit as first option if (latestCommitData?.latestCommit?.[0]) { - const gitVersionName = latestCommitData?.gitVersionName; - // Check if the latest commit's version exists in tags (to determine if it's a draft) - const tagVersionNames = (tags || []).map((tag) => { - const [, version] = tag.name.split('/'); - return version; - }); - const isInTags = tagVersionNames.includes(gitVersionName); - options.push({ - label: isInTags ? gitVersionName : 'Draft version', + label: 'Latest commit', value: 'latest', isLatest: true, - isDraft: !isInTags, + isDraft: true, sha: latestCommitData?.latestCommit?.[0]?.commitId, }); } // Add tags - filter out tags that have the same SHA as the latest commit if (tags && tags.length > 0) { - const latestCommitSha = latestCommitData?.latestCommit?.[0]?.commitId; - const filteredTags = latestCommitSha ? tags.filter((tag) => tag.commit?.sha !== latestCommitSha) : tags; - - filteredTags.forEach((tag) => { + tags.forEach((tag) => { const [, version] = tag.name.split('/'); options.push({ label: version, @@ -1334,32 +1322,32 @@ class HomePageComponent extends React.Component { return options; }; + getSelectedVersionCommitInfo = () => { + const { selectedVersionOption, latestCommitData, tags } = this.state; + const isLatest = !selectedVersionOption || selectedVersionOption === 'latest'; + + if (isLatest) { + return { + message: latestCommitData?.latestCommit[0]?.message, + author: latestCommitData?.latestCommit[0]?.author, + date: latestCommitData?.latestCommit[0]?.date, + versionName: latestCommitData?.gitVersionName, + }; + } + + const selectedTag = tags?.find((t) => t.name === selectedVersionOption); + return { + message: selectedTag?.message, + author: selectedTag?.tagger?.name, + date: selectedTag?.tagger?.date, + versionName: selectedVersionOption?.split('/')?.pop(), + }; + }; + renderVersionOption = (option) => { return (
    {option.label} -
    - {option.isLatest && ( - - Latest - - )} -
    ); }; @@ -1784,14 +1772,16 @@ class HomePageComponent extends React.Component { <>
    - {latestCommitData?.latestCommit[0]?.message || 'No commits yet'} + {this.getSelectedVersionCommitInfo().message || 'No commits yet'} +
    +
    + {this.getSelectedVersionCommitInfo().gitVersionName}
    -
    {latestCommitData?.gitVersionName}
    - {latestCommitData?.latestCommit[0]?.author && latestCommitData?.latestCommit[0]?.date && ( + {this.getSelectedVersionCommitInfo().author && this.getSelectedVersionCommitInfo().date && (
    - {`Done by ${latestCommitData?.latestCommit[0]?.author} at ${moment( - new Date(latestCommitData?.latestCommit[0]?.date) + {`Done by ${this.getSelectedVersionCommitInfo().author} at ${moment( + new Date(this.getSelectedVersionCommitInfo().date) ).format('DD MMM YYYY, h:mm a')}`}
    )} diff --git a/frontend/src/_components/AppModal.jsx b/frontend/src/_components/AppModal.jsx index f0ab1ab0ca..5c1f044316 100644 --- a/frontend/src/_components/AppModal.jsx +++ b/frontend/src/_components/AppModal.jsx @@ -220,7 +220,8 @@ export function AppModal({ {`${appTypeName} name must be unique and max 50 characters`} )} - {orgGit?.is_enabled && + {/* Disabling autoCommit */} + {/* {orgGit?.is_enabled && modalType !== 'create' && appType != APP_TYPE.WORKFLOW && appType != APP_TYPE.MODULE && ( @@ -244,7 +245,7 @@ export function AppModal({
    - )} + )} */}
    {dependentPlugins && dependentPlugins.length >= 1 && (
    e.stopPropagation()}> diff --git a/frontend/src/_components/SortableList/SortableList.jsx b/frontend/src/_components/SortableList/SortableList.jsx index 3a6631a5a9..91f0aa2805 100644 --- a/frontend/src/_components/SortableList/SortableList.jsx +++ b/frontend/src/_components/SortableList/SortableList.jsx @@ -3,8 +3,10 @@ import { DndContext, PointerSensor, useSensor, useSensors } from '@dnd-kit/core' import { SortableContext, arrayMove } from '@dnd-kit/sortable'; import { SortableItem } from './components'; import useStore from '@/AppBuilder/_stores/store'; +import { useModuleContext } from '@/AppBuilder/_contexts/ModuleContext'; export function SortableList({ items, onChange, renderItem }) { + const { isModuleEditor } = useModuleContext(); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { @@ -17,7 +19,7 @@ export function SortableList({ items, onChange, renderItem }) { // }) ); - const shouldFreeze = useStore((state) => state.isVersionReleased || state.isEditorFreezed); + const shouldFreeze = useStore((state) => state.getShouldFreeze(false, isModuleEditor)); const enableReleasedVersionPopupState = useStore((state) => state.enableReleasedVersionPopupState); return ( diff --git a/frontend/src/_services/git_sync.service.js b/frontend/src/_services/git_sync.service.js index 9fe23b2852..d518f3a028 100644 --- a/frontend/src/_services/git_sync.service.js +++ b/frontend/src/_services/git_sync.service.js @@ -28,6 +28,7 @@ export const gitSyncService = { updateGitConfigs, getGitConfigs, createGitTag, + checkTagExists, }; function create(organizationId, gitUrl, gitType) { @@ -358,4 +359,23 @@ function createGitTag(appId, versionId, versionDescription) { }; return fetch(`${config.apiUrl}/app-git/${appId}/versions/${versionId}/tag`, requestOptions).then(handleResponse); } + +/** + * Check if a git tag already exists for the given app and version name. + * This should be called BEFORE saving the version locally to ensure + * local save and tag creation stay in sync. + * @param {string} appId - Application ID + * @param {string} versionName - Version name to check + * @returns {Promise<{ exists: boolean, tag_name: string }>} Promise resolving to tag existence check + */ +function checkTagExists(appId, versionName) { + const requestOptions = { + method: 'GET', + headers: authHeader(), + credentials: 'include', + }; + return fetch(`${config.apiUrl}/app-git/${appId}/check-tag/${encodeURIComponent(versionName)}`, requestOptions).then( + handleResponse + ); +} // Remove all app-git api's to separate service from here. diff --git a/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx b/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx index e7441055e6..9be2f74922 100644 --- a/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx +++ b/frontend/src/modules/common/components/BasePromoteReleaseButton/components/PromoteVersionButton/components/PromoteConfirmationModal/PromoteConfirmationModal.jsx @@ -54,40 +54,47 @@ const PromoteConfirmationModal = React.memo(({ data, onClose, editingVersion }) versionIdToPromote, async (response) => { toast.success(`${versionToPromote.name} has been promoted to ${data.target.name}!`); - if ( - data?.current?.name == 'development' && - (creationMode !== 'GIT' || (creationMode === 'GIT' && allowAppEdit)) - ) { - try { - const gitData = await gitSyncService.getAppConfig(current_organization_id, versionToPromote?.id); - const appGit = gitData?.app_git; - if (appGit && appGit?.org_git?.auto_commit) { - const body = { - gitAppName: appGit?.git_app_name, - versionId: versionToPromote?.id, - lastCommitMessage: ` ${versionToPromote.name} Version of app ${appGit?.git_app_name} promoted from development to staging`, - gitVersionName: versionToPromote?.name, - allowMasterPush: true, - }; - await gitSyncService.gitPush(body, appGit?.id, versionToPromote?.id); - toast.success('Changes committed successfully'); - } - } catch (err) { - const status = err?.statusCode; - const error = err?.error; - if ( - !(status === 404 && error === 'Git Configuration not found') && - !(error === 'No Git Provider is enabled for the workspace') - ) { - toast.error(error, { - style: { - width: 'auto', - maxWidth: '339px', - }, - }); - } - } + setPromotingEnvironment(false); + onClose(); + + { + /* Can clean when autoCommit is removed completely */ } + // if ( + // data?.current?.name == 'development' && + // (creationMode !== 'GIT' || (creationMode === 'GIT' && allowAppEdit)) + // ) { + // try { + // const gitData = await gitSyncService.getAppConfig(current_organization_id, versionToPromote?.id); + // const appGit = gitData?.app_git; + // if (appGit && appGit?.org_git?.auto_commit) { + // const body = { + // gitAppName: appGit?.git_app_name, + // versionId: versionToPromote?.id, + // lastCommitMessage: ` ${versionToPromote.name} Version of app ${appGit?.git_app_name} promoted from development to staging`, + // gitVersionName: versionToPromote?.name, + // allowMasterPush: true, + // }; + // await gitSyncService.gitPush(body, appGit?.id, versionToPromote?.id); + // toast.success('Changes committed successfully'); + // } + // } catch (err) { + // const status = err?.statusCode; + // const error = err?.error; + // if ( + // !(status === 404 && error === 'Git Configuration not found') && + // !(error === 'No Git Provider is enabled for the workspace') + // ) { + // toast.error(error, { + // style: { + // width: 'auto', + // maxWidth: '339px', + // }, + // }); + // } + // } + // } + // setSelectedEnvironment(response); // set env id here-----> state update // appEnvironmentChanged(response, true); diff --git a/server/ee b/server/ee index db269e881c..9be6010912 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit db269e881cf9ec4595344cfffc54d0ac5c35dd2d +Subproject commit 9be601091283caaf438a273fffcc4d3e7e7ebad6 diff --git a/server/src/modules/apps/dto/index.ts b/server/src/modules/apps/dto/index.ts index 779736e91c..0df0d624e0 100644 --- a/server/src/modules/apps/dto/index.ts +++ b/server/src/modules/apps/dto/index.ts @@ -34,6 +34,10 @@ export class AppUpdateDto { @IsOptional() current_version_id: string; + @IsString() + @IsOptional() + editingVersionId: string; + @IsBoolean() @IsOptional() is_public: boolean; diff --git a/server/src/modules/apps/service.ts b/server/src/modules/apps/service.ts index f81b2c1562..052edd1c40 100644 --- a/server/src/modules/apps/service.ts +++ b/server/src/modules/apps/service.ts @@ -223,30 +223,54 @@ export class AppsService implements IAppsService { async update(app: App, appUpdateDto: AppUpdateDto, user: User) { const { id: userId, organizationId } = user; - const { name } = appUpdateDto; + const { name, editingVersionId } = appUpdateDto; + const orgGit = await this.organizationGitRepository.findOrgGitByOrganizationId(app.organizationId); + const isGitSyncEnabled = Boolean( + orgGit?.gitSsh?.isEnabled || orgGit?.gitHttps?.isEnabled || orgGit?.gitLab?.isEnabled + ); // Check if name is being changed - require draft version to exist if (name && name !== app.name) { + // Block rename if git sync is enabled and app has been pushed + if (isGitSyncEnabled) { + const appGitSync = await this.appGitRepository.findAppGitByAppId(app.id); + if (appGitSync) { + // Check if on default branch (not a feature branch) + const editingVersion = editingVersionId + ? await this.versionRepository.findById(editingVersionId, app.id) + : app.editingVersion; + + const isOnDefaultBranch = editingVersion?.versionType !== 'branch'; + + if (isOnDefaultBranch) { + throw new BadRequestException( + "Renaming isn't allowed on master. Switch branch in app builder to update name." + ); + } + } + } + const draftVersion = await this.versionRepository.findOne({ where: { appId: app.id, - versionType: AppVersionType.VERSION, + // versionType: AppVersionType.VERSION, status: AppVersionStatus.DRAFT, }, }); - if (!draftVersion) { + if (!draftVersion && isGitSyncEnabled) { throw new BadRequestException('Cannot rename app. Please create a draft version first to rename the app.'); } } const result = await this.appsUtilService.update(app, appUpdateDto, organizationId); - if (name && app.creationMode != 'GIT' && name != app.name) { + if (name && name != app.name) { const appRenameDto = { user: user, organizationId: organizationId, app: app, appUpdateDto: appUpdateDto, + editingVersionId: editingVersionId, }; await this.eventEmitter.emit('app-rename-commit', appRenameDto); } diff --git a/server/src/modules/folder-apps/service.ts b/server/src/modules/folder-apps/service.ts index 214fca80a9..9a060ea398 100644 --- a/server/src/modules/folder-apps/service.ts +++ b/server/src/modules/folder-apps/service.ts @@ -1,6 +1,6 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { FolderApp } from '../../entities/folder_app.entity'; -import { AppGitSync } from '../../entities/app_git_sync.entity' +import { AppGitSync } from '../../entities/app_git_sync.entity'; import { dbTransactionWrap } from '@helpers/database.helper'; import { EntityManager } from 'typeorm'; import { decamelizeKeys } from 'humps'; @@ -26,15 +26,10 @@ export class FolderAppsService implements IFolderAppsService { async remove(folderId: string, appId: string): Promise { return dbTransactionWrap(async (manager: EntityManager) => { - const gitSyncedApp = await manager.findOne(AppGitSync, { + const gitSyncedApp = await manager.findOne(AppGitSync, { where: { appId }, - select: ['id'], + select: ['id'], }); - if (gitSyncedApp) { - throw new BadRequestException( - "Apps connected to git can't be removed from folders." - ); - } // TODO: folder under user.organizationId return await manager.delete(FolderApp, { folderId, appId }); }); diff --git a/server/src/modules/folder-apps/util.service.ts b/server/src/modules/folder-apps/util.service.ts index a11c6721c9..a9ea34ecaa 100644 --- a/server/src/modules/folder-apps/util.service.ts +++ b/server/src/modules/folder-apps/util.service.ts @@ -1,6 +1,6 @@ import { Folder } from '@entities/folder.entity'; import { User } from '@entities/user.entity'; -import { BadRequestException, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { EntityManager, SelectQueryBuilder } from 'typeorm'; import { IFolderAppsUtilService } from './interfaces/IUtilService'; import { AppBase } from '@entities/app_base.entity'; @@ -10,7 +10,6 @@ import { MODULES } from '@modules/app/constants/modules'; import { UserAppsPermissions, UserWorkflowPermissions } from '@modules/ability/types'; import { AbilityService } from '@modules/ability/interfaces/IService'; import { APP_TYPES } from '@modules/apps/constants'; -import { AppGitSync } from '../../entities/app_git_sync.entity'; @Injectable() export class FolderAppsUtilService implements IFolderAppsUtilService { @@ -179,22 +178,9 @@ export class FolderAppsUtilService implements IFolderAppsUtilService { where: { appId }, }); + // If app is already in a folder, remove it first (apps can only be in one folder) if (existingFolderApp) { - throw new BadRequestException( - 'Apps can only be in one folder at a time. To add this app here, remove it from its current folder first.' - ); - } - - // Skip this check when called from app import flow - if (!skipGitSyncCheck) { - const gitSyncedApp = await manager.findOne(AppGitSync, { - where: { appId }, - select: ['id'], - }); - - if (gitSyncedApp) { - throw new BadRequestException('Git-synced app cannot be moved to the folder'); - } + await manager.delete(FolderApp, { id: existingFolderApp.id }); } // TODO: check if folder under user.organizationId and user has edit permission on app diff --git a/server/src/modules/folders/service.ts b/server/src/modules/folders/service.ts index 842e5bb579..0e5faf459a 100644 --- a/server/src/modules/folders/service.ts +++ b/server/src/modules/folders/service.ts @@ -1,7 +1,7 @@ -import { Injectable, BadRequestException } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; import { Folder } from '@entities/folder.entity'; import { FolderApp } from '../../entities/folder_app.entity'; -import { AppGitSync } from '../../entities/app_git_sync.entity' +import { AppGitSync } from '../../entities/app_git_sync.entity'; import { decamelizeKeys } from 'humps'; import { CreateFolderDto, UpdateFolderDto } from '@modules/folders/dto'; import { IFoldersService } from './interfaces/IService'; @@ -21,20 +21,6 @@ export class FoldersService implements IFoldersService { const folderId = id; const folderName = updateFolderDto.name; return dbTransactionWrap(async (manager: EntityManager) => { - - const gitSyncedAppInFolder = await manager - .createQueryBuilder(AppGitSync, 'ags') - .innerJoin(FolderApp, 'fa', 'fa.app_id = ags.app_id') - .where('fa.folder_id = :folderId', { folderId }) - .select('ags.id') - .getOne(); - - if (gitSyncedAppInFolder) { - throw new BadRequestException( - 'Folders with git-synced apps cannot be edited' - ); - } - const folder = await catchDbException(async () => { return manager.update(Folder, { id: folderId }, { name: folderName }); }, [ @@ -52,22 +38,18 @@ export class FoldersService implements IFoldersService { where: { id, organizationId: user.organizationId }, }); - const gitSyncedAppInFolder = await manager - .createQueryBuilder(AppGitSync, 'ags') - .innerJoin( - FolderApp, - 'fa', - 'fa.app_id = ags.app_id' - ) - .where('fa.folder_id = :folderId', { folderId: folder.id }) - .select('ags.id') - .getOne(); + const gitSyncedAppInFolder = await manager + .createQueryBuilder(AppGitSync, 'ags') + .innerJoin(FolderApp, 'fa', 'fa.app_id = ags.app_id') + .where('fa.folder_id = :folderId', { folderId: folder.id }) + .select('ags.id') + .getOne(); - if (gitSyncedAppInFolder) { - throw new BadRequestException( - "Folders with apps synced to git can't be deleted. Delete the git apps and try again." - ); - } + if (gitSyncedAppInFolder) { + throw new BadRequestException( + "Folders with apps synced to git can't be deleted. Delete the git apps and try again." + ); + } return manager.delete(Folder, { id: folder.id, organizationId: user.organizationId }); }); diff --git a/server/src/modules/versions/util.service.ts b/server/src/modules/versions/util.service.ts index b88bc360f5..90eb8233e7 100644 --- a/server/src/modules/versions/util.service.ts +++ b/server/src/modules/versions/util.service.ts @@ -264,7 +264,8 @@ export class VersionUtilService implements IVersionUtilService { } async deleteVersionGit(app: App, version: AppVersion, manager?: EntityManager): Promise { return await dbTransactionWrap(async (manager: EntityManager) => { - if (app.currentVersionId && app.currentVersionId === app.appVersions[0].id) { + // Check if the version being deleted is the currently released version + if (app.currentVersionId && app.currentVersionId === version.id) { throw new BadRequestException('You cannot delete a released version'); } await this.versionRepository.deleteById(version.id, manager); From 3d1fd48a19b6ea8195da7d78626bec1c8d80647f Mon Sep 17 00:00:00 2001 From: gsmithun4 Date: Thu, 5 Mar 2026 11:41:52 +0530 Subject: [PATCH 17/22] Implement feature X to enhance user experience and fix bug Y in module Z --- plugins/package-lock.json | 6923 ++++++++++++++----------------------- 1 file changed, 2615 insertions(+), 4308 deletions(-) diff --git a/plugins/package-lock.json b/plugins/package-lock.json index 9ca9d30267..7180d39712 100644 --- a/plugins/package-lock.json +++ b/plugins/package-lock.json @@ -140,44 +140,6 @@ "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@aws-crypto/sha256-browser": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", @@ -193,44 +155,6 @@ "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@aws-crypto/sha256-js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", @@ -265,444 +189,467 @@ "tslib": "^2.6.2" } }, - "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@aws-sdk/client-athena": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-athena/-/client-athena-3.975.0.tgz", - "integrity": "sha512-Z/YNQ1kvZKVxOU+0oT5TLyvNlV+5vdxLo6Jw5x+lYMnWzLN2/xNTxJtug/RBg+xJ3DyC7yZrmoYbkATBpW8pFQ==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-athena/-/client-athena-3.1002.0.tgz", + "integrity": "sha512-8YPsqrPOIFVZ5vYLvB06YmfZTl3l6YLUiHAOG+YKGy96vWOl9DGD7Dr2osDLsgXQdMhz2fVc7n7/uFK5a5mAsg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-node": "^3.972.16", + "@aws-sdk/middleware-host-header": "^3.972.6", + "@aws-sdk/middleware-logger": "^3.972.6", + "@aws-sdk/middleware-recursion-detection": "^3.972.6", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/region-config-resolver": "^3.972.6", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@aws-sdk/util-user-agent-browser": "^3.972.6", + "@aws-sdk/util-user-agent-node": "^3.973.2", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/hash-node": "^4.2.10", + "@smithy/invalid-dependency": "^4.2.10", + "@smithy/middleware-content-length": "^4.2.10", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/middleware-retry": "^4.4.38", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.37", + "@smithy/util-defaults-mode-node": "^4.2.40", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-athena/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.975.0.tgz", - "integrity": "sha512-HjPnxHB74FaeLSce+/B2n3H7FJ23lC5D4M2FnHhHdiuvGa8etFrsF12mxC8i635huARHJkqLLbLF2U39xX6AJA==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.1002.0.tgz", + "integrity": "sha512-tWopjShTQyg0/KIdOiUHWQAb7Ef26X7voDIRinxL9oql90qRMSEbSw050OzXM0pwpF0TapyMsed4V8V/Z5k+Cg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-node": "^3.972.16", + "@aws-sdk/middleware-host-header": "^3.972.6", + "@aws-sdk/middleware-logger": "^3.972.6", + "@aws-sdk/middleware-recursion-detection": "^3.972.6", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/region-config-resolver": "^3.972.6", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@aws-sdk/util-user-agent-browser": "^3.972.6", + "@aws-sdk/util-user-agent-node": "^3.973.2", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/hash-node": "^4.2.10", + "@smithy/invalid-dependency": "^4.2.10", + "@smithy/middleware-content-length": "^4.2.10", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/middleware-retry": "^4.4.38", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.37", + "@smithy/util-defaults-mode-node": "^4.2.40", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-cognito-identity/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-dynamodb": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.975.0.tgz", - "integrity": "sha512-Cq6oGb8XswG56YhF2kHmxuyEnMNayDpL8xDxp9E4zIUqDeSLCKE6lCaqZzo5zpngzqLluFsJbCC9jrMzZejMAA==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1002.0.tgz", + "integrity": "sha512-qwIQ7fXHJh/MLkabEEnYgY7NfOL6lbZeI9P29HzSo8jMp3c+uxHkZF/xlyLcArky/YEn5FFhiUF2RUzbsUAUjg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/dynamodb-codec": "^3.972.2", - "@aws-sdk/middleware-endpoint-discovery": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", - "@smithy/util-waiter": "^4.2.8", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-node": "^3.972.16", + "@aws-sdk/dynamodb-codec": "^3.972.18", + "@aws-sdk/middleware-endpoint-discovery": "^3.972.6", + "@aws-sdk/middleware-host-header": "^3.972.6", + "@aws-sdk/middleware-logger": "^3.972.6", + "@aws-sdk/middleware-recursion-detection": "^3.972.6", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/region-config-resolver": "^3.972.6", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@aws-sdk/util-user-agent-browser": "^3.972.6", + "@aws-sdk/util-user-agent-node": "^3.973.2", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/hash-node": "^4.2.10", + "@smithy/invalid-dependency": "^4.2.10", + "@smithy/middleware-content-length": "^4.2.10", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/middleware-retry": "^4.4.38", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.37", + "@smithy/util-defaults-mode-node": "^4.2.40", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/util-utf8": "^4.2.1", + "@smithy/util-waiter": "^4.2.10", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-dynamodb/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-s3": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.975.0.tgz", - "integrity": "sha512-aF1M/iMD29BPcpxjqoym0YFa4WR9Xie1/IhVumwOGH6TB45DaqYO7vLwantDBcYNRn/cZH6DFHksO7RmwTFBhw==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1002.0.tgz", + "integrity": "sha512-tc+vZgvjcm+1Ot+YhQjXZxVELKGGGO3D5cuR4p5xaeitXYX2+RRiz4/WdSak9slumIClnlXsdqhJ0OHognUT+w==", "license": "Apache-2.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.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/middleware-bucket-endpoint": "^3.972.1", - "@aws-sdk/middleware-expect-continue": "^3.972.1", - "@aws-sdk/middleware-flexible-checksums": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-location-constraint": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-sdk-s3": "^3.972.2", - "@aws-sdk/middleware-ssec": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/signature-v4-multi-region": "3.972.0", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/eventstream-serde-browser": "^4.2.8", - "@smithy/eventstream-serde-config-resolver": "^4.3.8", - "@smithy/eventstream-serde-node": "^4.2.8", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-blob-browser": "^4.2.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/hash-stream-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/md5-js": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-stream": "^4.5.10", - "@smithy/util-utf8": "^4.2.0", - "@smithy/util-waiter": "^4.2.8", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-node": "^3.972.16", + "@aws-sdk/middleware-bucket-endpoint": "^3.972.6", + "@aws-sdk/middleware-expect-continue": "^3.972.6", + "@aws-sdk/middleware-flexible-checksums": "^3.973.3", + "@aws-sdk/middleware-host-header": "^3.972.6", + "@aws-sdk/middleware-location-constraint": "^3.972.6", + "@aws-sdk/middleware-logger": "^3.972.6", + "@aws-sdk/middleware-recursion-detection": "^3.972.6", + "@aws-sdk/middleware-sdk-s3": "^3.972.17", + "@aws-sdk/middleware-ssec": "^3.972.6", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/region-config-resolver": "^3.972.6", + "@aws-sdk/signature-v4-multi-region": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@aws-sdk/util-user-agent-browser": "^3.972.6", + "@aws-sdk/util-user-agent-node": "^3.973.2", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/eventstream-serde-browser": "^4.2.10", + "@smithy/eventstream-serde-config-resolver": "^4.3.10", + "@smithy/eventstream-serde-node": "^4.2.10", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/hash-blob-browser": "^4.2.11", + "@smithy/hash-node": "^4.2.10", + "@smithy/hash-stream-node": "^4.2.10", + "@smithy/invalid-dependency": "^4.2.10", + "@smithy/md5-js": "^4.2.10", + "@smithy/middleware-content-length": "^4.2.10", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/middleware-retry": "^4.4.38", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.37", + "@smithy/util-defaults-mode-node": "^4.2.40", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/util-stream": "^4.5.16", + "@smithy/util-utf8": "^4.2.1", + "@smithy/util-waiter": "^4.2.10", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-s3/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-sesv2": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sesv2/-/client-sesv2-3.975.0.tgz", - "integrity": "sha512-4R+hR6N2LbvTIf6Y2e9b9PQlVkAD5WmSRMAGslul5L/jCE0LzOYC+4RQ7u5EOv0mERozcYleLPK2Zc0jTn4gTg==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sesv2/-/client-sesv2-3.1002.0.tgz", + "integrity": "sha512-V1TvXcwv0iEFiQQxdPzFrbEUFZkRwGdbdxADv1q1xcPGyQ9uy5EZu5sDYgcAFuQHjgcckk+AnS7qBMsiyuwrfQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/signature-v4-multi-region": "3.972.0", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-node": "^3.972.16", + "@aws-sdk/middleware-host-header": "^3.972.6", + "@aws-sdk/middleware-logger": "^3.972.6", + "@aws-sdk/middleware-recursion-detection": "^3.972.6", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/region-config-resolver": "^3.972.6", + "@aws-sdk/signature-v4-multi-region": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@aws-sdk/util-user-agent-browser": "^3.972.6", + "@aws-sdk/util-user-agent-node": "^3.973.2", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/hash-node": "^4.2.10", + "@smithy/invalid-dependency": "^4.2.10", + "@smithy/middleware-content-length": "^4.2.10", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/middleware-retry": "^4.4.38", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.37", + "@smithy/util-defaults-mode-node": "^4.2.40", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.975.0.tgz", - "integrity": "sha512-HpgJuleH7P6uILxzJKQOmlHdwaCY+xYC6VgRDzlwVEqU/HXjo4m2gOAyjUbpXlBOCWfGgMUzfBlNJ9z3MboqEQ==", + "node_modules/@aws-sdk/client-sesv2/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=20.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.975.0.tgz", - "integrity": "sha512-09uQiFTXZb0M2Vms2TtpPXZHAuySAEq66I7q4G2saJBNZyXFXmtTqtl3LGR+Y967RVl9UNOwvSR6hYiCHjDrYQ==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.1002.0.tgz", + "integrity": "sha512-KoWtMWq0o95k/8hMl2gzrxFehP3FxIH3j7k8gsOWW9qP/OyfU/Dp7KyopjuXSPQSE0HqjFibefExEdFbMr15Cw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-node": "^3.972.16", + "@aws-sdk/middleware-host-header": "^3.972.6", + "@aws-sdk/middleware-logger": "^3.972.6", + "@aws-sdk/middleware-recursion-detection": "^3.972.6", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/region-config-resolver": "^3.972.6", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@aws-sdk/util-user-agent-browser": "^3.972.6", + "@aws-sdk/util-user-agent-node": "^3.973.2", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/hash-node": "^4.2.10", + "@smithy/invalid-dependency": "^4.2.10", + "@smithy/middleware-content-length": "^4.2.10", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/middleware-retry": "^4.4.38", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.37", + "@smithy/util-defaults-mode-node": "^4.2.40", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-sts/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/core": { - "version": "3.973.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.2.tgz", - "integrity": "sha512-XwOjX86CNtmhO/Tx2vmNt1tT1yda045LXVm453w9crrkl7oyDEWV3ASg2xNi6hCPWbx1BXtLKJduQiGZnmHXrg==", + "version": "3.973.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.17.tgz", + "integrity": "sha512-VtgGP0TjbCeyp6DQpiBqJKbemTSIaN2bZc3UbeTDCani3lBCyxn75ouJYD6koSSp0bh7rKLEbUpiFsNCI7tr0w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/xml-builder": "^3.972.2", - "@smithy/core": "^3.21.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/xml-builder": "^3.972.9", + "@smithy/core": "^3.23.7", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/property-provider": "^4.2.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/signature-v4": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/crc64-nvme": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.0.tgz", - "integrity": "sha512-ThlLhTqX68jvoIVv+pryOdb5coP1cX1/MaTbB9xkGDCbWbsqQcLqzPxuSoW1DCnAAIacmXCWpzUNOB9pv+xXQw==", + "node_modules/@aws-sdk/core/node_modules/@smithy/signature-v4": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.11.tgz", + "integrity": "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/core/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/crc64-nvme": { + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.3.tgz", + "integrity": "sha512-UExeK+EFiq5LAcbHm96CQLSia+5pvpUVSAsVApscBzayb7/6dJBJKwV4/onsk4VbWSmqxDMcfuTD+pC4RxgZHg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -710,15 +657,15 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.2.tgz", - "integrity": "sha512-+tX6yfkw3+CpXLl/IoFqGSatbtZMzBcXr9HXPjbaYqCIu80SzfwjgQl8ddFeloTrA1xVPX2+eWOU04nVuACW7w==", + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.972.8.tgz", + "integrity": "sha512-ATo3JAoPiGFM+m6cW42ntpOAgHY817NnRZOoe3jNRsMDibHKfjkCPFz1azgIjKRwFp3ioY7QNkOZNp4t8XNI2Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.975.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/nested-clients": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@smithy/property-provider": "^4.2.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -726,15 +673,15 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.2.tgz", - "integrity": "sha512-wzH1EdrZsytG1xN9UHaK12J9+kfrnd2+c8y0LVoS4O4laEjPoie1qVK3k8/rZe7KOtvULzyMnO3FT4Krr9Z0Dg==", + "version": "3.972.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.15.tgz", + "integrity": "sha512-RhHQG1lhkWHL4tK1C/KDjaOeis+9U0tAMnWDiwiSVQZMC7CsST9Xin+sK89XywJ5g/tyABtb7TvFePJ4Te5XSQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/types": "^3.973.4", + "@smithy/property-provider": "^4.2.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -742,20 +689,20 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.3.tgz", - "integrity": "sha512-IbBGWhaxiEl64fznwh5PDEB0N7YJEAvK5b6nRtPVUKdKAHlOPgo6B9XB8mqWDs8Ct0oF/E34ZLiq2U0L5xDkrg==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.17.tgz", + "integrity": "sha512-b/bDL76p51+yQ+0O9ZDH5nw/ioE0sRYkjwjOwFWAWZXo6it2kQZUOXhVpjohx3ldKyUxt/SwAivjUu1Nr/PWlQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/types": "^3.973.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.10", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/types": "^3.973.4", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/property-provider": "^4.2.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.16", "tslib": "^2.6.2" }, "engines": { @@ -763,24 +710,24 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.2.tgz", - "integrity": "sha512-Jrb8sLm6k8+L7520irBrvCtdLxNtrG7arIxe9TCeMJt/HxqMGJdbIjw8wILzkEHLMIi4MecF2FbXCln7OT1Tag==", + "version": "3.972.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.15.tgz", + "integrity": "sha512-qWnM+wB8MmU2kKY7f4KowKjOjkwRosaFxrtseEEIefwoXn1SjN+CbHzXBVdTAQxxkbBiqhPgJ/WHiPtES4grRQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/credential-provider-env": "^3.972.2", - "@aws-sdk/credential-provider-http": "^3.972.3", - "@aws-sdk/credential-provider-login": "^3.972.2", - "@aws-sdk/credential-provider-process": "^3.972.2", - "@aws-sdk/credential-provider-sso": "^3.972.2", - "@aws-sdk/credential-provider-web-identity": "^3.972.2", - "@aws-sdk/nested-clients": "3.975.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-env": "^3.972.15", + "@aws-sdk/credential-provider-http": "^3.972.17", + "@aws-sdk/credential-provider-login": "^3.972.15", + "@aws-sdk/credential-provider-process": "^3.972.15", + "@aws-sdk/credential-provider-sso": "^3.972.15", + "@aws-sdk/credential-provider-web-identity": "^3.972.15", + "@aws-sdk/nested-clients": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@smithy/credential-provider-imds": "^4.2.10", + "@smithy/property-provider": "^4.2.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -788,18 +735,18 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.2.tgz", - "integrity": "sha512-mlaw2aiI3DrimW85ZMn3g7qrtHueidS58IGytZ+mbFpsYLK5wMjCAKZQtt7VatLMtSBG/dn/EY4njbnYXIDKeQ==", + "version": "3.972.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.15.tgz", + "integrity": "sha512-x92FJy34/95wgu+qOGD8SHcgh1hZ9Qx2uFtQEGn4m9Ljou8ICIv3Ybq5yxdB7A60S8ZGCQB0mIopmjJwiLbh5g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/nested-clients": "3.975.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/nested-clients": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@smithy/property-provider": "^4.2.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -807,22 +754,22 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.2.tgz", - "integrity": "sha512-Lz1J5IZdTjLYTVIcDP5DVDgi1xlgsF3p1cnvmbfKbjCRhQpftN2e2J4NFfRRvPD54W9+bZ8l5VipPXtTYK7aEg==", + "version": "3.972.16", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.16.tgz", + "integrity": "sha512-7mlt14Ee4rPFAFUVgpWE7+0CBhetJJyzVFqfIsMp7sgyOSm9Y/+qHZOWAuK5I4JNc+Y5PltvJ9kssTzRo92iXQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.2", - "@aws-sdk/credential-provider-http": "^3.972.3", - "@aws-sdk/credential-provider-ini": "^3.972.2", - "@aws-sdk/credential-provider-process": "^3.972.2", - "@aws-sdk/credential-provider-sso": "^3.972.2", - "@aws-sdk/credential-provider-web-identity": "^3.972.2", - "@aws-sdk/types": "^3.973.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/credential-provider-env": "^3.972.15", + "@aws-sdk/credential-provider-http": "^3.972.17", + "@aws-sdk/credential-provider-ini": "^3.972.15", + "@aws-sdk/credential-provider-process": "^3.972.15", + "@aws-sdk/credential-provider-sso": "^3.972.15", + "@aws-sdk/credential-provider-web-identity": "^3.972.15", + "@aws-sdk/types": "^3.973.4", + "@smithy/credential-provider-imds": "^4.2.10", + "@smithy/property-provider": "^4.2.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -830,16 +777,16 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.2.tgz", - "integrity": "sha512-NLKLTT7jnUe9GpQAVkPTJO+cs2FjlQDt5fArIYS7h/Iw/CvamzgGYGFRVD2SE05nOHCMwafUSi42If8esGFV+g==", + "version": "3.972.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.15.tgz", + "integrity": "sha512-PrH3iTeD18y/8uJvQD2s/T87BTGhsdS/1KZU7ReWHXsplBwvCqi7AbnnNbML1pFlQwRWCE2RdSZFWDVId3CvkA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/types": "^3.973.4", + "@smithy/property-provider": "^4.2.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -847,18 +794,18 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.2.tgz", - "integrity": "sha512-YpwDn8g3gCGUl61cCV0sRxP2pFIwg+ZsMfWQ/GalSyjXtRkctCMFA+u0yPb/Q4uTfNEiya1Y4nm0C5rIHyPW5Q==", + "version": "3.972.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.15.tgz", + "integrity": "sha512-M/+LBHTPKZxxXckM6m4dnJeR+jlm9NynH9b2YDswN4Zj2St05SK/crdL3Wy3WfJTZootnnhm3oTh87Usl7PS7w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.975.0", - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/token-providers": "3.975.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/nested-clients": "^3.996.5", + "@aws-sdk/token-providers": "3.1002.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/property-provider": "^4.2.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -866,17 +813,17 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.2.tgz", - "integrity": "sha512-x9DAiN9Qz+NjJ99ltDiVQ8d511M/tuF/9MFbe2jUgo7HZhD6+x4S3iT1YcP07ndwDUjmzKGmeOEgE24k4qvfdg==", + "version": "3.972.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.15.tgz", + "integrity": "sha512-QTH6k93v+UOfFam/ado8zc71tH+enTVyuvLy9uEWXX1x894dN5ovtf/MdBDgFwq3g6c9mbtgVJ4B+yBqDtXvdA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/nested-clients": "3.975.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/nested-clients": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@smithy/property-provider": "^4.2.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -884,30 +831,30 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.975.0.tgz", - "integrity": "sha512-3aisLw0I1yrmUpPuhqXZg8eLWOMQhwD/kRaP57WpTJzb2dGz3VouIgkyiUQALMx4KrA2SCy74zq52HnbFxtwRg==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.1002.0.tgz", + "integrity": "sha512-D9E3iBWt7kQ3WZ6R6mOy4GDiC/fV+z5lVMVuHNdicryga0fWkuoZBK/dTEdFBEiQBQ3WdDORzEzD+PytYstFBg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.975.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-cognito-identity": "^3.972.1", - "@aws-sdk/credential-provider-env": "^3.972.1", - "@aws-sdk/credential-provider-http": "^3.972.2", - "@aws-sdk/credential-provider-ini": "^3.972.1", - "@aws-sdk/credential-provider-login": "^3.972.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/credential-provider-process": "^3.972.1", - "@aws-sdk/credential-provider-sso": "^3.972.1", - "@aws-sdk/credential-provider-web-identity": "^3.972.1", - "@aws-sdk/nested-clients": "3.975.0", - "@aws-sdk/types": "^3.973.0", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/client-cognito-identity": "3.1002.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/credential-provider-cognito-identity": "^3.972.8", + "@aws-sdk/credential-provider-env": "^3.972.15", + "@aws-sdk/credential-provider-http": "^3.972.17", + "@aws-sdk/credential-provider-ini": "^3.972.15", + "@aws-sdk/credential-provider-login": "^3.972.15", + "@aws-sdk/credential-provider-node": "^3.972.16", + "@aws-sdk/credential-provider-process": "^3.972.15", + "@aws-sdk/credential-provider-sso": "^3.972.15", + "@aws-sdk/credential-provider-web-identity": "^3.972.15", + "@aws-sdk/nested-clients": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/credential-provider-imds": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/property-provider": "^4.2.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -915,29 +862,26 @@ } }, "node_modules/@aws-sdk/dynamodb-codec": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.972.3.tgz", - "integrity": "sha512-ZkCxaFHN/v30ZLU/F/lok7yNNVwavaAM8IwDVmCAnCvb4bNIueCw40w5iI8DNGMmnRPa+mfp+rM1LIYVSjuMDQ==", + "version": "3.972.18", + "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.972.18.tgz", + "integrity": "sha512-PKD3kBKmj0nvAgzYfV7cdjJ3z0sSxtoYiw5t1WTLedksyRW1RNBvpVDXDI7nt9xpcn6K7Ui1P7VV05yoiQxzDA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@smithy/core": "^3.21.1", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", + "@aws-sdk/core": "^3.973.17", + "@smithy/core": "^3.23.7", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-dynamodb": "3.975.0" } }, "node_modules/@aws-sdk/endpoint-cache": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.2.tgz", - "integrity": "sha512-3L7mwqSLJ6ouZZKtCntoNF0HTYDNs1FDQqkGjoPWXcv1p0gnLotaDmLq1rIDqfu4ucOit0Re3ioLyYDUTpSroA==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/endpoint-cache/-/endpoint-cache-3.972.3.tgz", + "integrity": "sha512-s5oiwOTe0ajI5y/cRMsThZsmlrZiAEcUct723O9NivR/es8fDtglbhHo7eQE4ydddCivFCm2lpNj8RPDLdL3AA==", "license": "Apache-2.0", "dependencies": { "mnemonist": "0.38.3", @@ -948,37 +892,37 @@ } }, "node_modules/@aws-sdk/lib-dynamodb": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.975.0.tgz", - "integrity": "sha512-BEhzr8atBFT8mJ8KuFne3OHj81zsqQWLP1Is2zzbzbZy4Mjbm1nRceNEwZ603tp9oFrV2mwTNLagFDPEudJC/g==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.1002.0.tgz", + "integrity": "sha512-zxS1q4yrMbvF8yl274CsfO8myNtijefnnU37CukP6H2CrNTE2Qoo1oZ3Ixgisz2jd7Rx1WAsSnXh7EUxEsLEjQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/util-dynamodb": "3.975.0", - "@smithy/core": "^3.21.1", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/util-dynamodb": "^3.996.1", + "@smithy/core": "^3.23.7", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "3.975.0" + "@aws-sdk/client-dynamodb": "^3.1002.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.2.tgz", - "integrity": "sha512-ofuXBnitp9j8t05O4NQVrpMZDECPtUhRIWdLzR35baR5njOIPY7YqNtJE+yELVpSn2m4jt2sV1ezYMBY4/Lo+w==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.6.tgz", + "integrity": "sha512-3H2bhvb7Cb/S6WFsBy/Dy9q2aegC9JmGH1inO8Lb2sWirSqpLJlZmvQHPE29h2tIxzv6el/14X/tLCQ8BQU6ZQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", + "@aws-sdk/types": "^3.973.4", "@aws-sdk/util-arn-parser": "^3.972.2", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.1", "tslib": "^2.6.2" }, "engines": { @@ -986,16 +930,16 @@ } }, "node_modules/@aws-sdk/middleware-endpoint-discovery": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.2.tgz", - "integrity": "sha512-Pzz/j7wiKibTHVfPDhqjdlhL+GqP/Nsd6mbeG56uc8BsmZGHBrz5TrwLAQXE1mWBliiEDs9fsh0W62CsX/Qy1g==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.6.tgz", + "integrity": "sha512-p5DYw2cpnsuT/bFA4DEBxucY/wn3TVGDZ7wonEds6EEox35I5DThCsw6aWDIN/fTpG0FMLO3q7s1PUKozWl3CQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/endpoint-cache": "^3.972.2", - "@aws-sdk/types": "^3.973.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/endpoint-cache": "^3.972.3", + "@aws-sdk/types": "^3.973.4", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1003,14 +947,14 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.2.tgz", - "integrity": "sha512-d9bBQlGk1T5j5rWfof20M2tErddOSoSLDauP2/yyuXfeOfQRCSBUZNrApSxjJ9Hw+/RDGR/XL+LEOqmXxSlV3A==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.6.tgz", + "integrity": "sha512-QMdffpU+GkSGC+bz6WdqlclqIeCsOfgX8JFZ5xvwDtX+UTj4mIXm3uXu7Ko6dBseRcJz1FA6T9OmlAAY6JgJUg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1018,39 +962,52 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.2.tgz", - "integrity": "sha512-GgWVZJdzXzqhXxzNAYB3TnZCj7d5rZNdovqSIV91e97nowHVaExRoyaZ3H/Ydqot7veHGPTl8nBp464zZeLDTQ==", + "version": "3.973.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.973.3.tgz", + "integrity": "sha512-C9Mu9pXMpQh7jBydx0MrfQxNIKwJvKbVbJJ0GZthM+cQ+KTChXA01MwttRsMq0ZRb4pBJZQtIKDUxXusDr5OKg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/crc64-nvme": "3.972.0", - "@aws-sdk/types": "^3.973.1", - "@smithy/is-array-buffer": "^4.2.0", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.10", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/crc64-nvme": "^3.972.3", + "@aws-sdk/types": "^3.973.4", + "@smithy/is-array-buffer": "^4.2.1", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-stream": "^4.5.16", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.2.tgz", - "integrity": "sha512-42hZ8jEXT2uR6YybCzNq9OomqHPw43YIfRfz17biZjMQA4jKSQUaHIl6VvqO2Ddl5904pXg2Yd/ku78S0Ikgog==", + "node_modules/@aws-sdk/middleware-flexible-checksums/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.6.tgz", + "integrity": "sha512-5XHwjPH1lHB+1q4bfC7T8Z5zZrZXfaLcjSMwTd1HPSPrCmPFMbg3UQ5vgNWcVj0xoX4HWqTGkSf2byrjlnRg5w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.4", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1058,13 +1015,13 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.2.tgz", - "integrity": "sha512-pyayzpq+VQiG1o9pEUyr6BXEJ2g2t4JIPdNxDkIHp2AhR63Gy/10WQkXTBOgRnfQ7/aLPLOnjRIWwOPp0CfUlA==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.6.tgz", + "integrity": "sha512-XdZ2TLwyj3Am6kvUc67vquQvs6+D8npXvXgyEUJAdkUDx5oMFJKOqpK+UpJhVDsEL068WAJl2NEGzbSik7dGJQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1072,13 +1029,13 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.2.tgz", - "integrity": "sha512-iUzdXKOgi4JVDDEG/VvoNw50FryRCEm0qAudw12DcZoiNJWl0rN6SYVLcL1xwugMfQncCXieK5UBlG6mhH7iYA==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.6.tgz", + "integrity": "sha512-iFnaMFMQdljAPrvsCVKYltPt2j40LQqukAbXvW7v0aL5I+1GO7bZ/W8m12WxW3gwyK5p5u1WlHg8TSAizC5cZw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1086,15 +1043,15 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.2.tgz", - "integrity": "sha512-/mzlyzJDtngNFd/rAYvqx29a2d0VuiYKN84Y/Mu9mGw7cfMOCyRK+896tb9wV6MoPRHUX7IXuKCIL8nzz2Pz5A==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.6.tgz", + "integrity": "sha512-dY4v3of5EEMvik6+UDwQ96KfUFDk8m1oZDdkSc5lwi4o7rFrjnv0A+yTV+gu230iybQZnKgDLg/rt2P3H+Vscw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", + "@aws-sdk/types": "^3.973.4", "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1102,38 +1059,70 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.3.tgz", - "integrity": "sha512-ZVtakKpQ7vI9l7tE2SJjQgoPYv2f/Bw/HMip5wBigsQBDvVbN300h+6nPnm0gnEQwIGGG0yJF3XCvr1/4pZW9A==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.17.tgz", + "integrity": "sha512-uSyOGoVFMP44pTt29MIMfsOjegqE/7lT0K3HG0GWPiH2lD4rqZC/TRi/kH4zrGiOQdsaLc+dkfd7Sb2q8vh+gA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/types": "^3.973.1", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/types": "^3.973.4", "@aws-sdk/util-arn-parser": "^3.972.2", - "@smithy/core": "^3.21.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.10", - "@smithy/util-utf8": "^4.2.0", + "@smithy/core": "^3.23.7", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/protocol-http": "^5.3.10", + "@smithy/signature-v4": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-stream": "^4.5.16", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.2.tgz", - "integrity": "sha512-HJ3OmQnlQ1es6esrDWnx3nVPhBAN89WaFCzsDcb6oT7TMjBPUfZ5+1BpI7B0Hnme8cc6kp7qc4cgo2plrlROJA==", + "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@smithy/signature-v4": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.11.tgz", + "integrity": "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.6.tgz", + "integrity": "sha512-acvMUX9jF4I2Ew+Z/EA6gfaFaz9ehci5wxBmXCZeulLuv8m+iGf6pY9uKz8TPjg39bdAz3hxoE0eLP8Qz+IYlA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.4", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1141,17 +1130,17 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.3.tgz", - "integrity": "sha512-zq6aTiO/BiAIOA8EH8nB+wYvvnZ14Md9Gomm5DDhParshVEVglAyNPO5ADK4ZXFQbftIoO+Vgcvf4gewW/+iYQ==", + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.17.tgz", + "integrity": "sha512-HHArkgWzomuwufXwheQqkddu763PWCpoNTq1dGjqXzJT/lojX3VlOqjNSR2Xvb6/T9ISfwYcMOcbFgUp4EWxXA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.972.0", - "@smithy/core": "^3.21.1", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@smithy/core": "^3.23.7", + "@smithy/protocol-http": "^5.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1159,54 +1148,67 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.975.0.tgz", - "integrity": "sha512-OkeFHPlQj2c/Y5bQGkX14pxhDWUGUFt3LRHhjcDKsSCw6lrxKcxN3WFZN0qbJwKNydP+knL5nxvfgKiCLpTLRA==", + "version": "3.996.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.5.tgz", + "integrity": "sha512-zn0WApcULn7Rtl6T+KP2CQTZo/7wOa2YV1yHQnbijTQoi4YXQHM8s21JcJzt33/mqPh8AdvWX1f+83KvKuxlZw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/hash-node": "^4.2.8", - "@smithy/invalid-dependency": "^4.2.8", - "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@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.26", - "@smithy/util-defaults-mode-node": "^4.2.29", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/middleware-host-header": "^3.972.6", + "@aws-sdk/middleware-logger": "^3.972.6", + "@aws-sdk/middleware-recursion-detection": "^3.972.6", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/region-config-resolver": "^3.972.6", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-endpoints": "^3.996.3", + "@aws-sdk/util-user-agent-browser": "^3.972.6", + "@aws-sdk/util-user-agent-node": "^3.973.2", + "@smithy/config-resolver": "^4.4.9", + "@smithy/core": "^3.23.7", + "@smithy/fetch-http-handler": "^5.3.12", + "@smithy/hash-node": "^4.2.10", + "@smithy/invalid-dependency": "^4.2.10", + "@smithy/middleware-content-length": "^4.2.10", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/middleware-retry": "^4.4.38", + "@smithy/middleware-serde": "^4.2.11", + "@smithy/middleware-stack": "^4.2.10", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/node-http-handler": "^4.4.13", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-base64": "^4.3.1", + "@smithy/util-body-length-browser": "^4.2.1", + "@smithy/util-body-length-node": "^4.2.2", + "@smithy/util-defaults-mode-browser": "^4.3.37", + "@smithy/util-defaults-mode-node": "^4.2.40", + "@smithy/util-endpoints": "^3.3.1", + "@smithy/util-middleware": "^4.2.10", + "@smithy/util-retry": "^4.2.10", + "@smithy/util-utf8": "^4.2.1", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/nested-clients/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/node-http-handler": { "version": "3.374.0", "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.374.0.tgz", @@ -1302,15 +1304,15 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.2.tgz", - "integrity": "sha512-/7vRBsfmiOlg2X67EdKrzzQGw5/SbkXb7ALHQmlQLkZh8qNgvS2G2dDC6NtF3hzFlpP3j2k+KIEtql/6VrI6JA==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.6.tgz", + "integrity": "sha512-Aa5PusHLXAqLTX1UKDvI3pHQJtIsF7Q+3turCHqfz/1F61/zDMWfbTC8evjhrrYVAtz9Vsv3SJ/waSUeu7B6gw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/config-resolver": "^4.4.6", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/config-resolver": "^4.4.9", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1318,18 +1320,18 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.975.0.tgz", - "integrity": "sha512-rqDktHVSB7Ah7XXqr6BWMqDhGXEccp0h1EivaOGED73JjeG/S7taoywJPqi7YkalRb3Ka+LRc7wVoN9wSa4KQA==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.1002.0.tgz", + "integrity": "sha512-vzbygdP2KMRoD7jheRNBlYVvrmGrwyeec+6KwHiM9AtFQ+tx4EvF8x0Wo+7FjVn1PL3t5Do7i54f4ozKCYJleQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.972.0", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-format-url": "^3.972.1", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", + "@aws-sdk/signature-v4-multi-region": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@aws-sdk/util-format-url": "^3.972.6", + "@smithy/middleware-endpoint": "^4.4.21", + "@smithy/protocol-http": "^5.3.10", + "@smithy/smithy-client": "^4.12.1", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1337,122 +1339,66 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.972.0.tgz", - "integrity": "sha512-2udiRijmjpN81Pvajje4TsjbXDZNP6K9bYUanBYH8hXa/tZG5qfGCySD+TyX0sgDxCQmEDMg3LaQdfjNHBDEgQ==", + "version": "3.996.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.5.tgz", + "integrity": "sha512-AVIhf74wRMzU1WBPVzcGPjlADF5VxZ8m8Ctm1v7eO4/reWMhZnEBn4tlR4vM4pOYFkdrYp3MTzYVZIikCO+53Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.972.0", - "@aws-sdk/types": "3.972.0", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/middleware-sdk-s3": "^3.972.17", + "@aws-sdk/types": "^3.973.4", + "@smithy/protocol-http": "^5.3.10", + "@smithy/signature-v4": "^5.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/core": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.972.0.tgz", - "integrity": "sha512-nEeUW2M9F+xdIaD98F5MBcQ4ITtykj3yKbgFZ6J0JtL3bq+Z90szQ6Yy8H/BLPYXTs3V4n9ifnBo8cprRDiE6A==", + "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@smithy/signature-v4": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.11.tgz", + "integrity": "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.972.0", - "@aws-sdk/xml-builder": "3.972.0", - "@smithy/core": "^3.20.6", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.10.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-utf8": "^4.2.0", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=20.0.0" + "node": ">=18.0.0" } }, - "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.0.tgz", - "integrity": "sha512-0bcKFXWx+NZ7tIlOo7KjQ+O2rydiHdIQahrq+fN6k9Osky29v17guy68urUKfhTobR6iY6KvxkroFWaFtTgS5w==", + "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.972.0", - "@aws-sdk/types": "3.972.0", - "@aws-sdk/util-arn-parser": "3.972.0", - "@smithy/core": "^3.20.6", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.10.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.10", - "@smithy/util-utf8": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/types": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.972.0.tgz", - "integrity": "sha512-U7xBIbLSetONxb2bNzHyDgND3oKGoIfmknrEVnoEU4GUSs+0augUOIn9DIWGUO2ETcRFdsRUnmx9KhPT9Ojbug==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.12.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/util-arn-parser": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.0.tgz", - "integrity": "sha512-RM5Mmo/KJ593iMSrALlHEOcc9YOIyOsDmS5x2NLOMdEmzv1o00fcpAkCQ02IGu1eFneBFT7uX0Mpag0HI+Cz2g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/signature-v4-multi-region/node_modules/@aws-sdk/xml-builder": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.0.tgz", - "integrity": "sha512-POaGMcXnozzqBUyJM3HLUZ9GR6OKJWPGJEmhtTnxZXt8B6JcJ/6K3xRJ5H/j8oovVLz8Wg6vFxAHv8lvuASxMg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.12.0", - "fast-xml-parser": "5.2.5", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" + "node": ">=18.0.0" } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.975.0.tgz", - "integrity": "sha512-AWQt64hkVbDQ+CmM09wnvSk2mVyH4iRROkmYkr3/lmUtFNbE2L/fnw26sckZnUcFCsHPqbkQrcsZAnTcBLbH4w==", + "version": "3.1002.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1002.0.tgz", + "integrity": "sha512-x972uKOydFn4Rb0PZJzLdNW59rH0KWC78Q2JbQzZpGlGt0DxjYdDRwBG6F42B1MyaEwHGqO/tkGc4r3/PRFfMw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/nested-clients": "3.975.0", - "@aws-sdk/types": "^3.973.0", - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@aws-sdk/core": "^3.973.17", + "@aws-sdk/nested-clients": "^3.996.5", + "@aws-sdk/types": "^3.973.4", + "@smithy/property-provider": "^4.2.10", + "@smithy/shared-ini-file-loader": "^4.4.5", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1460,12 +1406,12 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.973.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.1.tgz", - "integrity": "sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==", + "version": "3.973.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.4.tgz", + "integrity": "sha512-RW60aH26Bsc016Y9B98hC0Plx6fK5P2v/iQYwMzrSjiDh1qRMUCP6KrXHYEHe3uFvKiOC93Z9zk4BJsUi6Tj1Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1485,9 +1431,9 @@ } }, "node_modules/@aws-sdk/util-dynamodb": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.975.0.tgz", - "integrity": "sha512-ZsziF8m5Syn+kA2YJLEG2kk6zfxea8yRl/7SkSFpAls8RFYkt8EUmVUMBhX2hBpGw+nbZL7+AcRi4S2LxAcYWA==", + "version": "3.996.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.996.1.tgz", + "integrity": "sha512-5Vle00DrIcao9x5UuhkEprIQiMuhVvrxSLQwEhTb1sfWvdrLphcW4LqAtOkWSHpWF9ZdQQVKXvAOjKNV8LSlrw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -1496,32 +1442,19 @@ "node": ">=20.0.0" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "3.975.0" + "@aws-sdk/client-dynamodb": "^3.997.0" } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.972.0.tgz", - "integrity": "sha512-6JHsl1V/a1ZW8D8AFfd4R52fwZPnZ5H4U6DS8m/bWT8qad72NvbOFAC7U2cDtFs2TShqUO3TEiX/EJibtY3ijg==", + "version": "3.996.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.3.tgz", + "integrity": "sha512-yWIQSNiCjykLL+ezN5A+DfBb1gfXTytBxm57e64lYmwxDHNmInYHRJYYRAGWG1o77vKEiWaw4ui28e3yb1k5aQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.972.0", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-endpoints": "^3.2.8", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints/node_modules/@aws-sdk/types": { - "version": "3.972.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.972.0.tgz", - "integrity": "sha512-U7xBIbLSetONxb2bNzHyDgND3oKGoIfmknrEVnoEU4GUSs+0augUOIn9DIWGUO2ETcRFdsRUnmx9KhPT9Ojbug==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.10", + "@smithy/util-endpoints": "^3.3.1", "tslib": "^2.6.2" }, "engines": { @@ -1529,14 +1462,14 @@ } }, "node_modules/@aws-sdk/util-format-url": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.2.tgz", - "integrity": "sha512-RCd8eur5wzDLgFBvbBhoFQ1bw1wxHJiN88MQ82IiJBs6OGXTWaf0oFgLbK06qJvnVUqL13t3jEnlYPHPNdgBWw==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.6.tgz", + "integrity": "sha512-0YNVNgFyziCejXJx0rzxPiD2rkxTWco4c9wiMF6n37Tb9aQvIF8+t7GyEyIFCwQHZ0VMQaAl+nCZHOYz5I5EKw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/querystring-builder": "^4.2.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1556,27 +1489,27 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.2.tgz", - "integrity": "sha512-gz76bUyebPZRxIsBHJUd/v+yiyFzm9adHbr8NykP2nm+z/rFyvQneOHajrUejtmnc5tTBeaDPL4X25TnagRk4A==", + "version": "3.972.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.6.tgz", + "integrity": "sha512-Fwr/llD6GOrFgQnKaI2glhohdGuBDfHfora6iG9qsBBBR8xv1SdCSwbtf5CWlUdCw5X7g76G/9Hf0Inh0EmoxA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "^3.973.1", - "@smithy/types": "^4.12.0", + "@aws-sdk/types": "^3.973.4", + "@smithy/types": "^4.13.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.2.tgz", - "integrity": "sha512-vnxOc4C6AR7hVbwyFo1YuH0GB6dgJlWt8nIOOJpnzJAWJPkUMPJ9Zv2lnKsSU7TTZbhP2hEO8OZ4PYH59XFv8Q==", + "version": "3.973.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.2.tgz", + "integrity": "sha512-lpaIuekdkpw7VRiik0IZmd6TyvEUcuLgKZ5fKRGpCA3I4PjrD/XH15sSwW+OptxQjNU4DEzSxag70spC9SluvA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.3", - "@aws-sdk/types": "^3.973.1", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@aws-sdk/middleware-user-agent": "^3.972.17", + "@aws-sdk/types": "^3.973.4", + "@smithy/node-config-provider": "^4.3.10", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -1592,13 +1525,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.2.tgz", - "integrity": "sha512-jGOOV/bV1DhkkUhHiZ3/1GZ67cZyOXaDb7d1rYD6ZiXf5V9tBNOcgqXwRRPvrCbYaFRa1pPMFb3ZjqjWpR3YfA==", + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.9.tgz", + "integrity": "sha512-ItnlMgSqkPrUfJs7EsvU/01zw5UeIb2tNPhD09LBLHbg+g+HDiKibSLwpkuz/ZIlz4F2IMn+5XgE4AK/pfPuog==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "fast-xml-parser": "5.2.5", + "@smithy/types": "^4.13.0", + "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" }, "engines": { @@ -1738,17 +1671,19 @@ } }, "node_modules/@azure/core-http-compat": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.1.tgz", - "integrity": "sha512-az9BkXND3/d5VgdRRQVkiJb2gOmDU8Qcq4GvjtBmDICNiQ9udFmDk4ZpSB5Qq1OmtDJGlQAfBaS4palFsazQ5g==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.2.tgz", + "integrity": "sha512-Tf6ltdKzOJEgxZeWLCjMxrxbodB/ZeCbzzA1A2qHbhzAjzjHoBVSUeSl/baT/oHAxhc4qdqVaDKnc2+iE932gw==", "license": "MIT", "dependencies": { - "@azure/abort-controller": "^2.1.2", - "@azure/core-client": "^1.10.0", - "@azure/core-rest-pipeline": "^1.22.0" + "@azure/abort-controller": "^2.1.2" }, "engines": { "node": ">=20.0.0" + }, + "peerDependencies": { + "@azure/core-client": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0" } }, "node_modules/@azure/core-http-compat/node_modules/@azure/abort-controller": { @@ -2082,33 +2017,33 @@ } }, "node_modules/@azure/msal-browser": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.28.1.tgz", - "integrity": "sha512-al2u2fTchbClq3L4C1NlqLm+vwKfhYCPtZN2LR/9xJVaQ4Mnrwf5vANvuyPSJHcGvw50UBmhuVmYUAhTEetTpA==", + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.29.0.tgz", + "integrity": "sha512-/f3eHkSNUTl6DLQHm+bKecjBKcRQxbd/XLx8lvSYp8Nl/HRyPuIPOijt9Dt0sH50/SxOwQ62RnFCmFlGK+bR/w==", "license": "MIT", "dependencies": { - "@azure/msal-common": "15.14.1" + "@azure/msal-common": "15.15.0" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-common": { - "version": "15.14.1", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.14.1.tgz", - "integrity": "sha512-IkzF7Pywt6QKTS0kwdCv/XV8x8JXknZDvSjj/IccooxnP373T5jaadO3FnOrbWo3S0UqkfIDyZNTaQ/oAgRdXw==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.15.0.tgz", + "integrity": "sha512-/n+bN0AKlVa+AOcETkJSKj38+bvFs78BaP4rNtv3MJCmPH0YrHiskMRe74OhyZ5DZjGISlFyxqvf9/4QVEi2tw==", "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-node": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.6.tgz", - "integrity": "sha512-XTmhdItcBckcVVTy65Xp+42xG4LX5GK+9AqAsXPXk4IqUNv+LyQo5TMwNjuFYBfAB2GTG9iSQGk+QLc03vhf3w==", + "version": "3.8.8", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.8.tgz", + "integrity": "sha512-+f1VrJH1iI517t4zgmuhqORja0bL6LDQXfBqkjuMmfTYXTQQnh1EvwwxO3UbKLT05N0obF72SRHFrC1RBDv5Gg==", "license": "MIT", "dependencies": { - "@azure/msal-common": "15.14.1", + "@azure/msal-common": "15.15.0", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" }, @@ -2126,9 +2061,9 @@ } }, "node_modules/@azure/storage-blob": { - "version": "12.30.0", - "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.30.0.tgz", - "integrity": "sha512-peDCR8blSqhsAKDbpSP/o55S4sheNwSrblvCaHUZ5xUI73XA7ieUGGwrONgD/Fng0EoDe1VOa3fAQ7+WGB3Ocg==", + "version": "12.31.0", + "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.31.0.tgz", + "integrity": "sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg==", "license": "MIT", "dependencies": { "@azure/abort-controller": "^2.1.2", @@ -2142,7 +2077,7 @@ "@azure/core-util": "^1.11.0", "@azure/core-xml": "^1.4.5", "@azure/logger": "^1.1.4", - "@azure/storage-common": "^12.2.0", + "@azure/storage-common": "^12.3.0", "events": "^3.0.0", "tslib": "^2.8.1" }, @@ -2163,9 +2098,9 @@ } }, "node_modules/@azure/storage-common": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/@azure/storage-common/-/storage-common-12.2.0.tgz", - "integrity": "sha512-YZLxiJ3vBAAnFbG3TFuAMUlxZRexjQX5JDQxOkFGb6e2TpoxH3xyHI6idsMe/QrWtj41U/KoqBxlayzhS+LlwA==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@azure/storage-common/-/storage-common-12.3.0.tgz", + "integrity": "sha512-/OFHhy86aG5Pe8dP5tsp+BuJ25JOAl9yaMU3WZbkeoiFMHFtJ7tu5ili7qEdBXNW9G5lDB19trwyI6V49F/8iQ==", "license": "MIT", "dependencies": { "@azure/abort-controller": "^2.1.2", @@ -2205,9 +2140,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", - "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -2215,21 +2150,21 @@ } }, "node_modules/@babel/core": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", - "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/generator": "^7.28.6", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.28.6", + "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -2246,9 +2181,9 @@ } }, "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -2278,14 +2213,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", - "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -2512,13 +2447,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", - "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.6" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -2776,9 +2711,9 @@ } }, "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -2791,18 +2726,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", - "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/generator": "^7.28.6", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.6", + "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -2810,9 +2745,9 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -2825,9 +2760,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", - "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -2846,21 +2781,21 @@ "license": "MIT" }, "node_modules/@clickhouse/client": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@clickhouse/client/-/client-1.16.0.tgz", - "integrity": "sha512-ThPhoRMsKsf/hmBEgWlUsGxFecsr3i+k3JI8JV0Od7UpH2BSmk9VKMGJoyPCrTL0vPUs5rJH+7o4iCqBF09Xvg==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@clickhouse/client/-/client-1.18.1.tgz", + "integrity": "sha512-fO4QggCOSr0WBS9oGIFa83FUhbweP8VTFGOXF51DJQbR/oEXegdocNSma3Gp6F4Km9A1Xm1ZAhwrldtg3prPiQ==", "license": "Apache-2.0", "dependencies": { - "@clickhouse/client-common": "1.16.0" + "@clickhouse/client-common": "1.18.1" }, "engines": { "node": ">=16" } }, "node_modules/@clickhouse/client-common": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@clickhouse/client-common/-/client-common-1.16.0.tgz", - "integrity": "sha512-qMzkI1NmV29ZjFkNpVSvGNfA0c7sCExlufAQMv+V+5xtNeYXnRfdqzmBLIQoq6Pf1ij0kw/wGLD3HQrl7pTFLA==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@clickhouse/client-common/-/client-common-1.18.1.tgz", + "integrity": "sha512-kDk8miGZVDAzqFrBZRmD9rD82Li8gwaGlJ5MNUpWgxx1OUXRBUkcV6ULysWP1C9Jinb3yle3YLz/XbNOPVgVtQ==", "license": "Apache-2.0" }, "node_modules/@colors/colors": { @@ -2884,9 +2819,9 @@ } }, "node_modules/@databricks/sql": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@databricks/sql/-/sql-1.12.0.tgz", - "integrity": "sha512-bCUoHg2/mNgOXkYTooF1m0wyO57yPJPo44wOTXOlA9CREbXCzP1RMuUVa3GfXKzGifd52nNEPHyKeZvrbJBLnA==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@databricks/sql/-/sql-1.13.0.tgz", + "integrity": "sha512-xBuxCKmq3gR2fXnCzHsWkPujd5Vi/QxtHAyZXlj180v0fAqucIrG3SckSS5bpbF/NOH7uPLjolBUiZWDJ8E4xQ==", "license": "Apache 2.0", "dependencies": { "apache-arrow": "^13.0.0", @@ -2982,6 +2917,19 @@ "node": ">= 4" } }, + "node_modules/@gar/promise-retry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@gar/promise-retry/-/promise-retry-1.0.2.tgz", + "integrity": "sha512-Lm/ZLhDZcBECta3TmCQSngiQykFdfw+QtI1/GYMsZd4l3nG+P8WLB16XuS7WaBGLQ+9E+cOcWQsth9cayuGt8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "retry": "^0.13.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/@google-cloud/bigquery": { "version": "5.12.0", "resolved": "https://registry.npmjs.org/@google-cloud/bigquery/-/bigquery-5.12.0.tgz", @@ -3658,128 +3606,19 @@ } }, "node_modules/@ioredis/commands": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz", - "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz", + "integrity": "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==", "license": "MIT" }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=18" } }, "node_modules/@isaacs/fs-minipass": { @@ -4196,15 +4035,15 @@ "license": "MIT" }, "node_modules/@lerna/create": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-9.0.3.tgz", - "integrity": "sha512-hUTEWrR8zH+/Z3bp/R1aLm6DW8vB/BB7KH7Yeg4fMfrvSwxegiLVW9uJFAzWkK4mzEagmj/Dti85Yg9MN13t0g==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-9.0.5.tgz", + "integrity": "sha512-Gwd6ooSqXMdkdhiCGvHAfLRstj7W3ttr72WQB3Jf9HPP1A6mWtw0O80D0X+T/2hakqfe7lNLuKrEid4f7C0qbg==", "dev": true, "license": "MIT", "dependencies": { "@npmcli/arborist": "9.1.6", "@npmcli/package-json": "7.0.2", - "@npmcli/run-script": "10.0.2", + "@npmcli/run-script": "10.0.3", "@nx/devkit": ">=21.5.2 < 23.0.0", "@octokit/plugin-enterprise-rest": "6.0.1", "@octokit/rest": "20.1.2", @@ -4235,7 +4074,7 @@ "load-json-file": "6.2.0", "make-dir": "4.0.0", "make-fetch-happen": "15.0.2", - "minimatch": "3.0.5", + "minimatch": "3.1.4", "multimatch": "5.0.0", "npm-package-arg": "13.0.1", "npm-packlist": "10.0.3", @@ -4249,14 +4088,14 @@ "pify": "5.0.0", "read-cmd-shim": "4.0.0", "resolve-from": "5.0.0", - "rimraf": "^4.4.1", + "rimraf": "^6.1.2", "semver": "7.7.2", "set-blocking": "^2.0.0", "signal-exit": "3.0.7", "slash": "^3.0.0", "ssri": "12.0.0", "string-width": "^4.2.3", - "tar": "6.2.1", + "tar": "7.5.8", "temp-dir": "1.0.0", "through": "2.3.8", "tinyglobby": "0.2.12", @@ -4281,6 +4120,16 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/@lerna/create/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@lerna/create/node_modules/chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -4351,19 +4200,18 @@ } }, "node_modules/@lerna/create/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -4383,26 +4231,29 @@ } }, "node_modules/@lerna/create/node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@lerna/create/node_modules/glob/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -4432,9 +4283,9 @@ } }, "node_modules/@lerna/create/node_modules/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", "dev": true, "license": "ISC", "dependencies": { @@ -4444,16 +4295,6 @@ "node": "*" } }, - "node_modules/@lerna/create/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, "node_modules/@lerna/create/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -4465,19 +4306,20 @@ } }, "node_modules/@lerna/create/node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^9.2.0" + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" }, "bin": { - "rimraf": "dist/cjs/src/bin.js" + "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -4543,9 +4385,9 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.5.tgz", - "integrity": "sha512-k64Lbyb7ycCSXHSLzxVdb2xsKGPMvYZfCICXvDsI8Z65CeWQzTEKS4YmGbnqw+U9RBvLPTsB6UCmwkgsDTGWIw==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", + "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", "license": "MIT", "optional": true, "dependencies": { @@ -4668,9 +4510,9 @@ } }, "node_modules/@npmcli/agent/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -4725,10 +4567,33 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/@npmcli/arborist/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@npmcli/arborist/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@npmcli/arborist/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -4736,16 +4601,16 @@ } }, "node_modules/@npmcli/arborist/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -4775,12 +4640,13 @@ } }, "node_modules/@npmcli/arborist/node_modules/pacote": { - "version": "21.0.4", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.4.tgz", - "integrity": "sha512-RplP/pDW0NNNDh3pnaoIWYPvNenS7UqMbXyvMqJczosiFWTeGGwJC2NQBLqKf4rGLFfwCOnntw1aEp9Jiqm1MA==", + "version": "21.4.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.4.0.tgz", + "integrity": "sha512-DR7mn7HUOomAX1BORnpYy678qVIidbvOojkBscqy27dRKN+s/hLeQT1MeYYrx1Cxh62jyKjiWiDV7RTTqB+ZEQ==", "dev": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", @@ -4794,7 +4660,6 @@ "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" @@ -4834,9 +4699,9 @@ } }, "node_modules/@npmcli/arborist/node_modules/pacote/node_modules/ssri": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", - "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", "dev": true, "license": "ISC", "dependencies": { @@ -4860,18 +4725,18 @@ } }, "node_modules/@npmcli/git": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", - "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.2.tgz", + "integrity": "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==", "dev": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/promise-spawn": "^9.0.0", "ini": "^6.0.0", "lru-cache": "^11.2.1", "npm-pick-manifest": "^11.0.1", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "semver": "^7.3.5", "which": "^6.0.0" }, @@ -4890,19 +4755,19 @@ } }, "node_modules/@npmcli/git/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -4920,13 +4785,13 @@ } }, "node_modules/@npmcli/git/node_modules/which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" @@ -4978,62 +4843,58 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/@npmcli/map-workspaces/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@npmcli/map-workspaces/node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@npmcli/map-workspaces/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@npmcli/map-workspaces/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5105,10 +4966,34 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/@npmcli/package-json/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@npmcli/package-json/node_modules/glob": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -5129,44 +5014,17 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@npmcli/package-json/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@npmcli/package-json/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@npmcli/package-json/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5196,23 +5054,23 @@ } }, "node_modules/@npmcli/promise-spawn/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/@npmcli/promise-spawn/node_modules/which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" @@ -5245,18 +5103,18 @@ } }, "node_modules/@npmcli/run-script": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.2.tgz", - "integrity": "sha512-9lCTqxaoa9c9cdkzSSx+q/qaYrCrUPEwTWzLkVYg1/T8ESH3BG9vmb1zRc6ODsBVB0+gnGRSqSr01pxTS1yX3A==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", + "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", "dev": true, "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^5.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", - "node-gyp": "^11.0.0", + "node-gyp": "^12.1.0", "proc-log": "^6.0.0", - "which": "^5.0.0" + "which": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -5273,13 +5131,13 @@ } }, "node_modules/@npmcli/run-script/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/@npmcli/run-script/node_modules/proc-log": { @@ -5293,32 +5151,32 @@ } }, "node_modules/@npmcli/run-script/node_modules/which": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@nx/devkit": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-22.4.2.tgz", - "integrity": "sha512-ULInRB5YMcUfYdJRCoxrdAhshAv8on5LPVHRvUpk7RmirtLNTDSOL9q83pJD3ChFmwPYwEITPMOwvzm9ku6m7A==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-22.5.4.tgz", + "integrity": "sha512-+QCmpQZQmEGvi8IurC6bOgUTk+Q0dQo7wkp6V04lskXBztSyasBS0BGy5ic90kY05UlQUd++zRA1VY0jc+Yz5Q==", "dev": true, "license": "MIT", "dependencies": { "@zkochan/js-yaml": "0.0.7", "ejs": "^3.1.7", "enquirer": "~2.3.6", - "minimatch": "10.1.1", + "minimatch": "10.2.4", "semver": "^7.6.3", "tslib": "^2.3.0", "yargs-parser": "21.1.1" @@ -5327,6 +5185,29 @@ "nx": ">= 21 <= 23 || ^22.0.0-0" } }, + "node_modules/@nx/devkit/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@nx/devkit/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@nx/devkit/node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -5341,25 +5222,25 @@ } }, "node_modules/@nx/devkit/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@nx/nx-darwin-arm64": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-22.4.2.tgz", - "integrity": "sha512-l/NLbzB7UnE/YnHuFXrMtpchDZaKCXMrcAgleOkxWotqiQ/Fs5hOJ5xFvAbzX1FF/2MHOKXqeBVPfq0y0Vbj4A==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-22.5.4.tgz", + "integrity": "sha512-Ib9znwSLQZSZ/9hhg5ODplpNhE/RhGVXzdfRj6YonTuWSj/kH3dLMio+4JEkjRdTQVm06cDW0KdwSgnwovqMGg==", "cpu": [ "arm64" ], @@ -5371,9 +5252,9 @@ ] }, "node_modules/@nx/nx-darwin-x64": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-22.4.2.tgz", - "integrity": "sha512-H6Vf3VX49wQqxSps2zg5Xym+qjJCkGzCRkD9jPyzBfnUnuMc44tyOYBpO9kdSurq8SYXOu/HP/oFg5EVRiRCQg==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-22.5.4.tgz", + "integrity": "sha512-DjyXuQMc93MPU2XdRsJYjzbv1tgCzMi+zm7O0gc4x3h+ECFjKkjzQBg67pqGdhE3TV27MAlVRKrgHStyK9iigg==", "cpu": [ "x64" ], @@ -5385,9 +5266,9 @@ ] }, "node_modules/@nx/nx-freebsd-x64": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-22.4.2.tgz", - "integrity": "sha512-sNpGYjoOo+cDNLZ6mUK2P6rPN0p55pEyKh5lD7M0p1+DfeDls83NwHuS6apmayo9eUH/JDFFWgIY6Q8Q2uo0Iw==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-22.5.4.tgz", + "integrity": "sha512-DhxdP8AhIfN0yCtFhZQcbp32MVN3L7UiTotYqqnOgwW922NRGSd5e+KEAWiJVrIO6TdgnI7prxpg1hfQQK0WDw==", "cpu": [ "x64" ], @@ -5399,9 +5280,9 @@ ] }, "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-22.4.2.tgz", - "integrity": "sha512-KyjYmhPvJmBzB7bpqjyEWytCi6RwX1Hjly6HU2NjD6dDUg50Gq5qQr5hA+eTBNwxsdOKOB+uCe2+jVw+GZ5vwg==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-22.5.4.tgz", + "integrity": "sha512-pv1x1afTaLAOxPxVhQneLeXgjclp11f9ORxR7jA4E86bSgc9OL92dLSCkXtLQzqPNOej6SZ2fO+PPHVMZwtaPQ==", "cpu": [ "arm" ], @@ -5413,9 +5294,9 @@ ] }, "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-22.4.2.tgz", - "integrity": "sha512-jc7vB/iIHOrA3wg7nch4wBRpPtxuytmgsL1Qf1Ue1LB+PPZSlxYxwujO5YtfcwoB78vnBqt6wPTjx4nyvLcCOQ==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-22.5.4.tgz", + "integrity": "sha512-mPji9PzleWPvXpmFDKaXpTymRgZkk/hW8JHGhvEZpKHHXMYgTGWC+BqOEM2A4dYC4bu4fi9RrteL7aouRRWJoQ==", "cpu": [ "arm64" ], @@ -5427,9 +5308,9 @@ ] }, "node_modules/@nx/nx-linux-arm64-musl": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-22.4.2.tgz", - "integrity": "sha512-7m1u/McVDer4m+c6LDSdxuW2nIani2IeMV4Lvf2LjK5SrDcnqw47CybMeykaarREuY3UQgda04qXPSHWTKUwXg==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-22.5.4.tgz", + "integrity": "sha512-hF/HvEhbCjcFpTgY7RbP1tUTbp0M1adZq4ckyW8mwhDWQ/MDsc8FnOHwCO3Bzy9ZeJM0zQUES6/m0Onz8geaEA==", "cpu": [ "arm64" ], @@ -5441,9 +5322,9 @@ ] }, "node_modules/@nx/nx-linux-x64-gnu": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-22.4.2.tgz", - "integrity": "sha512-IBpm9dE0EdKR7SPZsC12beCk6/iSgSKCQnX5x3c+3cJSxP4Nld9s2TIfTLph1vtjNrgZUrrMO/3KFovzw1szoQ==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-22.5.4.tgz", + "integrity": "sha512-1+vicSYEOtc7CNMoRCjo59no4gFe8w2nGIT127wk1yeW3EJzRVNlOA7Deu10NUUbzLeOvHc8EFOaU7clT+F7XQ==", "cpu": [ "x64" ], @@ -5455,9 +5336,9 @@ ] }, "node_modules/@nx/nx-linux-x64-musl": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-22.4.2.tgz", - "integrity": "sha512-OmXbuSH1SMq2zSwV5lyXP1a4MFDvllZUFbdas7FVr2+gA6vT2xjUVpHiZpb7c0aoTX5X/558L3ic/+JNbDNZyg==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-22.5.4.tgz", + "integrity": "sha512-/KjndxVB14yU0SJOhqADHOWoTy4Y45h5RjW3cxcXlPSJZz7ar1FnlLne1rWMMMUttepc8ku+3T//SGKi2eu+Nw==", "cpu": [ "x64" ], @@ -5469,9 +5350,9 @@ ] }, "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-22.4.2.tgz", - "integrity": "sha512-bnoJ+dOtaAoAn/m7rhClZyMxXu7OcN8oan0TMTM5PvE8qMhLEvwU88l4LC769b/hRvuuVXUGCYKHGC92LQrtJA==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-22.5.4.tgz", + "integrity": "sha512-CrYt9FwhjOI6ZNy/G6YHLJmZuXCFJ24BCxugPXiZ7knDx7eGrr7owGgfht4SSiK3KCX40CvWCBJfqR4ZSgaSUA==", "cpu": [ "arm64" ], @@ -5483,9 +5364,9 @@ ] }, "node_modules/@nx/nx-win32-x64-msvc": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-22.4.2.tgz", - "integrity": "sha512-3JtK1Zty6U/Wc2qDqMPJoYcRk/GrySp8fixe407g1S8ZkKmYMoCyDJAo8mQSu21i3Mkhvwloeoo97yR5//NaqA==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-22.5.4.tgz", + "integrity": "sha512-g5YByv4XsYwsYZvFe24A9bvfhZA+mwtIQt6qZtEVduZTT1hfhIsq0LXGHhkGoFLYwRMXSracWOqkalY0KT4IQw==", "cpu": [ "x64" ], @@ -5890,12 +5771,13 @@ } }, "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", - "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.4.tgz", + "integrity": "sha512-vM2sG+wbVeVGYcCm16mM3d5fuem9oC28n436HjsGO3LcxoTI8LNVa4rwZDn3f76+cWyT4GGJDxjTYU1I2nr6zw==", "dev": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", @@ -5905,7 +5787,6 @@ "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "ssri": "^13.0.0" }, "engines": { @@ -5913,21 +5794,34 @@ } }, "node_modules/@sigstore/sign/node_modules/minipass-fetch": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.0.tgz", - "integrity": "sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.2.tgz", + "integrity": "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==", "dev": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", + "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "engines": { "node": "^20.17.0 || >=22.9.0" }, "optionalDependencies": { - "encoding": "^0.1.13" + "iconv-lite": "^0.7.2" + } + }, + "node_modules/@sigstore/sign/node_modules/minipass-sized": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">=8" } }, "node_modules/@sigstore/sign/node_modules/proc-log": { @@ -5941,9 +5835,9 @@ } }, "node_modules/@sigstore/sign/node_modules/ssri": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", - "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", "dev": true, "license": "ISC", "dependencies": { @@ -6022,12 +5916,12 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", - "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.11.tgz", + "integrity": "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6035,9 +5929,9 @@ } }, "node_modules/@smithy/chunked-blob-reader": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.0.tgz", - "integrity": "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.2.tgz", + "integrity": "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6047,12 +5941,12 @@ } }, "node_modules/@smithy/chunked-blob-reader-native": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.1.tgz", - "integrity": "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.3.tgz", + "integrity": "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-base64": "^4.3.0", + "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -6060,16 +5954,16 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", - "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.10.tgz", + "integrity": "sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.8", - "@smithy/util-middleware": "^4.2.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-endpoints": "^3.3.2", + "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -6077,20 +5971,33 @@ } }, "node_modules/@smithy/core": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.21.1.tgz", - "integrity": "sha512-NUH8R4O6FkN8HKMojzbGg/5pNjsfTjlMmeFclyPfPaXXUrbr5TzhWgbf7t92wfrpCHRgpjyz7ffASIS3wX28aA==", + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.8.tgz", + "integrity": "sha512-f7uPeBi7ehmLT4YF2u9j3qx6lSnurG1DLXOsTtJrIRNDF7VXio4BGHQ+SQteN/BrUVudbkuL4v7oOsRCzq4BqA==", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.2.9", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-stream": "^4.5.10", - "@smithy/util-utf8": "^4.2.0", - "@smithy/uuid": "^1.1.0", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-stream": "^4.5.17", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6098,15 +6005,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", - "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.11.tgz", + "integrity": "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -6114,14 +6021,14 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.8.tgz", - "integrity": "sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.11.tgz", + "integrity": "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6129,13 +6036,13 @@ } }, "node_modules/@smithy/eventstream-serde-browser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.8.tgz", - "integrity": "sha512-MTfQT/CRQz5g24ayXdjg53V0mhucZth4PESoA5IhvaWVDTOQLfo8qI9vzqHcPsdd2v6sqfTYqF5L/l+pea5Uyw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.11.tgz", + "integrity": "sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-serde-universal": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6143,12 +6050,12 @@ } }, "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.8.tgz", - "integrity": "sha512-ah12+luBiDGzBruhu3efNy1IlbwSEdNiw8fOZksoKoWW1ZHvO/04MQsdnws/9Aj+5b0YXSSN2JXKy/ClIsW8MQ==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.11.tgz", + "integrity": "sha512-XeNIA8tcP/GDWnnKkO7qEm/bg0B/bP9lvIXZBXcGZwZ+VYM8h8k9wuDvUODtdQ2Wcp2RcBkPTCSMmaniVHrMlA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6156,13 +6063,13 @@ } }, "node_modules/@smithy/eventstream-serde-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.8.tgz", - "integrity": "sha512-cYpCpp29z6EJHa5T9WL0KAlq3SOKUQkcgSoeRfRVwjGgSFl7Uh32eYGt7IDYCX20skiEdRffyDpvF2efEZPC0A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.11.tgz", + "integrity": "sha512-fzbCh18rscBDTQSCrsp1fGcclLNF//nJyhjldsEl/5wCYmgpHblv5JSppQAyQI24lClsFT0wV06N1Porn0IsEw==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-serde-universal": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-serde-universal": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6170,13 +6077,13 @@ } }, "node_modules/@smithy/eventstream-serde-universal": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.8.tgz", - "integrity": "sha512-iJ6YNJd0bntJYnX6s52NC4WFYcZeKrPUr1Kmmr5AwZcwCSzVpS7oavAmxMR7pMq7V+D1G4s9F5NJK0xwOsKAlQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.11.tgz", + "integrity": "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/eventstream-codec": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/eventstream-codec": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6184,15 +6091,15 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", - "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", + "version": "5.3.13", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.13.tgz", + "integrity": "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/querystring-builder": "^4.2.11", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" }, "engines": { @@ -6200,14 +6107,14 @@ } }, "node_modules/@smithy/hash-blob-browser": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.9.tgz", - "integrity": "sha512-m80d/iicI7DlBDxyQP6Th7BW/ejDGiF0bgI754+tiwK0lgMkcaIBgvwwVc7OFbY4eUzpGtnig52MhPAEJ7iNYg==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.12.tgz", + "integrity": "sha512-1wQE33DsxkM/waftAhCH9VtJbUGyt1PJ9YRDpOu+q9FUi73LLFUZ2fD8A61g2mT1UY9k7b99+V1xZ41Rz4SHRQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/chunked-blob-reader": "^5.2.0", - "@smithy/chunked-blob-reader-native": "^4.2.1", - "@smithy/types": "^4.12.0", + "@smithy/chunked-blob-reader": "^5.2.2", + "@smithy/chunked-blob-reader-native": "^4.2.3", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6215,14 +6122,27 @@ } }, "node_modules/@smithy/hash-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.8.tgz", - "integrity": "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.11.tgz", + "integrity": "sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6230,13 +6150,26 @@ } }, "node_modules/@smithy/hash-stream-node": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.8.tgz", - "integrity": "sha512-v0FLTXgHrTeheYZFGhR+ehX5qUm4IQsjAiL9qehad2cyjMWcN2QG6/4mSwbSgEQzI7jwfoXj7z4fxZUx/Mhj2w==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.11.tgz", + "integrity": "sha512-hQsTjwPCRY8w9GK07w1RqJi3e+myh0UaOWBBhZ1UMSDgofH/Q1fEYzU1teaX6HkpX/eWDdm7tAGR0jBPlz9QEQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-stream-node/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6244,12 +6177,12 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.8.tgz", - "integrity": "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.11.tgz", + "integrity": "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6257,9 +6190,9 @@ } }, "node_modules/@smithy/is-array-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", - "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6269,13 +6202,26 @@ } }, "node_modules/@smithy/md5-js": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.8.tgz", - "integrity": "sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.11.tgz", + "integrity": "sha512-350X4kGIrty0Snx2OWv7rPM6p6vM7RzryvFs6B/56Cux3w3sChOb3bymo5oidXJlPcP9fIRxGUCk7GqpiSOtng==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/md5-js/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6283,13 +6229,13 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.8.tgz", - "integrity": "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.11.tgz", + "integrity": "sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6297,18 +6243,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.11.tgz", - "integrity": "sha512-/WqsrycweGGfb9sSzME4CrsuayjJF6BueBmkKlcbeU5q18OhxRrvvKlmfw3tpDsK5ilx2XUJvoukwxHB0nHs/Q==", + "version": "4.4.22", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.22.tgz", + "integrity": "sha512-sc81w1o4Jy+/MAQlY3sQ8C7CmSpcvIi3TAzXblUv2hjG11BBSJi/Cw8vDx5BxMxapuH2I+Gc+45vWsgU07WZRQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.21.1", - "@smithy/middleware-serde": "^4.2.9", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", - "@smithy/url-parser": "^4.2.8", - "@smithy/util-middleware": "^4.2.8", + "@smithy/core": "^3.23.8", + "@smithy/middleware-serde": "^4.2.12", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", + "@smithy/url-parser": "^4.2.11", + "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" }, "engines": { @@ -6316,19 +6262,19 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.4.27", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.27.tgz", - "integrity": "sha512-xFUYCGRVsfgiN5EjsJJSzih9+yjStgMTCLANPlf0LVQkPDYCe0hz97qbdTZosFOiYlGBlHYityGRxrQ/hxhfVQ==", + "version": "4.4.39", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.39.tgz", + "integrity": "sha512-MCVCxaCzuZgiHtHGV2Ke44nh6t4+8/tO+rTYOzrr2+G4nMLU/qbzNCWKBX54lyEaVcGQrfOJiG2f8imtiw+nIQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/service-error-classification": "^4.2.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-retry": "^4.2.8", - "@smithy/uuid": "^1.1.0", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/service-error-classification": "^4.2.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", + "@smithy/util-middleware": "^4.2.11", + "@smithy/util-retry": "^4.2.11", + "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" }, "engines": { @@ -6336,13 +6282,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", - "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.12.tgz", + "integrity": "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6350,12 +6296,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", - "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.11.tgz", + "integrity": "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6363,14 +6309,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", - "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.11.tgz", + "integrity": "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/shared-ini-file-loader": "^4.4.3", - "@smithy/types": "^4.12.0", + "@smithy/property-provider": "^4.2.11", + "@smithy/shared-ini-file-loader": "^4.4.6", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6378,15 +6324,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.8.tgz", - "integrity": "sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg==", + "version": "4.4.14", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.14.tgz", + "integrity": "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/querystring-builder": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/abort-controller": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/querystring-builder": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6394,12 +6340,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", - "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.11.tgz", + "integrity": "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6407,12 +6353,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", - "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.11.tgz", + "integrity": "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6420,13 +6366,13 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", - "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.11.tgz", + "integrity": "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", - "@smithy/util-uri-escape": "^4.2.0", + "@smithy/types": "^4.13.0", + "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6434,12 +6380,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", - "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.11.tgz", + "integrity": "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6447,24 +6393,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", - "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.11.tgz", + "integrity": "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0" + "@smithy/types": "^4.13.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", - "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.6.tgz", + "integrity": "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6472,36 +6418,136 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.8.tgz", - "integrity": "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.4.tgz", + "integrity": "sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-middleware": "^4.2.8", - "@smithy/util-uri-escape": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/is-array-buffer": "^3.0.0", + "@smithy/protocol-http": "^4.1.8", + "@smithy/types": "^3.7.2", + "@smithy/util-hex-encoding": "^3.0.0", + "@smithy/util-middleware": "^3.0.11", + "@smithy/util-uri-escape": "^3.0.0", + "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/protocol-http": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", + "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/types": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", + "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/util-buffer-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", + "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/util-hex-encoding": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", + "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/util-middleware": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz", + "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^3.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/util-uri-escape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", + "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@smithy/signature-v4/node_modules/@smithy/util-utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", + "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^3.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@smithy/smithy-client": { - "version": "4.10.12", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.12.tgz", - "integrity": "sha512-VKO/HKoQ5OrSHW6AJUmEnUKeXI1/5LfCwO9cwyao7CmLvGnZeM1i36Lyful3LK1XU7HwTVieTqO1y2C/6t3qtA==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.2.tgz", + "integrity": "sha512-HezY3UuG0k4T+4xhFKctLXCA5N2oN+Rtv+mmL8Gt7YmsUY2yhmcLyW75qrSzldfj75IsCW/4UhY3s20KcFnZqA==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.21.1", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-stack": "^4.2.8", - "@smithy/protocol-http": "^5.3.8", - "@smithy/types": "^4.12.0", - "@smithy/util-stream": "^4.5.10", + "@smithy/core": "^3.23.8", + "@smithy/middleware-endpoint": "^4.4.22", + "@smithy/middleware-stack": "^4.2.11", + "@smithy/protocol-http": "^5.3.11", + "@smithy/types": "^4.13.0", + "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" }, "engines": { @@ -6509,9 +6555,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", - "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", + "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6521,13 +6567,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", - "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.11.tgz", + "integrity": "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing==", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/querystring-parser": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6535,13 +6581,26 @@ } }, "node_modules/@smithy/util-base64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", - "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6549,9 +6608,9 @@ } }, "node_modules/@smithy/util-body-length-browser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", - "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6561,9 +6620,9 @@ } }, "node_modules/@smithy/util-body-length-node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", - "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6573,12 +6632,12 @@ } }, "node_modules/@smithy/util-buffer-from": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", - "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.2.0", + "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6586,9 +6645,9 @@ } }, "node_modules/@smithy/util-config-provider": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", - "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6598,14 +6657,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.26", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.26.tgz", - "integrity": "sha512-vva0dzYUTgn7DdE0uaha10uEdAgmdLnNFowKFjpMm6p2R0XDk5FHPX3CBJLzWQkQXuEprsb0hGz9YwbicNWhjw==", + "version": "4.3.38", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.38.tgz", + "integrity": "sha512-c8P1mFLNxcsdAMabB8/VUQUbWzFmgujWi4bAXSggcqLYPc8V4U5abqFqOyn+dK4YT+q8UyCVkTO8807t4t2syA==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", + "@smithy/property-provider": "^4.2.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6613,17 +6672,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.29", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.29.tgz", - "integrity": "sha512-c6D7IUBsZt/aNnTBHMTf+OVh+h/JcxUUgfTcIJaWRe6zhOum1X+pNKSZtZ+7fbOn5I99XVFtmrnXKv8yHHErTQ==", + "version": "4.2.41", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.41.tgz", + "integrity": "sha512-/UG+9MT3UZAR0fLzOtMJMfWGcjjHvgggq924x/CRy8vRbL+yFf3Z6vETlvq8vDH92+31P/1gSOFoo7303wN8WQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.4.6", - "@smithy/credential-provider-imds": "^4.2.8", - "@smithy/node-config-provider": "^4.3.8", - "@smithy/property-provider": "^4.2.8", - "@smithy/smithy-client": "^4.10.12", - "@smithy/types": "^4.12.0", + "@smithy/config-resolver": "^4.4.10", + "@smithy/credential-provider-imds": "^4.2.11", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/property-provider": "^4.2.11", + "@smithy/smithy-client": "^4.12.2", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6631,13 +6690,13 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", - "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.2.tgz", + "integrity": "sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.8", - "@smithy/types": "^4.12.0", + "@smithy/node-config-provider": "^4.3.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6645,9 +6704,9 @@ } }, "node_modules/@smithy/util-hex-encoding": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", - "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6657,12 +6716,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", - "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.11.tgz", + "integrity": "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.12.0", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6670,13 +6729,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", - "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.11.tgz", + "integrity": "sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw==", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/service-error-classification": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6684,18 +6743,31 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.5.10", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.10.tgz", - "integrity": "sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g==", + "version": "4.5.17", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.17.tgz", + "integrity": "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.3.9", - "@smithy/node-http-handler": "^4.4.8", - "@smithy/types": "^4.12.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", + "@smithy/fetch-http-handler": "^5.3.13", + "@smithy/node-http-handler": "^4.4.14", + "@smithy/types": "^4.13.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream/node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" }, "engines": { @@ -6703,9 +6775,9 @@ } }, "node_modules/@smithy/util-uri-escape": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", - "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -6715,26 +6787,51 @@ } }, "node_modules/@smithy/util-utf8": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", - "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", "license": "Apache-2.0", "dependencies": { - "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-utf8/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-utf8/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" } }, "node_modules/@smithy/util-waiter": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.8.tgz", - "integrity": "sha512-n+lahlMWk+aejGuax7DPWtqav8HYnWxQwR+LCG2BgCUmaGcTe9qZCFsmw8TMg9iG75HOwhrJCX9TCJRLH+Yzqg==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.11.tgz", + "integrity": "sha512-x7Rh2azQPs3XxbvCzcttRErKKvLnbZfqRf/gOjw2pb+ZscX88e5UkRPCB67bVnsFHxayvMvmePfKTqsRb+is1A==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.8", - "@smithy/types": "^4.12.0", + "@smithy/abort-controller": "^4.2.11", + "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "engines": { @@ -6742,9 +6839,9 @@ } }, "node_modules/@smithy/uuid": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", - "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -7020,17 +7117,40 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/@tufjs/models/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7121,12 +7241,6 @@ "integrity": "sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg==", "license": "MIT" }, - "node_modules/@types/geojson": { - "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", - "license": "MIT" - }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -7138,9 +7252,9 @@ } }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", "license": "MIT" }, "node_modules/@types/istanbul-lib-coverage": { @@ -7197,12 +7311,6 @@ "@types/node": "*" } }, - "node_modules/@types/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==", - "license": "MIT" - }, "node_modules/@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", @@ -7224,12 +7332,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", - "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "version": "25.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", + "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/node-fetch": { @@ -7252,9 +7360,9 @@ } }, "node_modules/@types/nodemailer": { - "version": "6.4.22", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.22.tgz", - "integrity": "sha512-HV16KRsW7UyZBITE07B62k8PRAKFqRSFXn1T7vslurVjN761tMDBhk5Lbt17ehyTzK6XcyJnAgUpevrvkcVOzw==", + "version": "6.4.23", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.23.tgz", + "integrity": "sha512-aFV3/NsYFLSx9mbb5gtirBSXJnAlrusoKNuPbxsASWc7vrKLmIrTQRpdcxNcSFL3VW2A2XpeLEavwb2qMi6nlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7580,9 +7688,9 @@ } }, "node_modules/@typespec/ts-http-runtime": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", - "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.3.tgz", + "integrity": "sha512-91fp6CAAJSRtH5ja95T1FHSKa8aPW9/Zw6cta81jlZTUw/+Vq8jM/AfF/14h2b71wwR84JUTW/3Y8QPhDAawFA==", "license": "MIT", "dependencies": { "http-proxy-agent": "^7.0.0", @@ -7794,9 +7902,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -7977,6 +8085,15 @@ "node": ">=0.10.0" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -8053,15 +8170,6 @@ "retry": "0.13.1" } }, - "node_modules/async-retry/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -8099,13 +8207,13 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.3.tgz", - "integrity": "sha512-ERT8kdX7DZjtUm7IitEyV7InTHAF42iJuMArIiDIV5YtPanJkgw4hw5Dyg9fh0mihdWNn1GKaeIWErfe56UQ1g==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -8236,24 +8344,36 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.18", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz", - "integrity": "sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/basic-ftp": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.1.0.tgz", - "integrity": "sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", + "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", "license": "MIT", "engines": { "node": ">=10.0.0" } }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", @@ -8389,15 +8509,15 @@ "license": "MIT" }, "node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", + "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", "license": "MIT" }, "node_modules/bowser": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", - "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", "license": "MIT" }, "node_modules/brace-expansion": { @@ -8558,6 +8678,15 @@ "dev": true, "license": "MIT" }, + "node_modules/buildcheck": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.7.tgz", + "integrity": "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==", + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", @@ -8631,28 +8760,51 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/cacache/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/cacache/node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/cacache/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -8660,16 +8812,16 @@ } }, "node_modules/cacache/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8688,27 +8840,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cacache/node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/cacache/node_modules/ssri": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", - "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", "dev": true, "license": "ISC", "dependencies": { @@ -8846,9 +8981,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001766", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", - "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", + "version": "1.0.30001776", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", + "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==", "dev": true, "funding": [ { @@ -9539,6 +9674,20 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/cpu-features": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -9780,9 +9929,9 @@ } }, "node_modules/default-browser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz", - "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", @@ -10104,9 +10253,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.279", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.279.tgz", - "integrity": "sha512-0bblUU5UNdOt5G7XqGiJtpZMONma6WAfq9vsFmtn9x1+joAObr6x1chfqyxFSDCAFwFhCQDrqeAr6MYdpwJ9Hg==", + "version": "1.5.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", + "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", "dev": true, "license": "ISC" }, @@ -10810,10 +10959,22 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/fast-xml-parser": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", - "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", "funding": [ { "type": "github", @@ -10822,7 +10983,8 @@ ], "license": "MIT", "dependencies": { - "strnum": "^2.1.0" + "fast-xml-builder": "^1.0.0", + "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" @@ -10925,9 +11087,9 @@ } }, "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10945,9 +11107,9 @@ } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, "license": "ISC", "dependencies": { @@ -11036,9 +11198,9 @@ "license": "SEE LICENSE IN LICENSE" }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.4.tgz", + "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==", "dev": true, "license": "ISC" }, @@ -11166,9 +11328,9 @@ "license": "MIT" }, "node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { @@ -11451,6 +11613,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", "dev": true, "license": "MIT", "dependencies": { @@ -11493,6 +11656,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", + "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.", "dev": true, "license": "MIT", "dependencies": { @@ -11541,7 +11705,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -11922,6 +12086,23 @@ "node": ">=18.0.0" } }, + "node_modules/googleapis-common/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/googleapis-common/node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -11931,6 +12112,30 @@ "node": ">= 14" } }, + "node_modules/googleapis-common/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/googleapis-common/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/googleapis-common/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -11949,16 +12154,21 @@ "node": ">= 12" } }, + "node_modules/googleapis-common/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, "node_modules/googleapis-common/node_modules/gaxios": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", - "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2", - "rimraf": "^5.0.1" + "node-fetch": "^3.3.2" }, "engines": { "node": ">=18" @@ -11982,6 +12192,7 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -11999,23 +12210,37 @@ } }, "node_modules/googleapis-common/node_modules/google-auth-library": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", - "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.1.tgz", + "integrity": "sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.0.0", - "gcp-metadata": "^8.0.0", - "google-logging-utils": "^1.0.0", - "gtoken": "^8.0.0", + "gaxios": "7.1.3", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", "jws": "^4.0.0" }, "engines": { "node": ">=18" } }, + "node_modules/googleapis-common/node_modules/google-auth-library/node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/googleapis-common/node_modules/google-logging-utils": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", @@ -12025,19 +12250,6 @@ "node": ">=14" } }, - "node_modules/googleapis-common/node_modules/gtoken": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", - "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", - "license": "MIT", - "dependencies": { - "gaxios": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/googleapis-common/node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -12066,13 +12278,19 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/googleapis-common/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/googleapis-common/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -12099,6 +12317,22 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/googleapis-common/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/googleapis-common/node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", @@ -12114,6 +12348,72 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/googleapis-common/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/googleapis-common/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/googleapis-common/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/googleapis/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/googleapis/node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -12123,6 +12423,30 @@ "node": ">= 14" } }, + "node_modules/googleapis/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/googleapis/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/googleapis/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -12141,6 +12465,12 @@ "node": ">= 12" } }, + "node_modules/googleapis/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, "node_modules/googleapis/node_modules/gaxios": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", @@ -12174,6 +12504,7 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -12191,17 +12522,16 @@ } }, "node_modules/googleapis/node_modules/google-auth-library": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", - "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.1.tgz", + "integrity": "sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.0.0", - "gcp-metadata": "^8.0.0", - "google-logging-utils": "^1.0.0", - "gtoken": "^8.0.0", + "gaxios": "7.1.3", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", "jws": "^4.0.0" }, "engines": { @@ -12217,19 +12547,6 @@ "node": ">=14" } }, - "node_modules/googleapis/node_modules/gtoken": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", - "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", - "license": "MIT", - "dependencies": { - "gaxios": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/googleapis/node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -12258,13 +12575,19 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/googleapis/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/googleapis/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -12291,6 +12614,22 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/googleapis/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/googleapis/node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", @@ -12306,6 +12645,55 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/googleapis/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/googleapis/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/googleapis/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -12350,13 +12738,12 @@ "license": "ISC" }, "node_modules/grpc-js-reflection-client": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/grpc-js-reflection-client/-/grpc-js-reflection-client-1.3.3.tgz", - "integrity": "sha512-4OQCk2iZIfhgj3ou9+tKoUP3lDuh0vuN7ZhX1rW8w6SDv2fcam7rQz7zh7zGwQKWrcin1aRrNyPHckeJWjDJZw==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/grpc-js-reflection-client/-/grpc-js-reflection-client-1.3.5.tgz", + "integrity": "sha512-r5wjksqVDjcNzkXGyFsRnTOQKK9ZPmr68Kdq2thLOXNNsiN/4VFqirsVb/9+4b2uKD1ODQjMAMGUTG4aA3yhZQ==", "license": "MIT", "dependencies": { - "@types/lodash": "^4.17.21", - "lodash": "^4.17.21", + "lodash": "^4.17.23", "protobufjs": "^7.5.4" }, "peerDependencies": { @@ -12508,9 +12895,9 @@ } }, "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -12687,17 +13074,40 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/ignore-walk/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/ignore-walk/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -13324,13 +13734,13 @@ } }, "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@isaacs/cliui": "^9.0.0" }, "engines": { "node": "20 || >=22" @@ -13709,9 +14119,9 @@ } }, "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -14105,9 +14515,9 @@ } }, "node_modules/jsdom/node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -14467,16 +14877,16 @@ "license": "MIT" }, "node_modules/lerna": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-9.0.3.tgz", - "integrity": "sha512-wCsJWKX8FaGJoWX2K5gL5q7ReqQNxNsS92AW5glBe/JzWEtoM/jgXXGrEzQzORMb8rTXYFjUjpn60et+i8XugA==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-9.0.5.tgz", + "integrity": "sha512-LtwZu2wINHlKpjRCxrEdK3QopyeUpFuUS4v6uzLYdg/uxnAKqDHrGY/mDPxdxDR3YAXJzpWXBdz49AHNIKZaSg==", "dev": true, "license": "MIT", "dependencies": { - "@lerna/create": "9.0.3", + "@lerna/create": "9.0.5", "@npmcli/arborist": "9.1.6", "@npmcli/package-json": "7.0.2", - "@npmcli/run-script": "10.0.2", + "@npmcli/run-script": "10.0.3", "@nx/devkit": ">=21.5.2 < 23.0.0", "@octokit/plugin-enterprise-rest": "6.0.1", "@octokit/rest": "20.1.2", @@ -14513,7 +14923,7 @@ "load-json-file": "6.2.0", "make-dir": "4.0.0", "make-fetch-happen": "15.0.2", - "minimatch": "3.0.5", + "minimatch": "3.1.4", "multimatch": "5.0.0", "npm-package-arg": "13.0.1", "npm-packlist": "10.0.3", @@ -14529,14 +14939,14 @@ "pify": "5.0.0", "read-cmd-shim": "4.0.0", "resolve-from": "5.0.0", - "rimraf": "^4.4.1", + "rimraf": "^6.1.2", "semver": "7.7.2", "set-blocking": "^2.0.0", "signal-exit": "3.0.7", "slash": "3.0.0", "ssri": "12.0.0", "string-width": "^4.2.3", - "tar": "6.2.1", + "tar": "7.5.8", "temp-dir": "1.0.0", "through": "2.3.8", "tinyglobby": "0.2.12", @@ -14565,6 +14975,16 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/lerna/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/lerna/node_modules/chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -14635,19 +15055,18 @@ } }, "node_modules/lerna/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -14667,26 +15086,29 @@ } }, "node_modules/lerna/node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/lerna/node_modules/glob/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -14769,9 +15191,9 @@ } }, "node_modules/lerna/node_modules/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", "dev": true, "license": "ISC", "dependencies": { @@ -14781,16 +15203,6 @@ "node": "*" } }, - "node_modules/lerna/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, "node_modules/lerna/node_modules/pretty-format": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", @@ -14837,19 +15249,20 @@ } }, "node_modules/lerna/node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^9.2.0" + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" }, "bin": { - "rimraf": "dist/cjs/src/bin.js" + "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -14973,9 +15386,9 @@ } }, "node_modules/libnpmpublish/node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -15222,9 +15635,9 @@ } }, "node_modules/lru.min": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.3.tgz", - "integrity": "sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz", + "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==", "license": "MIT", "engines": { "bun": ">=1.0.0", @@ -15323,28 +15736,29 @@ } }, "node_modules/mariadb": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.4.5.tgz", - "integrity": "sha512-gThTYkhIS5rRqkVr+Y0cIdzr+GRqJ9sA2Q34e0yzmyhMCwyApf3OKAC1jnF23aSlIOqJuyaUFUcj7O1qZslmmQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.5.1.tgz", + "integrity": "sha512-ObKf/e7jU8pmwa5wTs1UwhLMrQYRBDwXPndej2Dv/rvbqsokJYlymubsNtpakVfjI+hd0bG3U6tiuVunDYoLtA==", "license": "LGPL-2.1-or-later", "dependencies": { - "@types/geojson": "^7946.0.16", - "@types/node": "^24.0.13", "denque": "^2.1.0", - "iconv-lite": "^0.6.3", + "iconv-lite": "^0.7.2", "lru-cache": "^10.4.3" }, "engines": { - "node": ">= 14" - } - }, - "node_modules/mariadb/node_modules/@types/node": { - "version": "24.10.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.9.tgz", - "integrity": "sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" + "node": ">= 18" + }, + "peerDependencies": { + "@types/geojson": ">=7946.0.0", + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/geojson": { + "optional": true + }, + "@types/node": { + "optional": true + } } }, "node_modules/mariadb/node_modules/denque": { @@ -15356,18 +15770,6 @@ "node": ">=0.10" } }, - "node_modules/mariadb/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mariadb/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -15621,9 +16023,9 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -15682,9 +16084,9 @@ } }, "node_modules/minio/node_modules/fast-xml-parser": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", - "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.4.tgz", + "integrity": "sha512-jE8ugADnYOBsu1uaoayVl1tVKAMNOXyjwvv2U6udEA2ORBhDooJDWoGxTkhd4Qn4yh59JVVt/pKXtjPwx9OguQ==", "funding": [ { "type": "github", @@ -15693,7 +16095,7 @@ ], "license": "MIT", "dependencies": { - "strnum": "^1.1.1" + "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" @@ -15721,10 +16123,10 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -16033,9 +16435,9 @@ } }, "node_modules/mysql2": { - "version": "3.16.2", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.16.2.tgz", - "integrity": "sha512-JsqBpYNy7pH20lGfPuSyRSIcCxSeAIwxWADpV64nP9KeyN3ZKpHZgjKXuBKsh7dH6FbOvf1bOgoVKjSUPXRMTw==", + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.18.2.tgz", + "integrity": "sha512-UfEShBFAZZEAKjySnTUuE7BgqkYT4mx+RjoJ5aqtmwSSvNcJ/QxQPXz/y3jSxNiVRedPfgccmuBtiPCSiEEytw==", "license": "MIT", "dependencies": { "aws-ssl-profiles": "^1.1.2", @@ -16043,13 +16445,15 @@ "generate-function": "^2.3.1", "iconv-lite": "^0.7.2", "long": "^5.3.2", - "lru.min": "^1.1.3", + "lru.min": "^1.1.4", "named-placeholders": "^1.1.6", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.3" + "sql-escaper": "^1.3.3" }, "engines": { "node": ">= 8.0" + }, + "peerDependencies": { + "@types/node": ">= 8" } }, "node_modules/mysql2/node_modules/denque": { @@ -16247,265 +16651,90 @@ } }, "node_modules/node-gyp": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.5.0.tgz", - "integrity": "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.2.0.tgz", + "integrity": "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==", "dev": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^14.0.3", - "nopt": "^8.0.0", - "proc-log": "^5.0.0", + "make-fetch-happen": "^15.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5", - "tar": "^7.4.3", + "tar": "^7.5.4", "tinyglobby": "^0.2.12", - "which": "^5.0.0" + "which": "^6.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/node-gyp/node_modules/@npmcli/agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", - "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "node_modules/node-gyp/node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", "dev": true, "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/node-gyp/node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/node-gyp/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/node-gyp/node_modules/cacache": { - "version": "19.0.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", - "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^4.0.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^7.0.2", - "ssri": "^12.0.0", - "tar": "^7.4.3", - "unique-filename": "^4.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/node-gyp/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-gyp/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/node-gyp/node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/node-gyp/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/node-gyp/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "engines": { + "node": ">=20" } }, - "node_modules/node-gyp/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/node-gyp/node_modules/make-fetch-happen": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", - "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "node_modules/node-gyp/node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", "dev": true, "license": "ISC", "dependencies": { - "@npmcli/agent": "^3.0.0", - "cacache": "^19.0.1", - "http-cache-semantics": "^4.1.1", - "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^1.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "ssri": "^12.0.0" + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/node-gyp/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/node-gyp/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", "dev": true, "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/node-gyp/node_modules/p-map": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", - "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/node-gyp/node_modules/unique-filename": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", - "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/node-gyp/node_modules/unique-slug": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", - "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/node-gyp/node_modules/which": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/node-int64": { @@ -16522,9 +16751,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "dev": true, "license": "MIT" }, @@ -16793,9 +17022,9 @@ "license": "MIT" }, "node_modules/nx": { - "version": "22.4.2", - "resolved": "https://registry.npmjs.org/nx/-/nx-22.4.2.tgz", - "integrity": "sha512-AlL79ED96d3gG0QtIQ+KXZwZAu/2O8PL/5rcLHxPMoF5Ag31e3krHWoFg3nESJKkFzgOYFilyWHZYPdZc7dSzw==", + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/nx/-/nx-22.5.4.tgz", + "integrity": "sha512-L8wL7uCjnmpyvq4r2mN9s+oriUE4lY+mX9VgOpjj0ucRd5nzaEaBQppVs0zQGkbKC0BnHS8PGtnAglspd5Gh1Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -16805,12 +17034,12 @@ "@yarnpkg/parsers": "3.0.2", "@zkochan/js-yaml": "0.0.7", "axios": "^1.12.0", - "chalk": "^4.1.0", "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^8.0.1", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", + "ejs": "^3.1.7", "enquirer": "~2.3.6", "figures": "3.2.0", "flat": "^5.0.2", @@ -16819,11 +17048,12 @@ "jest-diff": "^30.0.2", "jsonc-parser": "3.2.0", "lines-and-columns": "2.0.3", - "minimatch": "10.1.1", + "minimatch": "10.2.4", "node-machine-id": "1.1.12", "npm-run-path": "^4.0.1", "open": "^8.4.0", "ora": "5.3.0", + "picocolors": "^1.1.0", "resolve.exports": "2.0.3", "semver": "^7.6.3", "string-width": "^4.2.3", @@ -16841,20 +17071,20 @@ "nx-cloud": "bin/nx-cloud.js" }, "optionalDependencies": { - "@nx/nx-darwin-arm64": "22.4.2", - "@nx/nx-darwin-x64": "22.4.2", - "@nx/nx-freebsd-x64": "22.4.2", - "@nx/nx-linux-arm-gnueabihf": "22.4.2", - "@nx/nx-linux-arm64-gnu": "22.4.2", - "@nx/nx-linux-arm64-musl": "22.4.2", - "@nx/nx-linux-x64-gnu": "22.4.2", - "@nx/nx-linux-x64-musl": "22.4.2", - "@nx/nx-win32-arm64-msvc": "22.4.2", - "@nx/nx-win32-x64-msvc": "22.4.2" + "@nx/nx-darwin-arm64": "22.5.4", + "@nx/nx-darwin-x64": "22.5.4", + "@nx/nx-freebsd-x64": "22.5.4", + "@nx/nx-linux-arm-gnueabihf": "22.5.4", + "@nx/nx-linux-arm64-gnu": "22.5.4", + "@nx/nx-linux-arm64-musl": "22.5.4", + "@nx/nx-linux-x64-gnu": "22.5.4", + "@nx/nx-linux-x64-musl": "22.5.4", + "@nx/nx-win32-arm64-msvc": "22.5.4", + "@nx/nx-win32-x64-msvc": "22.5.4" }, "peerDependencies": { - "@swc-node/register": "^1.8.0", - "@swc/core": "^1.3.85" + "@swc-node/register": "^1.11.1", + "@swc/core": "^1.15.8" }, "peerDependenciesMeta": { "@swc-node/register": { @@ -16878,6 +17108,29 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/nx/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/nx/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/nx/node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -16918,16 +17171,16 @@ } }, "node_modules/nx/node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -17522,13 +17775,13 @@ } }, "node_modules/pacote/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/pacote/node_modules/lru-cache": { @@ -17740,26 +17993,31 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, "node_modules/path-type": { "version": "4.0.0", @@ -17772,14 +18030,14 @@ } }, "node_modules/pg": { - "version": "8.17.2", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.17.2.tgz", - "integrity": "sha512-vjbKdiBJRqzcYw1fNU5KuHyYvdJ1qpcQg1CeBrHFqV1pWgHeVR6j/+kX0E1AAXfyuLUGY1ICrN2ELKA/z2HWzw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", "license": "MIT", "dependencies": { - "pg-connection-string": "^2.10.1", - "pg-pool": "^3.11.0", - "pg-protocol": "^1.11.0", + "pg-connection-string": "^2.12.0", + "pg-pool": "^3.13.0", + "pg-protocol": "^1.13.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, @@ -17821,18 +18079,18 @@ } }, "node_modules/pg-pool": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz", - "integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", + "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", - "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", "license": "MIT" }, "node_modules/pg-types": { @@ -17852,9 +18110,9 @@ } }, "node_modules/pg/node_modules/pg-connection-string": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.10.1.tgz", - "integrity": "sha512-iNzslsoeSH2/gmDDKiyMqF64DATUCWj3YJ0wP14kqcsf2TUklwimd+66yYojKwZCA7h2yRNLGug71hCBA2a4sw==", + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", + "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", "license": "MIT" }, "node_modules/pgpass": { @@ -18145,6 +18403,16 @@ "node": ">=10" } }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -18306,9 +18574,9 @@ } }, "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -18362,9 +18630,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -18883,10 +19151,9 @@ } }, "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "license": "MIT", "engines": { "node": ">= 4" @@ -19044,9 +19311,9 @@ "integrity": "sha512-k6knZTDNK8PKKbIqnvxiOveJinuw2LcQjqDoaorZWP9M5AR2EPsnpDeSbeoZZ0pHr5ze1uoaKdK8NBGQrJ34Uw==" }, "node_modules/sax": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", - "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" @@ -19087,9 +19354,9 @@ } }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -19098,11 +19365,6 @@ "node": ">=10" } }, - "node_modules/seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" - }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -19390,9 +19652,9 @@ } }, "node_modules/snowflake-sdk/node_modules/@google-cloud/storage": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.18.0.tgz", - "integrity": "sha512-r3ZwDMiz4nwW6R922Z1pwpePxyRwE5GdevYX63hRmAQUkUQJcBH/79EnQPDv5cOv1mFBgevdNWQfi3tie3dHrQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.19.0.tgz", + "integrity": "sha512-n2FjE7NAOYyshogdc7KQOl/VZb4sneqPjWouSyia9CMDdMhRX5+RIbqalNmC7LOLzuLAN89VlF2HvG8na9G+zQ==", "license": "Apache-2.0", "dependencies": { "@google-cloud/paginator": "^5.0.0", @@ -19401,7 +19663,7 @@ "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "duplexify": "^4.1.3", - "fast-xml-parser": "^4.4.1", + "fast-xml-parser": "^5.3.4", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", "html-entities": "^2.5.2", @@ -19415,6 +19677,42 @@ "node": ">=14" } }, + "node_modules/snowflake-sdk/node_modules/@google-cloud/storage/node_modules/fast-xml-parser": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.2.tgz", + "integrity": "sha512-pw/6pIl4k0CSpElPEJhDppLzaixDEuWui2CUQQBH/ECDf7+y6YwA4Gf7Tyb0Rfe4DIMuZipYj4AEL0nACKglvQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "fast-xml-builder": "^1.0.0", + "strnum": "^2.1.2" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/snowflake-sdk/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/snowflake-sdk/node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -19433,6 +19731,30 @@ "node": ">= 14" } }, + "node_modules/snowflake-sdk/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/snowflake-sdk/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/snowflake-sdk/node_modules/arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -19443,9 +19765,9 @@ } }, "node_modules/snowflake-sdk/node_modules/bn.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", - "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz", + "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==", "license": "MIT" }, "node_modules/snowflake-sdk/node_modules/brace-expansion": { @@ -19457,10 +19779,16 @@ "balanced-match": "^1.0.0" } }, + "node_modules/snowflake-sdk/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, "node_modules/snowflake-sdk/node_modules/fast-xml-parser": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", - "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.4.tgz", + "integrity": "sha512-jE8ugADnYOBsu1uaoayVl1tVKAMNOXyjwvv2U6udEA2ORBhDooJDWoGxTkhd4Qn4yh59JVVt/pKXtjPwx9OguQ==", "funding": [ { "type": "github", @@ -19469,12 +19797,24 @@ ], "license": "MIT", "dependencies": { - "strnum": "^1.1.1" + "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, + "node_modules/snowflake-sdk/node_modules/fast-xml-parser/node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/snowflake-sdk/node_modules/gaxios": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", @@ -19522,6 +19862,7 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -19622,13 +19963,19 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/snowflake-sdk/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/snowflake-sdk/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -19668,6 +20015,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/snowflake-sdk/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/snowflake-sdk/node_modules/retry-request": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", @@ -19682,17 +20045,37 @@ "node": ">=14" } }, - "node_modules/snowflake-sdk/node_modules/strnum": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" + "node_modules/snowflake-sdk/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/snowflake-sdk/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, "node_modules/snowflake-sdk/node_modules/teeny-request": { "version": "9.0.0", @@ -19757,6 +20140,23 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/snowflake-sdk/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/socks": { "version": "2.8.7", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", @@ -19868,9 +20268,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "dev": true, "license": "CC0-1.0" }, @@ -19913,13 +20313,36 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/sqlstring": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", - "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "node_modules/sql-escaper": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/sql-escaper/-/sql-escaper-1.3.3.tgz", + "integrity": "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw==", "license": "MIT", "engines": { - "node": ">= 0.6" + "bun": ">=1.0.0", + "deno": ">=2.0.0", + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/mysqljs/sql-escaper?sponsor=1" + } + }, + "node_modules/ssh2": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", + "integrity": "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==", + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.10", + "nan": "^2.23.0" } }, "node_modules/ssri": { @@ -20130,9 +20553,9 @@ } }, "node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz", + "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==", "funding": [ { "type": "github", @@ -20249,9 +20672,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -20273,9 +20696,9 @@ "license": "MIT" }, "node_modules/tar": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.6.tgz", - "integrity": "sha512-xqUeu2JAIJpXyvskvU3uvQW8PAmHrtXp2KDuMJwQqW8Sqq0CaZBAQ+dKS3RBXVhU4wC5NjAdKrmh84241gO9cA==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.10.tgz", + "integrity": "sha512-8mOPs1//5q/rlkNSPcCegA6hiHJYDmSLEI8aMH/CdSQJNWztHC9WHNam5zdQlfpTwB9Xp7IBEsHfV5LKMJGVAw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -20916,10 +21339,16 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, "node_modules/twilio": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.12.0.tgz", - "integrity": "sha512-ZAKnDKcWvJSb90xQS13QB5KQOeMJPzsRPHxZqju8i5ALg3D4hNwAF9bpytVTxTJV99BL4Rn6Un+ZtXjGeMpjvQ==", + "version": "5.12.2", + "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.12.2.tgz", + "integrity": "sha512-yjTH04Ig0Z3PAxIXhwrto0IJC4Gv7lBDQQ9f4/P9zJhnxVdd+3tENqBMJOtdmmRags3X0jl2IGKEQefCEpJE9g==", "license": "MIT", "dependencies": { "axios": "^1.12.0", @@ -21039,9 +21468,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "license": "MIT" }, "node_modules/unique-filename": { @@ -21702,9 +22131,9 @@ } }, "node_modules/wsl-utils/node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" @@ -22580,6 +23009,7 @@ "knex": "^3.1.0", "react": "^17.0.2", "rimraf": "^3.0.2", + "ssh2": "^1.17.0", "tedious": "^18.2.1" } }, @@ -22591,7 +23021,8 @@ "knex": "^3.1.0", "mysql2": "^3.9.7", "react": "^17.0.2", - "rimraf": "^3.0.2" + "rimraf": "^3.0.2", + "ssh2": "^1.17.0" } }, "packages/n8n": { @@ -22841,2130 +23272,6 @@ "url": "^0.11.0" } }, - "packages/restapi/node_modules/@aws-sdk/core": { - "version": "3.973.13", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.13.tgz", - "integrity": "sha512-eCFiLyBhJR7c/i8hZOETdzj2wsLFzi2L/w9/jajOgwmGqO8xrUExqkTZqdjROkwU62owqeqSuw4sIzlCv1E/ww==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.2", - "@aws-sdk/xml-builder": "^3.972.6", - "@smithy/core": "^3.23.4", - "@smithy/node-config-provider": "^4.3.9", - "@smithy/property-provider": "^4.2.9", - "@smithy/protocol-http": "^5.3.9", - "@smithy/signature-v4": "^5.3.9", - "@smithy/smithy-client": "^4.11.7", - "@smithy/types": "^4.12.1", - "@smithy/util-base64": "^4.3.1", - "@smithy/util-middleware": "^4.2.9", - "@smithy/util-utf8": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/is-array-buffer": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.1.tgz", - "integrity": "sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/signature-v4": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.10.tgz", - "integrity": "sha512-Wab3wW8468WqTKIxI+aZe3JYO52/RYT/8sDOdzkUhjnLakLe9qoQqIcfih/qxcF4qWEFoWBszY0mj5uxffaVXA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.2.1", - "@smithy/protocol-http": "^5.3.10", - "@smithy/types": "^4.13.0", - "@smithy/util-hex-encoding": "^4.2.1", - "@smithy/util-middleware": "^4.2.10", - "@smithy/util-uri-escape": "^4.2.1", - "@smithy/util-utf8": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/util-buffer-from": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.1.tgz", - "integrity": "sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/util-hex-encoding": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.1.tgz", - "integrity": "sha512-c1hHtkgAWmE35/50gmdKajgGAKV3ePJ7t6UtEmpfCWJmQE9BQAQPz0URUVI89eSkcDqCtzqllxzG28IQoZPvwA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/util-middleware": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.10.tgz", - "integrity": "sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/util-uri-escape": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.1.tgz", - "integrity": "sha512-YmiUDn2eo2IOiWYYvGQkgX5ZkBSiTQu4FlDo5jNPpAxng2t6Sjb6WutnZV9l6VR4eJul1ABmCrnWBC9hKHQa6Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/core/node_modules/@smithy/util-utf8": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.1.tgz", - "integrity": "sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.11.tgz", - "integrity": "sha512-hbyoFuVm3qOAGfIPS9t7jCs8GFLFoaOs8ZmYp/chqciuHDyEGv+J365ip7YSvXSrxxUbeW9NyB1hTLt40NBMRg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/types": "^3.973.2", - "@smithy/property-provider": "^4.2.9", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-env/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.13", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.13.tgz", - "integrity": "sha512-a864QxQWFkdCZ5wQF0QZNKTbqAc/DFQNeARp4gOyZZdql5RHjj4CppUSfwAzS9cpw2IPY3eeJjWqLZ1QiDB/6w==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/types": "^3.973.2", - "@smithy/fetch-http-handler": "^5.3.10", - "@smithy/node-http-handler": "^4.4.11", - "@smithy/property-provider": "^4.2.9", - "@smithy/protocol-http": "^5.3.9", - "@smithy/smithy-client": "^4.11.7", - "@smithy/types": "^4.12.1", - "@smithy/util-stream": "^4.5.14", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.11.tgz", - "integrity": "sha512-kvPFn626ABLzxmjFMoqMRtmFKMeiUdWPhwxhmuPu233tqHnNuXzHv0MtrZlkzHd+rwlh9j0zCbQo89B54wIazQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/credential-provider-env": "^3.972.11", - "@aws-sdk/credential-provider-http": "^3.972.13", - "@aws-sdk/credential-provider-login": "^3.972.11", - "@aws-sdk/credential-provider-process": "^3.972.11", - "@aws-sdk/credential-provider-sso": "^3.972.11", - "@aws-sdk/credential-provider-web-identity": "^3.972.11", - "@aws-sdk/nested-clients": "^3.996.1", - "@aws-sdk/types": "^3.973.2", - "@smithy/credential-provider-imds": "^4.2.9", - "@smithy/property-provider": "^4.2.9", - "@smithy/shared-ini-file-loader": "^4.4.4", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.11.tgz", - "integrity": "sha512-stdy09EpBTmsxGiXe1vB5qtXNww9wact36/uWLlSV0/vWbCOUAY2JjhPXoDVLk8n+E6r0M5HeZseLk+iTtifxg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/nested-clients": "^3.996.1", - "@aws-sdk/types": "^3.973.2", - "@smithy/property-provider": "^4.2.9", - "@smithy/protocol-http": "^5.3.9", - "@smithy/shared-ini-file-loader": "^4.4.4", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-login/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-login/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.12", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.12.tgz", - "integrity": "sha512-gMWGnHbNSKWRj+PAiuSg0EDpEwpyIgk0v9U6EuZ1C/5/BUv25Way+E+UFB7r+YYkscuBJMJ+ai8E2K0Q8dx50g==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.11", - "@aws-sdk/credential-provider-http": "^3.972.13", - "@aws-sdk/credential-provider-ini": "^3.972.11", - "@aws-sdk/credential-provider-process": "^3.972.11", - "@aws-sdk/credential-provider-sso": "^3.972.11", - "@aws-sdk/credential-provider-web-identity": "^3.972.11", - "@aws-sdk/types": "^3.973.2", - "@smithy/credential-provider-imds": "^4.2.9", - "@smithy/property-provider": "^4.2.9", - "@smithy/shared-ini-file-loader": "^4.4.4", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.11.tgz", - "integrity": "sha512-B049fvbv41vf0Fs5bCtbzHpruBDp61sPiFDxUmkAJ/zvgSAturpj2rqzV1rj2clg4mb44Uxp9rgpcODexNFlFA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/types": "^3.973.2", - "@smithy/property-provider": "^4.2.9", - "@smithy/shared-ini-file-loader": "^4.4.4", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-process/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.11.tgz", - "integrity": "sha512-vX9z8skN8vPtamVWmSCm4KQohub+1uMuRzIo4urZ2ZUMBAl1bqHatVD/roCb3qRfAyIGvZXCA/AWS03BQRMyCQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/nested-clients": "^3.996.1", - "@aws-sdk/token-providers": "3.997.0", - "@aws-sdk/types": "^3.973.2", - "@smithy/property-provider": "^4.2.9", - "@smithy/shared-ini-file-loader": "^4.4.4", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.11.tgz", - "integrity": "sha512-VR2Ju/QBdOjnWNIYuxRml63eFDLGc6Zl8aDwLi1rzgWo3rLBgtaWhWVBAijhVXzyPdQIOqdL8hvll5ybqumjeQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/nested-clients": "^3.996.1", - "@aws-sdk/types": "^3.973.2", - "@smithy/property-provider": "^4.2.9", - "@smithy/shared-ini-file-loader": "^4.4.4", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/credential-provider-web-identity/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.4.tgz", - "integrity": "sha512-4q2Vg7/zOB10huDBLjzzTwVjBpG22X3J3ief2XrJEgTaANZrNfA3/cGbCVNAibSbu/nIYA7tDk8WCdsIzDDc4Q==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.2", - "@smithy/protocol-http": "^5.3.9", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-host-header/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-host-header/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.4.tgz", - "integrity": "sha512-xFqPvTysuZAHSkdygT+ken/5rzkR7fhOoDPejAJQslZpp0XBepmCJnDOqA57ERtCTBpu8wpjTFI1ETd4S0AXEw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.2", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-logger/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.4.tgz", - "integrity": "sha512-tVbRaayUZ7y2bOb02hC3oEPTqQf2A0HpPDwdMl1qTmye/q8Mq1F1WiIoFkQwG/YQFvbyErYIDMbYzIlxzzLtjQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.2", - "@aws/lambda-invoke-store": "^0.2.2", - "@smithy/protocol-http": "^5.3.9", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-recursion-detection/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-recursion-detection/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.13", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.13.tgz", - "integrity": "sha512-p1kVYbzBxRmhuOHoL/ANJPCedqUxnVgkEjxPoxt5pQv/yzppHM7aBWciYEE9TZY59M421D3GjLfZIZBoEFboVQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/types": "^3.973.2", - "@aws-sdk/util-endpoints": "^3.996.1", - "@smithy/core": "^3.23.4", - "@smithy/protocol-http": "^5.3.9", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-user-agent/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/middleware-user-agent/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/nested-clients": { - "version": "3.996.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.1.tgz", - "integrity": "sha512-XHVLFRGkuV2gh2uwBahCt65ALMb5wMpqplXEZIvFnWOCPlk60B7h7M5J9Em243K8iICDiWY6KhBEqVGfjTqlLA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/middleware-host-header": "^3.972.4", - "@aws-sdk/middleware-logger": "^3.972.4", - "@aws-sdk/middleware-recursion-detection": "^3.972.4", - "@aws-sdk/middleware-user-agent": "^3.972.13", - "@aws-sdk/region-config-resolver": "^3.972.4", - "@aws-sdk/types": "^3.973.2", - "@aws-sdk/util-endpoints": "^3.996.1", - "@aws-sdk/util-user-agent-browser": "^3.972.4", - "@aws-sdk/util-user-agent-node": "^3.972.12", - "@smithy/config-resolver": "^4.4.7", - "@smithy/core": "^3.23.4", - "@smithy/fetch-http-handler": "^5.3.10", - "@smithy/hash-node": "^4.2.9", - "@smithy/invalid-dependency": "^4.2.9", - "@smithy/middleware-content-length": "^4.2.9", - "@smithy/middleware-endpoint": "^4.4.18", - "@smithy/middleware-retry": "^4.4.35", - "@smithy/middleware-serde": "^4.2.10", - "@smithy/middleware-stack": "^4.2.9", - "@smithy/node-config-provider": "^4.3.9", - "@smithy/node-http-handler": "^4.4.11", - "@smithy/protocol-http": "^5.3.9", - "@smithy/smithy-client": "^4.11.7", - "@smithy/types": "^4.12.1", - "@smithy/url-parser": "^4.2.9", - "@smithy/util-base64": "^4.3.1", - "@smithy/util-body-length-browser": "^4.2.1", - "@smithy/util-body-length-node": "^4.2.2", - "@smithy/util-defaults-mode-browser": "^4.3.34", - "@smithy/util-defaults-mode-node": "^4.2.37", - "@smithy/util-endpoints": "^3.2.9", - "@smithy/util-middleware": "^4.2.9", - "@smithy/util-retry": "^4.2.9", - "@smithy/util-utf8": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/is-array-buffer": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.1.tgz", - "integrity": "sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/util-buffer-from": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.1.tgz", - "integrity": "sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/util-middleware": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.10.tgz", - "integrity": "sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/util-utf8": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.1.tgz", - "integrity": "sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.4.tgz", - "integrity": "sha512-3GrJYv5eI65oCKveBZP7Q246dVP+tqeys9aKMB0dfX1glUWfppWlxIu52derqdNb9BX9lxYmeiaBcBIqOAYSgQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.2", - "@smithy/config-resolver": "^4.4.7", - "@smithy/node-config-provider": "^4.3.9", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/region-config-resolver/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/token-providers": { - "version": "3.997.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.997.0.tgz", - "integrity": "sha512-UdG36F7lU9aTqGFRieEyuRUJlgEJBqKeKKekC0esH21DbUSKhPR1kZBah214kYasIaWe1hLJLaqUigoTa5hZAQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.13", - "@aws-sdk/nested-clients": "^3.996.1", - "@aws-sdk/types": "^3.973.2", - "@smithy/property-provider": "^4.2.9", - "@smithy/shared-ini-file-loader": "^4.4.4", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/token-providers/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/types": { - "version": "3.973.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.2.tgz", - "integrity": "sha512-maTZwGsALtnAw4TJr/S6yERAosTwPduu0XhUV+SdbvRZtCOgSgk1ttL2R0XYzvkYSpvbtJocn77tBXq2AKglBw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/types/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/util-endpoints": { - "version": "3.996.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.1.tgz", - "integrity": "sha512-7cJyd+M5i0IoqWkJa1KFx8KNCGIx+Ywu+lT53KpqX7ReVwz03DCKUqvZ/y65vdKwo9w9/HptSAeLDluO5MpGIg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.2", - "@smithy/types": "^4.12.1", - "@smithy/url-parser": "^4.2.9", - "@smithy/util-endpoints": "^3.2.9", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/util-endpoints/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.4.tgz", - "integrity": "sha512-GHb+8XHv6hfLWKQKAKaSOm+vRvogg07s+FWtbR3+eCXXPSFn9XVmiYF4oypAxH7dGIvoxkVG/buHEnzYukyJiA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.973.2", - "@smithy/types": "^4.12.1", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "packages/restapi/node_modules/@aws-sdk/util-user-agent-browser/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.972.12", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.12.tgz", - "integrity": "sha512-c1n3wBK6te+Vd9qU86nF8AsYuiBsxLn0AADGWyFX7vEADr3btaAg5iPQT6GYj6rvzSOEVVisvaAatOWInlJUbQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.13", - "@aws-sdk/types": "^3.973.2", - "@smithy/node-config-provider": "^4.3.9", - "@smithy/types": "^4.12.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } - } - }, - "packages/restapi/node_modules/@aws-sdk/util-user-agent-node/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/xml-builder": { - "version": "3.972.6", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.6.tgz", - "integrity": "sha512-YrXu+UnfC8IdARa4ZkrpcyuRmA/TVgYW6Lcdtvi34NQgRjM1hTirNirN+rGb+s/kNomby8oJiIAu0KNbiZC7PA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.12.1", - "fast-xml-parser": "5.3.6", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "packages/restapi/node_modules/@aws-sdk/xml-builder/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/abort-controller": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.10.tgz", - "integrity": "sha512-qocxM/X4XGATqQtUkbE9SPUB6wekBi+FyJOMbPj0AhvyvFGYEmOlz6VB22iMePCQsFmMIvFSeViDvA7mZJG47g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/abort-controller/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/config-resolver": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.9.tgz", - "integrity": "sha512-ejQvXqlcU30h7liR9fXtj7PIAau1t/sFbJpgWPfiYDs7zd16jpH0IsSXKcba2jF6ChTXvIjACs27kNMc5xxE2Q==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.3.10", - "@smithy/types": "^4.13.0", - "@smithy/util-config-provider": "^4.2.1", - "@smithy/util-endpoints": "^3.3.1", - "@smithy/util-middleware": "^4.2.10", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/config-resolver/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/config-resolver/node_modules/@smithy/util-middleware": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.10.tgz", - "integrity": "sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/core": { - "version": "3.23.6", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.6.tgz", - "integrity": "sha512-4xE+0L2NrsFKpEVFlFELkIHQddBvMbQ41LRIP74dGCXnY1zQ9DgksrBcRBDJT+iOzGy4VEJIeU3hkUK5mn06kg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/middleware-serde": "^4.2.11", - "@smithy/protocol-http": "^5.3.10", - "@smithy/types": "^4.13.0", - "@smithy/util-base64": "^4.3.1", - "@smithy/util-body-length-browser": "^4.2.1", - "@smithy/util-middleware": "^4.2.10", - "@smithy/util-stream": "^4.5.15", - "@smithy/util-utf8": "^4.2.1", - "@smithy/uuid": "^1.1.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/core/node_modules/@smithy/is-array-buffer": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.1.tgz", - "integrity": "sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/core/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/core/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/core/node_modules/@smithy/util-buffer-from": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.1.tgz", - "integrity": "sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/core/node_modules/@smithy/util-middleware": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.10.tgz", - "integrity": "sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/core/node_modules/@smithy/util-utf8": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.1.tgz", - "integrity": "sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/credential-provider-imds": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.10.tgz", - "integrity": "sha512-3bsMLJJLTZGZqVGGeBVFfLzuRulVsGTj12BzRKODTHqUABpIr0jMN1vN3+u6r2OfyhAQ2pXaMZWX/swBK5I6PQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.3.10", - "@smithy/property-provider": "^4.2.10", - "@smithy/types": "^4.13.0", - "@smithy/url-parser": "^4.2.10", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/credential-provider-imds/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/fetch-http-handler": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.11.tgz", - "integrity": "sha512-wbTRjOxdFuyEg0CpumjZO0hkUl+fetJFqxNROepuLIoijQh51aMBmzFLfoQdwRjxsuuS2jizzIUTjPWgd8pd7g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^5.3.10", - "@smithy/querystring-builder": "^4.2.10", - "@smithy/types": "^4.13.0", - "@smithy/util-base64": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/fetch-http-handler/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/hash-node": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.10.tgz", - "integrity": "sha512-1VzIOI5CcsvMDvP3iv1vG/RfLJVVVc67dCRyLSB2Hn9SWCZrDO3zvcIzj3BfEtqRW5kcMg5KAeVf1K3dR6nD3w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "@smithy/util-buffer-from": "^4.2.1", - "@smithy/util-utf8": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/hash-node/node_modules/@smithy/is-array-buffer": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.1.tgz", - "integrity": "sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/hash-node/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/hash-node/node_modules/@smithy/util-buffer-from": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.1.tgz", - "integrity": "sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/hash-node/node_modules/@smithy/util-utf8": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.1.tgz", - "integrity": "sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/invalid-dependency": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.10.tgz", - "integrity": "sha512-vy9KPNSFUU0ajFYk0sDZIYiUlAWGEAhRfehIr5ZkdFrRFTAuXEPUd41USuqHU6vvLX4r6Q9X7MKBco5+Il0Org==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/invalid-dependency/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/is-array-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", - "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-content-length": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.10.tgz", - "integrity": "sha512-TQZ9kX5c6XbjhaEBpvhSvMEZ0klBs1CFtOdPFwATZSbC9UeQfKHPLPN9Y+I6wZGMOavlYTOlHEPDrt42PMSH9w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^5.3.10", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-content-length/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-content-length/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-endpoint": { - "version": "4.4.20", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.20.tgz", - "integrity": "sha512-9W6Np4ceBP3XCYAGLoMCmn8t2RRVzuD1ndWPLBbv7H9CrwM9Bprf6Up6BM9ZA/3alodg0b7Kf6ftBK9R1N04vw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.23.6", - "@smithy/middleware-serde": "^4.2.11", - "@smithy/node-config-provider": "^4.3.10", - "@smithy/shared-ini-file-loader": "^4.4.5", - "@smithy/types": "^4.13.0", - "@smithy/url-parser": "^4.2.10", - "@smithy/util-middleware": "^4.2.10", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-endpoint/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-endpoint/node_modules/@smithy/util-middleware": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.10.tgz", - "integrity": "sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-retry": { - "version": "4.4.37", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.37.tgz", - "integrity": "sha512-/1psZZllBBSQ7+qo5+hhLz7AEPGLx3Z0+e3ramMBEuPK2PfvLK4SrncDB9VegX5mBn+oP/UTDrM6IHrFjvX1ZA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.3.10", - "@smithy/protocol-http": "^5.3.10", - "@smithy/service-error-classification": "^4.2.10", - "@smithy/smithy-client": "^4.12.0", - "@smithy/types": "^4.13.0", - "@smithy/util-middleware": "^4.2.10", - "@smithy/util-retry": "^4.2.10", - "@smithy/uuid": "^1.1.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-retry/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-retry/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-retry/node_modules/@smithy/util-middleware": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.10.tgz", - "integrity": "sha512-LxaQIWLp4y0r72eA8mwPNQ9va4h5KeLM0I3M/HV9klmFaY2kN766wf5vsTzmaOpNNb7GgXAd9a25P3h8T49PSA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-serde": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.11.tgz", - "integrity": "sha512-STQdONGPwbbC7cusL60s7vOa6He6A9w2jWhoapL0mgVjmR19pr26slV+yoSP76SIssMTX/95e5nOZ6UQv6jolg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^5.3.10", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-serde/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-serde/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-stack": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.10.tgz", - "integrity": "sha512-pmts/WovNcE/tlyHa8z/groPeOtqtEpp61q3W0nW1nDJuMq/x+hWa/OVQBtgU0tBqupeXq0VBOLA4UZwE8I0YA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/middleware-stack/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/node-config-provider": { - "version": "4.3.10", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.10.tgz", - "integrity": "sha512-UALRbJtVX34AdP2VECKVlnNgidLHA2A7YgcJzwSBg1hzmnO/bZBHl/LDQQyYifzUwp1UOODnl9JJ3KNawpUJ9w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^4.2.10", - "@smithy/shared-ini-file-loader": "^4.4.5", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/node-config-provider/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/node-http-handler": { - "version": "4.4.12", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.12.tgz", - "integrity": "sha512-zo1+WKJkR9x7ZtMeMDAAsq2PufwiLDmkhcjpWPRRkmeIuOm6nq1qjFICSZbnjBvD09ei8KMo26BWxsu2BUU+5w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/abort-controller": "^4.2.10", - "@smithy/protocol-http": "^5.3.10", - "@smithy/querystring-builder": "^4.2.10", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/node-http-handler/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/node-http-handler/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/property-provider": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.10.tgz", - "integrity": "sha512-5jm60P0CU7tom0eNrZ7YrkgBaoLFXzmqB0wVS+4uK8PPGmosSrLNf6rRd50UBvukztawZ7zyA8TxlrKpF5z9jw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/property-provider/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/protocol-http": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", - "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/querystring-builder": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.10.tgz", - "integrity": "sha512-HeN7kEvuzO2DmAzLukE9UryiUvejD3tMp9a1D1NJETerIfKobBUCLfviP6QEk500166eD2IATaXM59qgUI+YDA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "@smithy/util-uri-escape": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/querystring-builder/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/querystring-builder/node_modules/@smithy/util-uri-escape": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.1.tgz", - "integrity": "sha512-YmiUDn2eo2IOiWYYvGQkgX5ZkBSiTQu4FlDo5jNPpAxng2t6Sjb6WutnZV9l6VR4eJul1ABmCrnWBC9hKHQa6Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/querystring-parser": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.10.tgz", - "integrity": "sha512-4Mh18J26+ao1oX5wXJfWlTT+Q1OpDR8ssiC9PDOuEgVBGloqg18Fw7h5Ct8DyT9NBYwJgtJ2nLjKKFU6RP1G1Q==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/querystring-parser/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/service-error-classification": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.10.tgz", - "integrity": "sha512-0R/+/Il5y8nB/By90o8hy/bWVYptbIfvoTYad0igYQO5RefhNCDmNzqxaMx7K1t/QWo0d6UynqpqN5cCQt1MCg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/service-error-classification/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.5.tgz", - "integrity": "sha512-pHgASxl50rrtOztgQCPmOXFjRW+mCd7ALr/3uXNzRrRoGV5G2+78GOsQ3HlQuBVHCh9o6xqMNvlIKZjWn4Euug==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/shared-ini-file-loader/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/signature-v4": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.4.tgz", - "integrity": "sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "@smithy/protocol-http": "^4.1.8", - "@smithy/types": "^3.7.2", - "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.11", - "@smithy/util-uri-escape": "^3.0.0", - "@smithy/util-utf8": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/smithy-client": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.0.tgz", - "integrity": "sha512-R8bQ9K3lCcXyZmBnQqUZJF4ChZmtWT5NLi6x5kgWx5D+/j0KorXcA0YcFg/X5TOgnTCy1tbKc6z2g2y4amFupQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.23.6", - "@smithy/middleware-endpoint": "^4.4.20", - "@smithy/middleware-stack": "^4.2.10", - "@smithy/protocol-http": "^5.3.10", - "@smithy/types": "^4.13.0", - "@smithy/util-stream": "^4.5.15", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/smithy-client/node_modules/@smithy/protocol-http": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.10.tgz", - "integrity": "sha512-2NzVWpYY0tRdfeCJLsgrR89KE3NTWT2wGulhNUxYlRmtRmPwLQwKzhrfVaiNlA9ZpJvbW7cjTVChYKgnkqXj1A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/smithy-client/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/types": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", - "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/url-parser": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.10.tgz", - "integrity": "sha512-uypjF7fCDsRk26u3qHmFI/ePL7bxxB9vKkE+2WKEciHhz+4QtbzWiHRVNRJwU3cKhrYDYQE3b0MRFtqfLYdA4A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/querystring-parser": "^4.2.10", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/url-parser/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-base64": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.1.tgz", - "integrity": "sha512-BKGuawX4Doq/bI/uEmg+Zyc36rJKWuin3py89PquXBIBqmbnJwBBsmKhdHfNEp0+A4TDgLmT/3MSKZ1SxHcR6w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.2.1", - "@smithy/util-utf8": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-base64/node_modules/@smithy/is-array-buffer": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.1.tgz", - "integrity": "sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-base64/node_modules/@smithy/util-buffer-from": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.1.tgz", - "integrity": "sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-base64/node_modules/@smithy/util-utf8": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.1.tgz", - "integrity": "sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-body-length-browser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.1.tgz", - "integrity": "sha512-SiJeLiozrAoCrgDBUgsVbmqHmMgg/2bA15AzcbcW+zan7SuyAVHN4xTSbq0GlebAIwlcaX32xacnrG488/J/6g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-body-length-node": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.2.tgz", - "integrity": "sha512-4rHqBvxtJEBvsZcFQSPQqXP2b/yy/YlB66KlcEgcH2WNoOKCKB03DSLzXmOsXjbl8dJ4OEYTn31knhdznwk7zw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-buffer-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", - "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-config-provider": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.1.tgz", - "integrity": "sha512-462id/00U8JWFw6qBuTSWfN5TxOHvDu4WliI97qOIOnuC/g+NDAknTU8eoGXEPlLkRVgWEr03jJBLV4o2FL8+A==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.36", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.36.tgz", - "integrity": "sha512-R0smq7EHQXRVMxkAxtH5akJ/FvgAmNF6bUy/GwY/N20T4GrwjT633NFm0VuRpC+8Bbv8R9A0DoJ9OiZL/M3xew==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^4.2.10", - "@smithy/smithy-client": "^4.12.0", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.39", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.39.tgz", - "integrity": "sha512-otWuoDm35btJV1L8MyHrPl462B07QCdMTktKc7/yM+Psv6KbED/ziXiHnmr7yPHUjfIwE9S8Max0LO24Mo3ZVg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/config-resolver": "^4.4.9", - "@smithy/credential-provider-imds": "^4.2.10", - "@smithy/node-config-provider": "^4.3.10", - "@smithy/property-provider": "^4.2.10", - "@smithy/smithy-client": "^4.12.0", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-endpoints": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.3.1.tgz", - "integrity": "sha512-xyctc4klmjmieQiF9I1wssBWleRV0RhJ2DpO8+8yzi2LO1Z+4IWOZNGZGNj4+hq9kdo+nyfrRLmQTzc16Op2Vg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.3.10", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-endpoints/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-hex-encoding": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", - "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-middleware": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz", - "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^3.7.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-retry": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.10.tgz", - "integrity": "sha512-HrBzistfpyE5uqTwiyLsFHscgnwB0kgv8vySp7q5kZ0Eltn/tjosaSGGDj/jJ9ys7pWzIP/icE2d+7vMKXLv7A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^4.2.10", - "@smithy/types": "^4.13.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-retry/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-stream": { - "version": "4.5.15", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.15.tgz", - "integrity": "sha512-OlOKnaqnkU9X+6wEkd7mN+WB7orPbCVDauXOj22Q7VtiTkvy7ZdSsOg4QiNAZMgI4OkvNf+/VLUC3VXkxuWJZw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/fetch-http-handler": "^5.3.11", - "@smithy/node-http-handler": "^4.4.12", - "@smithy/types": "^4.13.0", - "@smithy/util-base64": "^4.3.1", - "@smithy/util-buffer-from": "^4.2.1", - "@smithy/util-hex-encoding": "^4.2.1", - "@smithy/util-utf8": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-stream/node_modules/@smithy/is-array-buffer": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.1.tgz", - "integrity": "sha512-Yfu664Qbf1B4IYIsYgKoABt010daZjkaCRvdU/sPnZG6TtHOB0md0RjNdLGzxe5UIdn9js4ftPICzmkRa9RJ4Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-stream/node_modules/@smithy/types": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz", - "integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-stream/node_modules/@smithy/util-buffer-from": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.1.tgz", - "integrity": "sha512-/swhmt1qTiVkaejlmMPPDgZhEaWb/HWMGRBheaxwuVkusp/z+ErJyQxO6kaXumOciZSWlmq6Z5mNylCd33X7Ig==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-stream/node_modules/@smithy/util-hex-encoding": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.1.tgz", - "integrity": "sha512-c1hHtkgAWmE35/50gmdKajgGAKV3ePJ7t6UtEmpfCWJmQE9BQAQPz0URUVI89eSkcDqCtzqllxzG28IQoZPvwA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-stream/node_modules/@smithy/util-utf8": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.1.tgz", - "integrity": "sha512-DSIwNaWtmzrNQHv8g7DBGR9mulSit65KSj5ymGEIAknmIN8IpbZefEep10LaMG/P/xquwbmJ1h9ectz8z6mV6g==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.2.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-uri-escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", - "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/util-utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", - "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^3.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "packages/restapi/node_modules/@smithy/uuid": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.1.tgz", - "integrity": "sha512-dSfDCeihDmZlV2oyr0yWPTUfh07suS+R5OB+FZGiv/hHyK3hrFBW5rR1UYjfa57vBsrP9lciFkRPzebaV1Qujw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "packages/restapi/node_modules/fast-xml-parser": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.6.tgz", - "integrity": "sha512-QNI3sAvSvaOiaMl8FYU4trnEzCwiRr8XMWgAHzlrWpTSj+QaCSvOf1h82OEP1s4hiAXhnbXSyFWCf4ldZzZRVA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^2.1.2" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "packages/rethinkdb": { "name": "@tooljet-plugins/rethinkdb", "version": "1.0.0", From 10cfb5f98dda9e8b6f1a44b910399241f59bec72 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Thu, 5 Mar 2026 11:52:19 +0530 Subject: [PATCH 18/22] Enhance Dockerfile with nsjail and Redis setup Added installation of nsjail for Python sandboxing and updated Redis configuration. --- docker/pre-release/ee/ee-preview.Dockerfile | 93 +++++++++++++++++++-- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/docker/pre-release/ee/ee-preview.Dockerfile b/docker/pre-release/ee/ee-preview.Dockerfile index c2533f2405..cc5d8f1024 100644 --- a/docker/pre-release/ee/ee-preview.Dockerfile +++ b/docker/pre-release/ee/ee-preview.Dockerfile @@ -2,23 +2,71 @@ FROM node:22.15.1 AS builder # Fix for JS heap limit allocation issue ENV NODE_OPTIONS="--max-old-space-size=4096" -RUN mkdir -p /app +# Build nsjail for Python sandboxing +RUN apt-get update && apt-get install -y --no-install-recommends \ + autoconf \ + bison \ + flex \ + gcc \ + g++ \ + libprotobuf-dev \ + libnl-route-3-dev \ + libtool \ + make \ + pkg-config \ + protobuf-compiler \ + && rm -rf /var/lib/apt/lists/* +WORKDIR /build-nsjail +RUN git clone --depth 1 --branch 3.4 https://github.com/google/nsjail.git && \ + cd nsjail && \ + make && \ + strip nsjail + +# Build Python runtime with pre-installed packages +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 \ + python3-venv \ + python3-pip \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +RUN python3 -m venv /opt/python-runtime + +RUN /opt/python-runtime/bin/pip install --no-cache-dir --upgrade pip setuptools wheel && \ + /opt/python-runtime/bin/pip install --no-cache-dir \ + numpy==1.26.4 \ + pandas==2.2.1 \ + requests==2.31.0 \ + httpx==0.27.0 \ + python-dateutil==2.9.0 \ + pytz==2024.1 \ + pydantic==2.6.4 \ + typing-extensions==4.10.0 + +RUN mkdir -p /app WORKDIR /app -# Set GitHub token and branch as build arguments +# Set GitHub token, branch and repository URL as build arguments ARG CUSTOM_GITHUB_TOKEN ARG BRANCH_NAME +ARG REPO_URL=https://github.com/ToolJet/ToolJet.git # Clone and checkout the frontend repository RUN git config --global url."https://x-access-token:${CUSTOM_GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/" RUN git config --global http.version HTTP/1.1 RUN git config --global http.postBuffer 524288000 -RUN git clone https://github.com/ToolJet/ToolJet.git . +RUN git clone ${REPO_URL} . # The branch name needs to be changed the branch with modularisation in CE repo -RUN git checkout ${BRANCH_NAME} +RUN if git show-ref --verify --quiet refs/heads/${BRANCH_NAME} || \ + git ls-remote --exit-code --heads origin ${BRANCH_NAME}; then \ + git checkout ${BRANCH_NAME}; \ + else \ + echo "Branch ${BRANCH_NAME} not found, falling back to main"; \ + git checkout main; \ + fi # Handle submodules - try normal submodule update first, if it fails clone directly from base repo RUN if git submodule update --init --recursive; then \ @@ -107,7 +155,10 @@ COPY --from=postgrest/postgrest:v12.2.0 /bin/postgrest /bin ENV NODE_ENV=production ENV TOOLJET_EDITION=ee ENV NODE_OPTIONS="--max-old-space-size=4096" -RUN apt-get update && apt-get install -y freetds-dev libaio1 wget supervisor +# Install Redis 7.x from official Redis repository for BullMQ compatibility +RUN curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg \ + && echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb bullseye main" | tee /etc/apt/sources.list.d/redis.list \ + && apt-get update && apt-get install -y freetds-dev libaio1 wget supervisor redis-server libprotobuf23 libnl-route-3-200 python3 python3-pip # Install Instantclient Basic Light Oracle and Dependencies WORKDIR /opt/oracle @@ -121,6 +172,15 @@ RUN wget https://tooljet-plugins-production.s3.us-east-2.amazonaws.com/marketpla # Set the Instant Client library paths ENV LD_LIBRARY_PATH="/opt/oracle/instantclient_11_2:/opt/oracle/instantclient_21_10:${LD_LIBRARY_PATH}" +# Copy nsjail and Python runtime from builder +COPY --from=builder /build-nsjail/nsjail/nsjail /usr/local/bin/nsjail +RUN chmod 755 /usr/local/bin/nsjail + +COPY --from=builder /opt/python-runtime /opt/python-runtime + +# Create nsjail config directory and Python execution temp directory +RUN mkdir -p /etc/nsjail /tmp/python-exec && chmod 1777 /tmp/python-exec + WORKDIR / # copy npm scripts @@ -141,6 +201,8 @@ COPY --from=builder /app/server/node_modules ./app/server/node_modules COPY --from=builder /app/server/templates ./app/server/templates COPY --from=builder /app/server/scripts ./app/server/scripts COPY --from=builder /app/server/dist ./app/server/dist +# Copy nsjail configuration for Python sandboxing +COPY --from=builder /app/server/ee/workflows/nsjail/python-execution.cfg /etc/nsjail/python-execution.cfg WORKDIR /app @@ -166,7 +228,18 @@ RUN rm -rf /var/lib/postgresql/13/main && \ # Initialize PostgreSQL RUN su - postgres -c "/usr/lib/postgresql/13/bin/initdb -D /var/lib/postgresql/13/main" -# Configure Supervisor to manage PostgREST, ToolJet, and Redis +# Configure Redis for BullMQ +RUN mkdir -p /etc/redis /var/lib/redis /var/log/redis && \ + chown -R redis:redis /var/lib/redis /var/log/redis && \ + chmod 755 /var/lib/redis /var/log/redis + +# Copy Redis configuration +COPY ./docker/LTS/ee/redis.conf /etc/redis/redis.conf +RUN chown redis:redis /etc/redis/redis.conf && \ + chmod 644 /etc/redis/redis.conf + +# Configure Supervisor to manage PostgREST and ToolJet +# Note: PostgreSQL and Redis are started directly in preview.sh RUN echo "[supervisord] \n" \ "nodaemon=true \n" \ "user=root \n" \ @@ -175,6 +248,10 @@ RUN echo "[supervisord] \n" \ "command=/bin/postgrest \n" \ "autostart=true \n" \ "autorestart=true \n" \ + "stderr_logfile=/dev/stdout \n" \ + "stderr_logfile_maxbytes=0 \n" \ + "stdout_logfile=/dev/stdout \n" \ + "stdout_logfile_maxbytes=0 \n" \ "\n" \ "[program:tooljet] \n" \ "user=root \n" \ @@ -205,6 +282,10 @@ ENV TOOLJET_HOST=http://localhost \ PGRST_DB_URI=postgres://postgres:postgres@localhost/tooljet_db \ PGRST_JWT_SECRET=r9iMKoe5CRMgvJBBtp4HrqN7QiPpUToj \ PGRST_DB_PRE_CONFIG=postgrest.pre_config \ + REDIS_HOST=localhost \ + REDIS_PORT=6379 \ + REDIS_DB=0 \ + REDIS_TLS_ENABLED=false \ ORM_LOGGING=true \ DEPLOYMENT_PLATFORM=docker:local \ HOME=/home/appuser \ From 663ac486b0a057020ef5294f72edc287da1c361e Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Thu, 5 Mar 2026 11:54:29 +0530 Subject: [PATCH 19/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15439)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/ee | 2 +- server/ee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/ee b/frontend/ee index 36dc07f486..fcf2363dc5 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit 36dc07f486a5fac781fe244a9ac2dbe5b76af2a9 +Subproject commit fcf2363dc5f71e79f8bb0ec7d0cf6cd0626849cc diff --git a/server/ee b/server/ee index 9be6010912..42d32d1c39 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit 9be601091283caaf438a273fffcc4d3e7e7ebad6 +Subproject commit 42d32d1c399e018e69808d9566b7c4f284026966 From 8fb21a6d78cbf9c4e6d88138bb727d57292f6c78 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:02:41 +0530 Subject: [PATCH 20/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15489)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> --- frontend/ee | 2 +- server/ee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/ee b/frontend/ee index fcf2363dc5..16fc80f3d2 160000 --- a/frontend/ee +++ b/frontend/ee @@ -1 +1 @@ -Subproject commit fcf2363dc5f71e79f8bb0ec7d0cf6cd0626849cc +Subproject commit 16fc80f3d2e50307cedcf10133d4c7e1a82752f3 diff --git a/server/ee b/server/ee index 42d32d1c39..d3f416cace 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit 42d32d1c399e018e69808d9566b7c4f284026966 +Subproject commit d3f416caceb62452b46c8db80ae7b48a39874cb2 From 81747fd31f135c040fa9d16185c5370e24995861 Mon Sep 17 00:00:00 2001 From: Sahil Dewangan <123866478+sahil7303@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:11:43 +0530 Subject: [PATCH 21/22] feat: add user metadata update and get endpoints (#15387) * feat: add user metadata update and get endpoints # Conflicts: # server/src/modules/external-apis/dto/index.ts * refactor: parameter names for user metadata endpoints to ensure consistency * fix: address review comments for module imports * feat: update user metadata endpoint to use PUT method, replace the metadata instead of merge --- .../external-apis/Interfaces/IUtilService.ts | 15 +++++++++++++ .../external-apis/constants/feature.ts | 8 +++++++ .../modules/external-apis/constants/index.ts | 2 ++ .../src/modules/external-apis/controller.ts | 21 ++++++++++++++++++- server/src/modules/external-apis/dto/index.ts | 19 ++++++++++++++++- server/src/modules/external-apis/module.ts | 2 ++ .../src/modules/external-apis/types/index.ts | 2 ++ .../src/modules/external-apis/util.service.ts | 19 +++++++++++++++++ .../src/modules/organization-users/module.ts | 2 +- 9 files changed, 87 insertions(+), 3 deletions(-) diff --git a/server/src/modules/external-apis/Interfaces/IUtilService.ts b/server/src/modules/external-apis/Interfaces/IUtilService.ts index 53c1d2cb00..f326b414d0 100644 --- a/server/src/modules/external-apis/Interfaces/IUtilService.ts +++ b/server/src/modules/external-apis/Interfaces/IUtilService.ts @@ -1,5 +1,7 @@ import { ValidateEditUserGroupAdditionObject } from '../types'; import { EntityManager } from 'typeorm'; +import { UserDetailKeyValueDto } from '../dto'; + export interface IExternalApiUtilService { // generates random password by taking length as the input generateRandomPassword(length?: number): string; @@ -7,4 +9,17 @@ export interface IExternalApiUtilService { functionParam: ValidateEditUserGroupAdditionObject, manager?: EntityManager ): Promise; + + updateUserMetadata( + workspaceId: string, + userId: string, + userDetails: UserDetailKeyValueDto[], + manager?: EntityManager + ): Promise; + + getUserMetadata( + workspaceId: string, + userId: string, + manager?: EntityManager + ): Promise; } diff --git a/server/src/modules/external-apis/constants/feature.ts b/server/src/modules/external-apis/constants/feature.ts index bf1be82228..7174af92c7 100644 --- a/server/src/modules/external-apis/constants/feature.ts +++ b/server/src/modules/external-apis/constants/feature.ts @@ -49,6 +49,14 @@ export const FEATURES: FeaturesConfig = { license: LICENSE_FIELD.EXTERNAL_API, isPublic: true, }, + [FEATURE_KEY.UPDATE_USER_METADATA]: { + license: LICENSE_FIELD.EXTERNAL_API, + isPublic: true, + }, + [FEATURE_KEY.GET_USER_METADATA]: { + license: LICENSE_FIELD.EXTERNAL_API, + isPublic: true, + }, [FEATURE_KEY.PULL_NEW_APP]: { license: LICENSE_FIELD.EXTERNAL_API, isPublic: true, diff --git a/server/src/modules/external-apis/constants/index.ts b/server/src/modules/external-apis/constants/index.ts index 2013aee208..3590d675a5 100644 --- a/server/src/modules/external-apis/constants/index.ts +++ b/server/src/modules/external-apis/constants/index.ts @@ -7,6 +7,8 @@ export enum FEATURE_KEY { UPDATE_USER_WORKSPACE = 'UPDATE_USER_WORKSPACE', GET_ALL_WORKSPACES = 'GET_ALL_WORKSPACES', UPDATE_USER_ROLE = 'UPDATE_USER_ROLE', + UPDATE_USER_METADATA = 'UPDATE_USER_METADATA', + GET_USER_METADATA = 'GET_USER_METADATA', PULL_NEW_APP = 'PULL_NEW_APP', PULL_EXISTING_APP = 'PULL_EXISTING_APP', PUSH_APP_VERSION = 'PUSH_APP_VERSION', diff --git a/server/src/modules/external-apis/controller.ts b/server/src/modules/external-apis/controller.ts index 7180ea23fb..93e7d2c72e 100644 --- a/server/src/modules/external-apis/controller.ts +++ b/server/src/modules/external-apis/controller.ts @@ -1,5 +1,5 @@ import { Controller, Get, Param, UseGuards, Body, Patch, Post, Put, NotFoundException } from '@nestjs/common'; -import { UpdateUserDto, WorkspaceDto, UpdateGivenWorkspaceDto, CreateUserDto } from './dto'; +import { UpdateUserDto, WorkspaceDto, UpdateGivenWorkspaceDto, CreateUserDto, UpdateUserMetadataDto } from './dto'; import { IExternalApisController } from './Interfaces/IController'; import { EditUserRoleDto } from '@modules/roles/dto'; import { ExternalApiSecurityGuard } from '@modules/auth/guards/external-api-security.guard'; @@ -53,4 +53,23 @@ export class ExternalApisController implements IExternalApisController { async updateUserRole(@Param('workspaceId') workspaceId: string, @Body() editRoleDto: EditUserRoleDto) { throw new NotFoundException(); } + + @UseGuards(ExternalApiSecurityGuard) + @Put('workspace/:workspaceId/user/:userId') + async updateUserMetadata( + @Param('workspaceId') workspaceId: string, + @Param('userId') userId: string, + @Body() updateUserMetadataDto: UpdateUserMetadataDto + ) { + throw new NotFoundException(); + } + + @UseGuards(ExternalApiSecurityGuard) + @Get('workspace/:workspaceId/user/:userId') + async getUserMetadata( + @Param('workspaceId') workspaceId: string, + @Param('userId') userId: string + ) { + throw new NotFoundException(); + } } diff --git a/server/src/modules/external-apis/dto/index.ts b/server/src/modules/external-apis/dto/index.ts index 25f56ae0e1..855f9bc380 100644 --- a/server/src/modules/external-apis/dto/index.ts +++ b/server/src/modules/external-apis/dto/index.ts @@ -290,6 +290,23 @@ export class ValidatePATSessionDto { accessToken: string; } +export class UserDetailKeyValueDto { + @IsString() + @IsNotEmpty() + key: string; + + @IsString() + @IsNotEmpty() + value: string; +} + +export class UpdateUserMetadataDto { + @IsArray() + @ValidateNested({ each: true }) + @Type(() => UserDetailKeyValueDto) + userDetails: UserDetailKeyValueDto[]; +} + // Export groups DTOs export { CreateGroupExternalDto, @@ -300,4 +317,4 @@ export { DataSourcePermissionsDto, WorkspacePermissionsDto, WorkflowPermissionsDto, -} from './groups.dto'; +} from './groups.dto'; \ No newline at end of file diff --git a/server/src/modules/external-apis/module.ts b/server/src/modules/external-apis/module.ts index ca10a53db4..147b0d058c 100644 --- a/server/src/modules/external-apis/module.ts +++ b/server/src/modules/external-apis/module.ts @@ -20,6 +20,7 @@ import { OrganizationRepository } from '@modules/organizations/repository'; import { SubModule } from '@modules/app/sub-module'; import { AppsRepository } from '@modules/apps/repository'; import { UserRepository } from '@modules/users/repositories/repository'; +import { OrganizationUsersModule } from '@modules/organization-users/module'; export class ExternalApiModule extends SubModule { static async register(configs?: { IS_GET_CONTEXT: boolean }, isMainImport: boolean = false): Promise { @@ -51,6 +52,7 @@ export class ExternalApiModule extends SubModule { await GitSyncModule.register(configs), await AppEnvironmentsModule.register(configs), await SessionModule.register(configs), + await OrganizationUsersModule.register(configs) ], providers: [ ExternalApiUtilService, diff --git a/server/src/modules/external-apis/types/index.ts b/server/src/modules/external-apis/types/index.ts index e5d2229b19..a66db9d810 100644 --- a/server/src/modules/external-apis/types/index.ts +++ b/server/src/modules/external-apis/types/index.ts @@ -14,6 +14,8 @@ interface Features { [FEATURE_KEY.PULL_EXISTING_APP]: FeatureConfig; [FEATURE_KEY.PUSH_APP_VERSION]: FeatureConfig; [FEATURE_KEY.UPDATE_USER_ROLE]: FeatureConfig; + [FEATURE_KEY.UPDATE_USER_METADATA]: FeatureConfig; + [FEATURE_KEY.GET_USER_METADATA]: FeatureConfig; [FEATURE_KEY.CREATE_ORG_GIT]: FeatureConfig; [FEATURE_KEY.AUTO_RELEASE_APP]: FeatureConfig; [FEATURE_KEY.GET_ALL_WORKSPACE_APPS]: FeatureConfig; diff --git a/server/src/modules/external-apis/util.service.ts b/server/src/modules/external-apis/util.service.ts index 7900d664be..aa0847b1ba 100644 --- a/server/src/modules/external-apis/util.service.ts +++ b/server/src/modules/external-apis/util.service.ts @@ -2,6 +2,8 @@ import { Injectable } from '@nestjs/common'; import { IExternalApiUtilService } from './Interfaces/IUtilService'; import { ValidateEditUserGroupAdditionObject } from './types'; import { EntityManager } from 'typeorm'; +import { UserDetailKeyValueDto } from './dto'; + @Injectable() export class ExternalApiUtilService implements IExternalApiUtilService { generateRandomPassword(length?: number): string { @@ -14,4 +16,21 @@ export class ExternalApiUtilService implements IExternalApiUtilService { ): Promise { throw new Error('Method not implemented.'); } + + async updateUserMetadata( + workspaceId: string, + userId: string, + userDetails: UserDetailKeyValueDto[], + manager?: EntityManager + ): Promise { + throw new Error('Method not implemented.'); + } + + async getUserMetadata( + workspaceId: string, + userId: string, + manager?: EntityManager + ): Promise { + throw new Error('Method not implemented.'); + } } diff --git a/server/src/modules/organization-users/module.ts b/server/src/modules/organization-users/module.ts index b56e21499d..9a8b0b66d6 100644 --- a/server/src/modules/organization-users/module.ts +++ b/server/src/modules/organization-users/module.ts @@ -44,7 +44,7 @@ export class OrganizationUsersModule extends SubModule { GroupPermissionsRepository, FeatureAbilityFactory, ], - exports: [OrganizationUsersUtilService], + exports: [OrganizationUsersUtilService, UserDetailsService], }; } } From 6bcc50476d2e958e76e8611c78bf28785002d424 Mon Sep 17 00:00:00 2001 From: Adish M <44204658+adishM98@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:13:46 +0530 Subject: [PATCH 22/22] =?UTF-8?q?=F0=9F=9A=80=20chore:=20update=20submodul?= =?UTF-8?q?es=20to=20latest=20main=20after=20auto-merge=20(#15491)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gsmithun4 <3417097+gsmithun4@users.noreply.github.com> --- server/ee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/ee b/server/ee index d3f416cace..9d25317dba 160000 --- a/server/ee +++ b/server/ee @@ -1 +1 @@ -Subproject commit d3f416caceb62452b46c8db80ae7b48a39874cb2 +Subproject commit 9d25317dba9c6063ff5d65d509c79a8f444ac4fe