From 79da5956b82105e4b2d3ab6a535e85b94ae33a8f Mon Sep 17 00:00:00 2001 From: Dean Date: Mon, 30 Oct 2023 12:46:44 +0000 Subject: [PATCH 001/294] Patch from original environment --- packages/builder/package.json | 2 +- packages/builder/src/api.js | 4 +- .../{builderStore => builder}/dataBinding.js | 32 +- .../schemaGenerator.js | 0 .../createFromScratchScreen.js | 0 .../store/screenTemplates/index.js | 0 .../store/screenTemplates/rowListScreen.js | 0 .../screenTemplates/utils/BaseStructure.js | 0 .../store/screenTemplates/utils/Component.js | 0 .../store/screenTemplates/utils/Screen.js | 5 + .../screenTemplates/utils/commonComponents.js | 0 .../screenTemplates/utils/sanitizeUrl.js | 0 .../src/{builderStore => builder}/utils.js | 0 packages/builder/src/builderStore/index.js | 151 -- .../src/builderStore/store/frontend.js | 1453 ----------------- .../AutomationBuilder.svelte | 2 +- .../FlowChart/ActionModal.svelte | 4 +- .../FlowChart/FlowChart.svelte | 7 +- .../FlowChart/FlowItem.svelte | 2 +- .../FlowChart/FlowItemHeader.svelte | 2 +- .../FlowChart/TestDataModal.svelte | 2 +- .../AutomationBuilder/TestPanel.svelte | 2 +- .../AutomationPanel/AutomationList.svelte | 2 +- .../CreateAutomationModal.svelte | 2 +- .../EditAutomationPopover.svelte | 2 +- .../UpdateAutomationModal.svelte | 2 +- .../SetupPanel/AutomationBlockSetup.svelte | 4 +- .../Shared/CreateWebhookModal.svelte | 2 +- .../backend/DataTable/TableDataTable.svelte | 8 +- .../DataTable/modals/CreateEditColumn.svelte | 2 +- .../DataTable/modals/JSONSchemaModal.svelte | 2 +- .../modals/grid/GridUsersTableButton.svelte | 7 +- .../DatasourceNavigator.svelte | 11 +- .../TableNavigator/TableNavigator.svelte | 5 +- .../popovers/EditTablePopover.svelte | 6 +- .../commandPalette/CommandPalette.svelte | 19 +- .../common/CodeEditor/CodeEditor.svelte | 2 +- .../components/common/CodeMirrorEditor.svelte | 2 +- .../common/bindings/BindableCombobox.svelte | 2 +- .../common/bindings/BindingPanel.svelte | 2 +- .../bindings/DrawerBindableCombobox.svelte | 2 +- .../bindings/DrawerBindableInput.svelte | 13 +- .../common/bindings/DrawerBindableSlot.svelte | 2 +- .../common/bindings/ModalBindableInput.svelte | 2 +- .../src/components/deploy/AppActions.svelte | 45 +- .../CreateWebhookDeploymentModal.svelte | 2 +- .../src/components/deploy/DeleteModal.svelte | 13 +- .../src/components/deploy/RevertModal.svelte | 8 +- .../src/components/deploy/VersionModal.svelte | 29 +- .../design/ScreenDetailsModal.svelte | 6 +- .../ButtonActionDrawer.svelte | 2 +- .../actions/ChangeFormStep.svelte | 6 +- .../actions/ClearForm.svelte | 6 +- .../actions/DuplicateRow.svelte | 10 +- .../actions/ExportData.svelte | 6 +- .../actions/NavigateTo.svelte | 4 +- .../actions/OpenSidePanel.svelte | 4 +- .../actions/RefreshDataProvider.svelte | 6 +- .../actions/S3Upload.svelte | 4 +- .../ButtonActionEditor/actions/SaveRow.svelte | 12 +- .../actions/ScrollTo.svelte | 8 +- .../actions/TriggerAutomation.svelte | 2 +- .../actions/UpdateFieldValue.svelte | 8 +- .../actions/UpdateState.svelte | 2 +- .../actions/ValidateForm.svelte | 6 +- .../controls/ButtonActionEditor/index.js | 4 +- .../settings/controls/ColorPicker.svelte | 4 +- .../controls/ColumnEditor/CellDrawer.svelte | 6 +- .../controls/ColumnEditor/ColumnEditor.svelte | 4 +- .../controls/DataProviderSelect.svelte | 9 +- .../settings/controls/DataSourceSelect.svelte | 6 +- .../EditFieldPopover.svelte | 9 +- .../FieldConfiguration.svelte | 7 +- .../settings/controls/FieldSelect.svelte | 4 +- .../controls/FilterEditor/FilterEditor.svelte | 4 +- .../settings/controls/FormFieldSelect.svelte | 2 +- .../settings/controls/LayoutSelect.svelte | 4 +- .../settings/controls/MultiFieldSelect.svelte | 4 +- .../settings/controls/PropertyControl.svelte | 6 +- .../controls/RelationshipFilterEditor.svelte | 6 +- .../controls/ResetFieldsButton.svelte | 8 +- .../controls/SearchFieldSelect.svelte | 4 +- .../controls/SortableFieldSelect.svelte | 4 +- .../design/settings/controls/URLSelect.svelte | 4 +- .../ValidationEditor/ValidationDrawer.svelte | 6 +- .../integration/QueryBindingBuilder.svelte | 2 +- .../components/integration/QueryEditor.svelte | 2 +- .../QueryViewerBindingBuilder.svelte | 4 +- .../integration/RestQueryViewer.svelte | 2 +- .../portal/licensing/LicensingOverlays.svelte | 3 +- .../portal/licensing/licensingBanners.js | 3 +- .../portal/onboarding/TourPopover.svelte | 21 +- .../portal/onboarding/TourWrap.svelte | 4 +- .../portal/onboarding/tourHandler.js | 10 +- .../src/components/portal/onboarding/tours.js | 10 +- .../src/components/settings/ThemeModal.svelte | 2 +- .../components/start/CreateAppModal.svelte | 9 +- .../components/start/ImportAppModal.svelte | 6 +- packages/builder/src/helpers/formFields.js | 4 +- .../_components/BuilderSidePanel.svelte | 22 +- .../_components/PreviewOverlay.svelte | 21 +- .../builder/app/[application]/_layout.svelte | 53 +- .../automation/[automationId]/_layout.svelte | 2 +- .../[application]/automation/_layout.svelte | 11 +- .../app/[application]/automation/index.svelte | 2 +- .../GoogleButton.svelte | 4 +- .../RestAuthenticationModal.svelte | 5 +- .../_components/panels/Headers.svelte | 2 +- .../_components/panels/Variables/index.svelte | 2 +- .../datasource/[datasourceId]/_layout.svelte | 4 +- .../data/datasource/bb_internal/index.svelte | 4 +- .../index.svelte | 4 +- .../data/query/[queryId]/_layout.svelte | 4 +- .../data/query/[queryId]/index.svelte | 3 +- .../query/new/[datasourceId]/index.svelte | 3 +- .../data/table/[tableId]/_layout.svelte | 4 +- .../data/table/[tableId]/index.svelte | 3 +- .../data/view/v1/[viewName]/_layout.svelte | 4 +- .../data/view/v1/[viewName]/index.svelte | 3 +- .../data/view/v2/[viewId]/_layout.svelte | 4 +- .../Component/ComponentSettingsPanel.svelte | 14 +- .../Component/ComponentSettingsSection.svelte | 9 +- .../Component/ConditionalUIDrawer.svelte | 4 +- .../Component/ConditionalUISection.svelte | 4 +- .../Component/CustomStylesSection.svelte | 8 +- .../_components/Component/StyleSection.svelte | 4 +- .../_components/Navigation/LinksDrawer.svelte | 4 +- .../_components/Navigation/LinksEditor.svelte | 8 +- .../_components/Navigation/index.svelte | 53 +- .../_components/Screen/AppThemeSelect.svelte | 6 +- .../_components/Screen/GeneralPanel.svelte | 14 +- .../_components/Screen/ThemePanel.svelte | 14 +- .../_components/Screen/index.svelte | 62 +- .../[screenId]/[componentId]/_layout.svelte | 20 +- .../new/_components/NewComponentPanel.svelte | 27 +- .../[screenId]/_components/AppPanel.svelte | 8 +- .../[screenId]/_components/AppPreview.svelte | 72 +- .../ComponentDropdownMenu.svelte | 6 +- .../ComponentList/ComponentKeyHandler.svelte | 32 +- .../ComponentList/ComponentTree.svelte | 23 +- .../ScreenslotDropdownMenu.svelte | 10 +- .../_components/ComponentList/dndStore.js | 15 +- .../_components/ComponentList/index.svelte | 27 +- .../_components/DevicePreviewSelect.svelte | 14 +- .../ScreenList/DropdownMenu.svelte | 16 +- .../_components/ScreenList/index.svelte | 8 +- .../design/[screenId]/_layout.svelte | 7 +- .../design/[screenId]/index.svelte | 4 +- .../NewScreen/CreateScreenModal.svelte | 16 +- .../NewScreen/DatasourceModal.svelte | 2 +- .../NewScreen/ScreenRoleModal.svelte | 4 +- .../design/_components/NewScreen/index.svelte | 4 +- .../app/[application]/design/index.svelte | 6 +- .../app/[application]/design/new.svelte | 4 +- .../app/[application]/settings/_layout.svelte | 2 +- .../_components/HistoryDetailsPanel.svelte | 2 +- .../settings/automation-history/index.svelte | 4 +- .../_components/ActionsRenderer.svelte | 2 +- .../settings/backups/index.svelte | 12 +- .../app/[application]/settings/embed.svelte | 4 +- .../settings/exportImport.svelte | 4 +- .../settings/name-and-url.svelte | 24 +- .../app/[application]/settings/version.svelte | 10 +- .../pages/builder/portal/apps/index.svelte | 7 +- .../portal/apps/onboarding/index.svelte | 7 +- .../builder/portal/users/users/index.svelte | 2 +- .../builder/src/stores/backend/database.js | 3 - packages/builder/src/stores/backend/index.js | 43 +- .../builder/src/stores/frontend/BudiStore.js | 27 + packages/builder/src/stores/frontend/app.js | 100 ++ .../frontend/automations.js} | 35 +- .../builder/src/stores/frontend/builder.js | 102 ++ .../src/stores/frontend/components/index.js | 938 +++++++++++ .../frontend/components/utils.js} | 4 +- .../builder/src/stores/frontend/database.js | 17 + .../store => stores/frontend}/deployments.js | 8 +- .../store => stores/frontend}/history.js | 0 packages/builder/src/stores/frontend/index.js | 88 + .../builder/src/stores/frontend/layouts.js | 82 + .../builder/src/stores/frontend/navigation.js | 86 + .../builder/src/stores/frontend/preview.js | 66 + .../builder/src/stores/frontend/screens.js | 517 ++++++ .../src/stores/frontend/tests/app.test.js | 135 ++ .../src/stores/frontend/tests/builder.test.js | 184 +++ .../src/stores/frontend/tests/fixtures.js | 161 ++ .../frontend/tests}/history.test.js | 2 +- .../stores/frontend/tests/navigation.test.js | 244 +++ .../src/stores/frontend/tests/screens.test.js | 803 +++++++++ packages/builder/src/stores/frontend/theme.js | 64 + .../store => stores/frontend}/users.js | 24 +- .../frontend}/websocket.js | 25 +- packages/builder/src/stores/portal/index.js | 2 + .../store => stores/portal}/temporal.js | 4 +- .../store => stores/portal}/theme.js | 3 + packages/builder/vite.config.js | 4 +- .../client/src/components/app/Layout.svelte | 8 +- packages/client/src/sdk.js | 2 + 197 files changed, 4422 insertions(+), 2277 deletions(-) rename packages/builder/src/{builderStore => builder}/dataBinding.js (97%) rename packages/builder/src/{builderStore => builder}/schemaGenerator.js (100%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/createFromScratchScreen.js (100%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/index.js (100%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/rowListScreen.js (100%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/utils/BaseStructure.js (100%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/utils/Component.js (100%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/utils/Screen.js (94%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/utils/commonComponents.js (100%) rename packages/builder/src/{builderStore => builder}/store/screenTemplates/utils/sanitizeUrl.js (100%) rename packages/builder/src/{builderStore => builder}/utils.js (100%) delete mode 100644 packages/builder/src/builderStore/index.js delete mode 100644 packages/builder/src/builderStore/store/frontend.js delete mode 100644 packages/builder/src/stores/backend/database.js create mode 100644 packages/builder/src/stores/frontend/BudiStore.js create mode 100644 packages/builder/src/stores/frontend/app.js rename packages/builder/src/{builderStore/store/automation/index.js => stores/frontend/automations.js} (88%) create mode 100644 packages/builder/src/stores/frontend/builder.js create mode 100644 packages/builder/src/stores/frontend/components/index.js rename packages/builder/src/{builderStore/componentUtils.js => stores/frontend/components/utils.js} (98%) create mode 100644 packages/builder/src/stores/frontend/database.js rename packages/builder/src/{builderStore/store => stores/frontend}/deployments.js (76%) rename packages/builder/src/{builderStore/store => stores/frontend}/history.js (100%) create mode 100644 packages/builder/src/stores/frontend/index.js create mode 100644 packages/builder/src/stores/frontend/layouts.js create mode 100644 packages/builder/src/stores/frontend/navigation.js create mode 100644 packages/builder/src/stores/frontend/preview.js create mode 100644 packages/builder/src/stores/frontend/screens.js create mode 100644 packages/builder/src/stores/frontend/tests/app.test.js create mode 100644 packages/builder/src/stores/frontend/tests/builder.test.js create mode 100644 packages/builder/src/stores/frontend/tests/fixtures.js rename packages/builder/src/{builderStore/store => stores/frontend/tests}/history.test.js (99%) create mode 100644 packages/builder/src/stores/frontend/tests/navigation.test.js create mode 100644 packages/builder/src/stores/frontend/tests/screens.test.js create mode 100644 packages/builder/src/stores/frontend/theme.js rename packages/builder/src/{builderStore/store => stores/frontend}/users.js (56%) rename packages/builder/src/{builderStore => stores/frontend}/websocket.js (83%) rename packages/builder/src/{builderStore/store => stores/portal}/temporal.js (90%) rename packages/builder/src/{builderStore/store => stores/portal}/theme.js (94%) diff --git a/packages/builder/package.json b/packages/builder/package.json index 3cc5612652..679bca2891 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -23,7 +23,7 @@ "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/internals/mocks/fileMock.js", "\\.(css|less|sass|scss)$": "identity-obj-proxy", "components(.*)$": "/src/components$1", - "builderStore(.*)$": "/src/builderStore$1", + "builder(.*)$": "/src/builder$1", "stores(.*)$": "/src/stores$1", "analytics(.*)$": "/src/analytics$1", "constants/backend": "/src/constants/backend/index.js" diff --git a/packages/builder/src/api.js b/packages/builder/src/api.js index 37894d9bbc..df18f4c17a 100644 --- a/packages/builder/src/api.js +++ b/packages/builder/src/api.js @@ -3,14 +3,14 @@ import { CookieUtils, Constants, } from "@budibase/frontend-core" -import { store } from "./builderStore" +import { appStore } from "./stores/frontend" import { get } from "svelte/store" import { auth } from "./stores/portal" export const API = createAPIClient({ attachHeaders: headers => { // Attach app ID header from store - let appId = get(store).appId + let appId = get(appStore).appId if (appId) { headers["x-budibase-app-id"] = appId } diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builder/dataBinding.js similarity index 97% rename from packages/builder/src/builderStore/dataBinding.js rename to packages/builder/src/builder/dataBinding.js index 8445bf9e6d..ca0c51af98 100644 --- a/packages/builder/src/builderStore/dataBinding.js +++ b/packages/builder/src/builder/dataBinding.js @@ -5,8 +5,13 @@ import { findComponent, findComponentPath, getComponentSettings, -} from "./componentUtils" -import { store, currentAsset } from "builderStore" +} from "stores/frontend/components/utils" +import { + currentAsset, + componentStore, + screenStore, + appStore, +} from "stores/frontend" import { queries as queriesStores, tables as tablesStore, @@ -178,7 +183,7 @@ export const getComponentBindableProperties = (asset, componentId) => { // Ensure that the component exists and exposes context const component = findComponent(asset.props, componentId) - const def = store.actions.components.getDefinition(component?._component) + const def = componentStore.getDefinition(component?._component) if (!def?.context) { return [] } @@ -209,7 +214,7 @@ export const getContextProviderComponents = ( // Filter by only data provider components return path.filter(component => { - const def = store.actions.components.getDefinition(component._component) + const def = componentStore.getDefinition(component._component) if (!def?.context) { return false } @@ -240,7 +245,7 @@ export const getActionProviderComponents = (asset, componentId, actionType) => { // Filter by only data provider components return path.filter(component => { - const def = store.actions.components.getDefinition(component._component) + const def = componentStore.getDefinition(component._component) return def?.actions?.includes(actionType) }) } @@ -312,7 +317,7 @@ const getProviderContextBindings = (asset, dataProviders) => { // Create bindings for each data provider let bindings = [] dataProviders.forEach(component => { - const def = store.actions.components.getDefinition(component._component) + const def = componentStore.getDefinition(component._component) const contexts = Array.isArray(def.context) ? def.context : [def.context] // Create bindings for each context block provided by this data provider @@ -502,7 +507,7 @@ export const getUserBindings = () => { */ const getDeviceBindings = () => { let bindings = [] - if (get(store).clientFeatures?.deviceAwareness) { + if (get(appStore).clientFeatures?.deviceAwareness) { const safeDevice = makePropSafe("device") bindings = [ @@ -540,7 +545,7 @@ const getDeviceBindings = () => { */ const getSelectedRowsBindings = asset => { let bindings = [] - if (get(store).clientFeatures?.rowSelection) { + if (get(appStore).clientFeatures?.rowSelection) { // Add bindings for table components let tables = findAllMatchingComponents(asset?.props, component => component._component.endsWith("table") @@ -595,7 +600,7 @@ export const makeStateBinding = key => { */ const getStateBindings = () => { let bindings = [] - if (get(store).clientFeatures?.state) { + if (get(appStore).clientFeatures?.state) { bindings = getAllStateVariables().map(makeStateBinding) } return bindings @@ -671,8 +676,7 @@ export const getEventContextBindings = ({ } const definition = - componentDefinition ?? - store.actions.components.getDefinition(component?._component) + componentDefinition ?? componentStore.getDefinition(component?._component) const settings = getComponentSettings(component?._component) const eventSetting = settings.find(setting => setting.key === settingKey) @@ -1015,7 +1019,7 @@ export const getAllStateVariables = () => { }) // Add on load settings from screens - get(store).screens.forEach(screen => { + get(screenStore).screens.forEach(screen => { if (screen.onLoad) { eventSettings.push(screen.onLoad) } @@ -1044,8 +1048,8 @@ export const getAllStateVariables = () => { export const getAllAssets = () => { // Get all component containing assets let allAssets = [] - allAssets = allAssets.concat(get(store).layouts || []) - allAssets = allAssets.concat(get(store).screens || []) + allAssets = allAssets.concat(get(appStore).layouts || []) + allAssets = allAssets.concat(get(screenStore).screens || []) return allAssets } diff --git a/packages/builder/src/builderStore/schemaGenerator.js b/packages/builder/src/builder/schemaGenerator.js similarity index 100% rename from packages/builder/src/builderStore/schemaGenerator.js rename to packages/builder/src/builder/schemaGenerator.js diff --git a/packages/builder/src/builderStore/store/screenTemplates/createFromScratchScreen.js b/packages/builder/src/builder/store/screenTemplates/createFromScratchScreen.js similarity index 100% rename from packages/builder/src/builderStore/store/screenTemplates/createFromScratchScreen.js rename to packages/builder/src/builder/store/screenTemplates/createFromScratchScreen.js diff --git a/packages/builder/src/builderStore/store/screenTemplates/index.js b/packages/builder/src/builder/store/screenTemplates/index.js similarity index 100% rename from packages/builder/src/builderStore/store/screenTemplates/index.js rename to packages/builder/src/builder/store/screenTemplates/index.js diff --git a/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js b/packages/builder/src/builder/store/screenTemplates/rowListScreen.js similarity index 100% rename from packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js rename to packages/builder/src/builder/store/screenTemplates/rowListScreen.js diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/BaseStructure.js b/packages/builder/src/builder/store/screenTemplates/utils/BaseStructure.js similarity index 100% rename from packages/builder/src/builderStore/store/screenTemplates/utils/BaseStructure.js rename to packages/builder/src/builder/store/screenTemplates/utils/BaseStructure.js diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js b/packages/builder/src/builder/store/screenTemplates/utils/Component.js similarity index 100% rename from packages/builder/src/builderStore/store/screenTemplates/utils/Component.js rename to packages/builder/src/builder/store/screenTemplates/utils/Component.js diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/Screen.js b/packages/builder/src/builder/store/screenTemplates/utils/Screen.js similarity index 94% rename from packages/builder/src/builderStore/store/screenTemplates/utils/Screen.js rename to packages/builder/src/builder/store/screenTemplates/utils/Screen.js index 6fc79e53b0..afe9123b6d 100644 --- a/packages/builder/src/builderStore/store/screenTemplates/utils/Screen.js +++ b/packages/builder/src/builder/store/screenTemplates/utils/Screen.js @@ -33,6 +33,11 @@ export class Screen extends BaseStructure { } } + role(role) { + this._json.routing.roleId = role + return this + } + normalStyle(styling) { this._json.props._styles.normal = styling return this diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/commonComponents.js b/packages/builder/src/builder/store/screenTemplates/utils/commonComponents.js similarity index 100% rename from packages/builder/src/builderStore/store/screenTemplates/utils/commonComponents.js rename to packages/builder/src/builder/store/screenTemplates/utils/commonComponents.js diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/sanitizeUrl.js b/packages/builder/src/builder/store/screenTemplates/utils/sanitizeUrl.js similarity index 100% rename from packages/builder/src/builderStore/store/screenTemplates/utils/sanitizeUrl.js rename to packages/builder/src/builder/store/screenTemplates/utils/sanitizeUrl.js diff --git a/packages/builder/src/builderStore/utils.js b/packages/builder/src/builder/utils.js similarity index 100% rename from packages/builder/src/builderStore/utils.js rename to packages/builder/src/builder/utils.js diff --git a/packages/builder/src/builderStore/index.js b/packages/builder/src/builderStore/index.js deleted file mode 100644 index eecccab7a6..0000000000 --- a/packages/builder/src/builderStore/index.js +++ /dev/null @@ -1,151 +0,0 @@ -import { getFrontendStore } from "./store/frontend" -import { getAutomationStore } from "./store/automation" -import { getTemporalStore } from "./store/temporal" -import { getThemeStore } from "./store/theme" -import { getUserStore } from "./store/users" -import { getDeploymentStore } from "./store/deployments" -import { derived, writable } from "svelte/store" -import { findComponent, findComponentPath } from "./componentUtils" -import { RoleUtils } from "@budibase/frontend-core" -import { createHistoryStore } from "builderStore/store/history" -import { get } from "svelte/store" - -export const store = getFrontendStore() -export const automationStore = getAutomationStore() -export const themeStore = getThemeStore() -export const temporalStore = getTemporalStore() -export const userStore = getUserStore() -export const deploymentStore = getDeploymentStore() - -// Setup history for screens -export const screenHistoryStore = createHistoryStore({ - getDoc: id => get(store).screens?.find(screen => screen._id === id), - selectDoc: store.actions.screens.select, - afterAction: () => { - // Ensure a valid component is selected - if (!get(selectedComponent)) { - store.update(state => ({ - ...state, - selectedComponentId: get(selectedScreen)?.props._id, - })) - } - }, -}) -store.actions.screens.save = screenHistoryStore.wrapSaveDoc( - store.actions.screens.save -) -store.actions.screens.delete = screenHistoryStore.wrapDeleteDoc( - store.actions.screens.delete -) - -// Setup history for automations -export const automationHistoryStore = createHistoryStore({ - getDoc: automationStore.actions.getDefinition, - selectDoc: automationStore.actions.select, -}) -automationStore.actions.save = automationHistoryStore.wrapSaveDoc( - automationStore.actions.save -) -automationStore.actions.delete = automationHistoryStore.wrapDeleteDoc( - automationStore.actions.delete -) - -export const selectedScreen = derived(store, $store => { - return $store.screens.find(screen => screen._id === $store.selectedScreenId) -}) - -export const selectedLayout = derived(store, $store => { - return $store.layouts?.find(layout => layout._id === $store.selectedLayoutId) -}) - -export const selectedComponent = derived( - [store, selectedScreen], - ([$store, $selectedScreen]) => { - if ( - $selectedScreen && - $store.selectedComponentId?.startsWith(`${$selectedScreen._id}-`) - ) { - return $selectedScreen?.props - } - if (!$selectedScreen || !$store.selectedComponentId) { - return null - } - return findComponent($selectedScreen?.props, $store.selectedComponentId) - } -) - -// For legacy compatibility only, but with the new design UI this is just -// the selected screen -export const currentAsset = selectedScreen - -export const sortedScreens = derived(store, $store => { - return $store.screens.slice().sort((a, b) => { - // Sort by role first - const roleA = RoleUtils.getRolePriority(a.routing.roleId) - const roleB = RoleUtils.getRolePriority(b.routing.roleId) - if (roleA !== roleB) { - return roleA > roleB ? -1 : 1 - } - // Then put home screens first - const homeA = !!a.routing.homeScreen - const homeB = !!b.routing.homeScreen - if (homeA !== homeB) { - return homeA ? -1 : 1 - } - // Then sort alphabetically by each URL param - const aParams = a.routing.route.split("/") - const bParams = b.routing.route.split("/") - let minParams = Math.min(aParams.length, bParams.length) - for (let i = 0; i < minParams; i++) { - if (aParams[i] === bParams[i]) { - continue - } - return aParams[i] < bParams[i] ? -1 : 1 - } - // Then sort by the fewest amount of URL params - return aParams.length < bParams.length ? -1 : 1 - }) -}) - -export const selectedComponentPath = derived( - [store, selectedScreen], - ([$store, $selectedScreen]) => { - return findComponentPath( - $selectedScreen?.props, - $store.selectedComponentId - ).map(component => component._id) - } -) - -// Derived automation state -export const selectedAutomation = derived(automationStore, $automationStore => { - if (!$automationStore.selectedAutomationId) { - return null - } - return $automationStore.automations?.find( - x => x._id === $automationStore.selectedAutomationId - ) -}) - -// Derive map of resource IDs to other users. -// We only ever care about a single user in each resource, so if multiple users -// share the same datasource we can just overwrite them. -export const userSelectedResourceMap = derived(userStore, $userStore => { - let map = {} - $userStore.forEach(user => { - const resource = user.builderMetadata?.selectedResourceId - if (resource) { - if (!map[resource]) { - map[resource] = [] - } - map[resource].push(user) - } - }) - return map -}) - -export const isOnlyUser = derived(userStore, $userStore => { - return $userStore.length < 2 -}) - -export const screensHeight = writable("210px") diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js deleted file mode 100644 index a567caf87f..0000000000 --- a/packages/builder/src/builderStore/store/frontend.js +++ /dev/null @@ -1,1453 +0,0 @@ -import { get, writable } from "svelte/store" -import { cloneDeep } from "lodash/fp" -import { - selectedScreen, - selectedComponent, - screenHistoryStore, - automationHistoryStore, -} from "builderStore" -import { - datasources, - integrations, - queries, - database, - tables, -} from "stores/backend" -import { API } from "api" -import analytics, { Events } from "analytics" -import { - findComponentParent, - findClosestMatchingComponent, - findAllMatchingComponents, - findComponent, - getComponentSettings, - makeComponentUnique, - findComponentPath, -} from "../componentUtils" -import { Helpers } from "@budibase/bbui" -import { Utils } from "@budibase/frontend-core" -import { - BUDIBASE_INTERNAL_DB_ID, - DB_TYPE_INTERNAL, - DB_TYPE_EXTERNAL, -} from "constants/backend" -import { - buildFormSchema, - getSchemaForDatasource, -} from "builderStore/dataBinding" -import { makePropSafe as safe } from "@budibase/string-templates" -import { getComponentFieldOptions } from "helpers/formFields" -import { createBuilderWebsocket } from "builderStore/websocket" -import { BuilderSocketEvent } from "@budibase/shared-core" - -const INITIAL_FRONTEND_STATE = { - initialised: false, - apps: [], - name: "", - url: "", - description: "", - layouts: [], - screens: [], - components: [], - clientFeatures: { - spectrumThemes: false, - intelligentLoading: false, - deviceAwareness: false, - state: false, - rowSelection: false, - customThemes: false, - devicePreview: false, - messagePassing: false, - continueIfAction: false, - showNotificationAction: false, - sidePanel: false, - }, - features: { - componentValidation: false, - disableUserMetadata: false, - }, - errors: [], - hasAppPackage: false, - libraries: null, - appId: "", - routes: {}, - clientLibPath: "", - theme: "", - customTheme: {}, - previewDevice: "desktop", - highlightedSettingKey: null, - propertyFocus: null, - builderSidePanel: false, - hasLock: true, - showPreview: false, - - // URL params - selectedScreenId: null, - selectedComponentId: null, - selectedLayoutId: null, - - // Client state - selectedComponentInstance: null, - - // Onboarding - onboarding: false, - tourNodes: null, -} - -export const getFrontendStore = () => { - const store = writable({ ...INITIAL_FRONTEND_STATE }) - let websocket - - // This is a fake implementation of a "patch" API endpoint to try and prevent - // 409s. All screen doc mutations (aside from creation) use this function, - // which queues up invocations sequentially and ensures pending mutations are - // always applied to the most up-to-date doc revision. - // This is slightly better than just a traditional "patch" endpoint and this - // supports deeply mutating the current doc rather than just appending data. - const sequentialScreenPatch = Utils.sequential(async (patchFn, screenId) => { - const state = get(store) - const screen = state.screens.find(screen => screen._id === screenId) - if (!screen) { - return - } - let clone = cloneDeep(screen) - const result = patchFn(clone) - - if (result === false) { - return - } - return await store.actions.screens.save(clone) - }) - - store.actions = { - reset: () => { - store.set({ ...INITIAL_FRONTEND_STATE }) - websocket?.disconnect() - websocket = null - }, - initialise: async pkg => { - const { layouts, screens, application, clientLibPath, hasLock } = pkg - if (!websocket) { - websocket = createBuilderWebsocket(application.appId) - } - await store.actions.components.refreshDefinitions(application.appId) - - // Reset store state - store.update(state => ({ - ...state, - libraries: application.componentLibraries, - name: application.name, - description: application.description, - appId: application.appId, - url: application.url, - layouts: layouts || [], - screens: screens || [], - theme: application.theme || "spectrum--light", - customTheme: application.customTheme, - hasAppPackage: true, - appInstance: application.instance, - clientLibPath, - previousTopNavPath: {}, - version: application.version, - revertableVersion: application.revertableVersion, - upgradableVersion: application.upgradableVersion, - navigation: application.navigation || {}, - usedPlugins: application.usedPlugins || [], - hasLock, - features: { - ...INITIAL_FRONTEND_STATE.features, - ...application.features, - }, - icon: application.icon || {}, - initialised: true, - })) - screenHistoryStore.reset() - automationHistoryStore.reset() - - // Initialise backend stores - database.set(application.instance) - await datasources.init() - await integrations.init() - await queries.init() - await tables.init() - }, - theme: { - save: async theme => { - const appId = get(store).appId - const app = await API.saveAppMetadata({ - appId, - metadata: { theme }, - }) - store.update(state => { - state.theme = app.theme - return state - }) - }, - }, - customTheme: { - save: async customTheme => { - const appId = get(store).appId - const app = await API.saveAppMetadata({ - appId, - metadata: { customTheme }, - }) - store.update(state => { - state.customTheme = app.customTheme - return state - }) - }, - }, - navigation: { - save: async navigation => { - const appId = get(store).appId - const app = await API.saveAppMetadata({ - appId, - metadata: { navigation }, - }) - store.update(state => { - state.navigation = app.navigation - return state - }) - }, - }, - screens: { - select: screenId => { - // Check this screen exists - const state = get(store) - const screen = state.screens.find(screen => screen._id === screenId) - if (!screen) { - return - } - - // Check screen isn't already selected - if (state.selectedScreenId === screen._id) { - return - } - - // Select new screen - store.update(state => { - state.selectedScreenId = screen._id - return state - }) - }, - validate: screen => { - // Recursive function to find any illegal children in component trees - const findIllegalChild = ( - component, - illegalChildren = [], - legalDirectChildren = [] - ) => { - const type = component._component - - if (illegalChildren.includes(type)) { - return type - } - if ( - legalDirectChildren.length && - !legalDirectChildren.includes(type) - ) { - return type - } - if (!component?._children?.length) { - return - } - - if (type === "@budibase/standard-components/sidepanel") { - illegalChildren = [] - } - - const definition = store.actions.components.getDefinition( - component._component - ) - // Reset whitelist for direct children - legalDirectChildren = [] - if (definition?.legalDirectChildren?.length) { - legalDirectChildren = definition.legalDirectChildren.map(x => { - return `@budibase/standard-components/${x}` - }) - } - - // Append blacklisted components and remove duplicates - if (definition?.illegalChildren?.length) { - const blacklist = definition.illegalChildren.map(x => { - return `@budibase/standard-components/${x}` - }) - illegalChildren = [...new Set([...illegalChildren, ...blacklist])] - } - - // Recurse on all children - for (let child of component._children) { - const illegalChild = findIllegalChild( - child, - illegalChildren, - legalDirectChildren - ) - if (illegalChild) { - return illegalChild - } - } - } - - // Validate the entire tree and throw an error if an illegal child is - // found anywhere - const illegalChild = findIllegalChild(screen.props) - if (illegalChild) { - const def = store.actions.components.getDefinition(illegalChild) - throw `You can't place a ${def.name} here` - } - }, - save: async screen => { - const state = get(store) - - // Validate screen structure if the app supports it - if (state.features?.componentValidation) { - store.actions.screens.validate(screen) - } - - // Check screen definition for any component settings which need updated - store.actions.screens.enrichEmptySettings(screen) - - // Save screen - const creatingNewScreen = screen._id === undefined - const savedScreen = await API.saveScreen(screen) - const routesResponse = await API.fetchAppRoutes() - - // If plugins changed we need to fetch the latest app metadata - let usedPlugins = state.usedPlugins - if (savedScreen.pluginAdded) { - const { application } = await API.fetchAppPackage(state.appId) - usedPlugins = application.usedPlugins || [] - } - - // Update state - store.update(state => { - // Update screen object - const idx = state.screens.findIndex(x => x._id === savedScreen._id) - if (idx !== -1) { - state.screens.splice(idx, 1, savedScreen) - } else { - state.screens.push(savedScreen) - } - - // Select the new screen if creating a new one - if (creatingNewScreen) { - state.selectedScreenId = savedScreen._id - state.selectedComponentId = savedScreen.props._id - } - - // Update routes - state.routes = routesResponse.routes - - // Update used plugins - state.usedPlugins = usedPlugins - return state - }) - return savedScreen - }, - patch: async (patchFn, screenId) => { - // Default to the currently selected screen - if (!screenId) { - const state = get(store) - screenId = state.selectedScreenId - } - if (!screenId || !patchFn) { - return - } - return await sequentialScreenPatch(patchFn, screenId) - }, - replace: async (screenId, screen) => { - if (!screenId) { - return - } - if (!screen) { - // Screen deletion - store.update(state => ({ - ...state, - screens: state.screens.filter(x => x._id !== screenId), - })) - } else { - const index = get(store).screens.findIndex(x => x._id === screen._id) - if (index === -1) { - // Screen addition - store.update(state => ({ - ...state, - screens: [...state.screens, screen], - })) - } else { - // Screen update - store.update(state => { - state.screens[index] = screen - return state - }) - } - } - }, - delete: async screens => { - const screensToDelete = Array.isArray(screens) ? screens : [screens] - - // Build array of promises to speed up bulk deletions - let promises = [] - let deleteUrls = [] - screensToDelete.forEach(screen => { - // Delete the screen - promises.push( - API.deleteScreen({ - screenId: screen._id, - screenRev: screen._rev, - }) - ) - // Remove links to this screen - deleteUrls.push(screen.routing.route) - }) - - await Promise.all(promises) - await store.actions.links.delete(deleteUrls) - const deletedIds = screensToDelete.map(screen => screen._id) - const routesResponse = await API.fetchAppRoutes() - store.update(state => { - // Remove deleted screens from state - state.screens = state.screens.filter(screen => { - return !deletedIds.includes(screen._id) - }) - - // Deselect the current screen if it was deleted - if (deletedIds.includes(state.selectedScreenId)) { - state.selectedScreenId = null - state.selectedComponentId = null - } - - // Update routing - state.routes = routesResponse.routes - - return state - }) - return null - }, - updateSetting: async (screen, name, value) => { - if (!screen || !name) { - return - } - - // Apply setting update - const patch = screen => { - if (!screen) { - return false - } - // Skip update if the value is the same - if (Helpers.deepGet(screen, name) === value) { - return false - } - Helpers.deepSet(screen, name, value) - } - await store.actions.screens.patch(patch, screen._id) - - // Ensure we don't have more than one home screen for this new role. - // This could happen after updating multiple different settings. - const state = get(store) - const updatedScreen = state.screens.find(s => s._id === screen._id) - if (!updatedScreen) { - return - } - const otherHomeScreens = state.screens.filter(s => { - return ( - s.routing.roleId === updatedScreen.routing.roleId && - s.routing.homeScreen && - s._id !== screen._id - ) - }) - if (otherHomeScreens.length && updatedScreen.routing.homeScreen) { - const patch = screen => { - screen.routing.homeScreen = false - } - for (let otherHomeScreen of otherHomeScreens) { - await store.actions.screens.patch(patch, otherHomeScreen._id) - } - } - }, - removeCustomLayout: async screen => { - // Pull relevant settings from old layout, if required - const layout = get(store).layouts.find(x => x._id === screen.layoutId) - const patch = screen => { - screen.layoutId = null - screen.showNavigation = layout?.props.navigation !== "None" - screen.width = layout?.props.width || "Large" - } - await store.actions.screens.patch(patch, screen._id) - }, - enrichEmptySettings: screen => { - // Flatten the recursive component tree - const components = findAllMatchingComponents(screen.props, x => x) - - // Iterate over all components and run checks - components.forEach(component => { - store.actions.components.enrichEmptySettings(component, { - screen, - }) - }) - }, - }, - preview: { - setDevice: device => { - store.update(state => { - state.previewDevice = device - return state - }) - }, - sendEvent: (name, payload) => { - const { previewEventHandler } = get(store) - previewEventHandler?.(name, payload) - }, - registerEventHandler: handler => { - store.update(state => { - state.previewEventHandler = handler - return state - }) - }, - }, - layouts: { - select: layoutId => { - // Check this layout exists - const state = get(store) - const layout = state.layouts.find(layout => layout._id === layoutId) - if (!layout) { - return - } - - // Check layout isn't already selected - if ( - state.selectedLayoutId === layout._id && - state.selectedComponentId === layout.props?._id - ) { - return - } - - // Select new layout - store.update(state => { - state.selectedLayoutId = layout._id - state.selectedComponentId = layout.props?._id - return state - }) - }, - delete: async layout => { - if (!layout?._id) { - return - } - await API.deleteLayout({ - layoutId: layout._id, - layoutRev: layout._rev, - }) - store.update(state => { - state.layouts = state.layouts.filter(x => x._id !== layout._id) - return state - }) - }, - }, - components: { - refreshDefinitions: async appId => { - if (!appId) { - appId = get(store).appId - } - - // Fetch definitions and filter out custom component definitions so we - // can flag them - const components = await API.fetchComponentLibDefinitions(appId) - const customComponents = Object.keys(components).filter(name => - name.startsWith("plugin/") - ) - - // Update store - store.update(state => ({ - ...state, - components, - customComponents, - clientFeatures: { - ...INITIAL_FRONTEND_STATE.clientFeatures, - ...components.features, - }, - })) - }, - getDefinition: componentName => { - if (!componentName) { - return null - } - return get(store).components[componentName] - }, - getDefaultDatasource: () => { - // Ignore users table - const validTables = get(tables).list.filter(x => x._id !== "ta_users") - - // Try to use their own internal table first - let table = validTables.find(table => { - return ( - table.sourceId !== BUDIBASE_INTERNAL_DB_ID && - table.type === DB_TYPE_INTERNAL - ) - }) - if (table) { - return table - } - - // Then try sample data - table = validTables.find(table => { - return ( - table.sourceId === BUDIBASE_INTERNAL_DB_ID && - table.type === DB_TYPE_INTERNAL - ) - }) - if (table) { - return table - } - - // Finally try an external table - return validTables.find(table => table.type === DB_TYPE_EXTERNAL) - }, - enrichEmptySettings: (component, opts) => { - if (!component?._component) { - return - } - const defaultDS = store.actions.components.getDefaultDatasource() - const settings = getComponentSettings(component._component) - const { parent, screen, useDefaultValues } = opts || {} - const treeId = parent?._id || component._id - if (!screen) { - return - } - settings.forEach(setting => { - const value = component[setting.key] - - // Fill empty settings - if (value == null || value === "") { - if (setting.type === "multifield" && setting.selectAllFields) { - // Select all schema fields where required - component[setting.key] = Object.keys(defaultDS?.schema || {}) - } else if ( - (setting.type === "dataSource" || setting.type === "table") && - defaultDS - ) { - // Select default datasource where required - component[setting.key] = { - label: defaultDS.name, - tableId: defaultDS._id, - resourceId: defaultDS._id, - type: "table", - } - } else if (setting.type === "dataProvider") { - // Pick closest data provider where required - const path = findComponentPath(screen.props, treeId) - const providers = path.filter(component => - component._component?.endsWith("/dataprovider") - ) - if (providers.length) { - const id = providers[providers.length - 1]?._id - component[setting.key] = `{{ literal ${safe(id)} }}` - } - } else if (setting.type.startsWith("field/")) { - // Autofill form field names - // Get all available field names in this form schema - let fieldOptions = getComponentFieldOptions( - screen.props, - treeId, - setting.type, - false - ) - - // Get all currently used fields - const form = findClosestMatchingComponent( - screen.props, - treeId, - x => x._component === "@budibase/standard-components/form" - ) - const usedFields = Object.keys(buildFormSchema(form) || {}) - - // Filter out already used fields - fieldOptions = fieldOptions.filter(x => !usedFields.includes(x)) - - // Set field name and also assume we have a label setting - if (fieldOptions[0]) { - component[setting.key] = fieldOptions[0] - component.label = fieldOptions[0] - } - } else if (useDefaultValues && setting.defaultValue !== undefined) { - // Use default value where required - component[setting.key] = setting.defaultValue - } - } - - // Validate non-empty settings - else { - if (setting.type === "dataProvider") { - // Validate data provider exists, or else clear it - const treeId = parent?._id || component._id - const path = findComponentPath(screen?.props, treeId) - const providers = path.filter(component => - component._component?.endsWith("/dataprovider") - ) - // Validate non-empty values - const valid = providers?.some(dp => value.includes?.(dp._id)) - if (!valid) { - if (providers.length) { - const id = providers[providers.length - 1]?._id - component[setting.key] = `{{ literal ${safe(id)} }}` - } else { - delete component[setting.key] - } - } - } - } - }) - }, - createInstance: (componentName, presetProps, parent) => { - const definition = store.actions.components.getDefinition(componentName) - if (!definition) { - return null - } - - // Generate basic component structure - let instance = { - _id: Helpers.uuid(), - _component: definition.component, - _styles: { - normal: {}, - hover: {}, - active: {}, - }, - _instanceName: `New ${definition.friendlyName || definition.name}`, - ...presetProps, - } - - // Enrich empty settings - store.actions.components.enrichEmptySettings(instance, { - parent, - screen: get(selectedScreen), - useDefaultValues: true, - }) - - // Add any extra properties the component needs - let extras = {} - if (definition.hasChildren) { - extras._children = [] - } - if (componentName.endsWith("/formstep")) { - const parentForm = findClosestMatchingComponent( - get(selectedScreen).props, - get(selectedComponent)._id, - component => component._component.endsWith("/form") - ) - const formSteps = findAllMatchingComponents(parentForm, component => - component._component.endsWith("/formstep") - ) - extras.step = formSteps.length + 1 - extras._instanceName = `Step ${formSteps.length + 1}` - } - return { - ...cloneDeep(instance), - ...extras, - } - }, - create: async (componentName, presetProps, parent, index) => { - const state = get(store) - const componentInstance = store.actions.components.createInstance( - componentName, - presetProps, - parent - ) - if (!componentInstance) { - return - } - - // Insert in position if specified - if (parent && index != null) { - await store.actions.screens.patch(screen => { - let parentComponent = findComponent(screen.props, parent) - if (!parentComponent._children?.length) { - parentComponent._children = [componentInstance] - } else { - parentComponent._children.splice(index, 0, componentInstance) - } - }) - } - - // Otherwise we work out where this component should be inserted - else { - await store.actions.screens.patch(screen => { - // Find the selected component - let selectedComponentId = state.selectedComponentId - if (selectedComponentId.startsWith(`${screen._id}-`)) { - selectedComponentId = screen?.props._id - } - const currentComponent = findComponent( - screen.props, - selectedComponentId - ) - if (!currentComponent) { - return false - } - - // Find parent node to attach this component to - let parentComponent - if (currentComponent) { - // Use selected component as parent if one is selected - const definition = store.actions.components.getDefinition( - currentComponent._component - ) - if (definition?.hasChildren) { - // Use selected component if it allows children - parentComponent = currentComponent - } else { - // Otherwise we need to use the parent of this component - parentComponent = findComponentParent( - screen.props, - currentComponent._id - ) - } - } else { - // Use screen or layout if no component is selected - parentComponent = screen.props - } - - // Attach new component - if (!parentComponent) { - return false - } - if (!parentComponent._children) { - parentComponent._children = [] - } - parentComponent._children.push(componentInstance) - }) - } - - // Select new component - store.update(state => { - state.selectedComponentId = componentInstance._id - return state - }) - - // Log event - analytics.captureEvent(Events.COMPONENT_CREATED, { - name: componentInstance._component, - }) - - return componentInstance - }, - patch: async (patchFn, componentId, screenId) => { - // Use selected component by default - if (!componentId || !screenId) { - const state = get(store) - componentId = componentId || state.selectedComponentId - screenId = screenId || state.selectedScreenId - } - if (!componentId || !screenId || !patchFn) { - return - } - const patchScreen = screen => { - // findComponent looks in the tree not comp.settings[0] - let component = findComponent(screen.props, componentId) - if (!component) { - return false - } - return patchFn(component, screen) - } - await store.actions.screens.patch(patchScreen, screenId) - }, - delete: async component => { - if (!component) { - return - } - - // Determine the next component to select after deletion - const state = get(store) - let nextSelectedComponentId - if (state.selectedComponentId === component._id) { - nextSelectedComponentId = store.actions.components.getNext() - if (!nextSelectedComponentId) { - nextSelectedComponentId = store.actions.components.getPrevious() - } - } - - // Patch screen - await store.actions.screens.patch(screen => { - // Check component exists - component = findComponent(screen.props, component._id) - if (!component) { - return false - } - - // Check component has a valid parent - const parent = findComponentParent(screen.props, component._id) - if (!parent) { - return false - } - parent._children = parent._children.filter( - child => child._id !== component._id - ) - }) - - // Update selected component if required - if (nextSelectedComponentId) { - store.update(state => { - state.selectedComponentId = nextSelectedComponentId - return state - }) - } - }, - copy: (component, cut = false, selectParent = true) => { - // Update store with copied component - store.update(state => { - state.componentToPaste = cloneDeep(component) - state.componentToPaste.isCut = cut - return state - }) - - // Select the parent if cutting - if (cut && selectParent) { - const screen = get(selectedScreen) - const parent = findComponentParent(screen?.props, component._id) - if (parent) { - store.update(state => { - state.selectedComponentId = parent._id - return state - }) - } - } - }, - paste: async (targetComponent, mode, targetScreen) => { - const state = get(store) - if (!state.componentToPaste) { - return - } - let newComponentId - - // Remove copied component if cutting, regardless if pasting works - let componentToPaste = cloneDeep(state.componentToPaste) - if (componentToPaste.isCut) { - store.update(state => { - delete state.componentToPaste - return state - }) - } - - // Patch screen - const patch = screen => { - // Get up to date ref to target - targetComponent = findComponent(screen.props, targetComponent._id) - if (!targetComponent) { - return false - } - const cut = componentToPaste.isCut - const originalId = componentToPaste._id - delete componentToPaste.isCut - - // Make new component unique if copying - if (!cut) { - componentToPaste = makeComponentUnique(componentToPaste) - } - newComponentId = componentToPaste._id - - // Delete old component if cutting - if (cut) { - const parent = findComponentParent(screen.props, originalId) - if (parent?._children) { - parent._children = parent._children.filter( - component => component._id !== originalId - ) - } - } - - // Check inside is valid - if (mode === "inside") { - const definition = store.actions.components.getDefinition( - targetComponent._component - ) - if (!definition.hasChildren) { - mode = "below" - } - } - - // Paste new component - if (mode === "inside") { - // Paste inside target component if chosen - if (!targetComponent._children) { - targetComponent._children = [] - } - targetComponent._children.push(componentToPaste) - } else { - // Otherwise paste in the correct order in the parent's children - const parent = findComponentParent( - screen.props, - targetComponent._id - ) - if (!parent?._children) { - return false - } - const targetIndex = parent._children.findIndex(component => { - return component._id === targetComponent._id - }) - const index = mode === "above" ? targetIndex : targetIndex + 1 - parent._children.splice(index, 0, componentToPaste) - } - } - const targetScreenId = targetScreen?._id || state.selectedScreenId - await store.actions.screens.patch(patch, targetScreenId) - - // Select the new component - store.update(state => { - state.selectedScreenId = targetScreenId - state.selectedComponentId = newComponentId - return state - }) - }, - getPrevious: () => { - const state = get(store) - const componentId = state.selectedComponentId - const screen = get(selectedScreen) - const parent = findComponentParent(screen.props, componentId) - const index = parent?._children.findIndex(x => x._id === componentId) - - // Check for screen and navigation component edge cases - const screenComponentId = `${screen._id}-screen` - const navComponentId = `${screen._id}-navigation` - if (componentId === screenComponentId) { - return null - } - if (componentId === navComponentId) { - return screenComponentId - } - if (parent._id === screen.props._id && index === 0) { - return navComponentId - } - - // If we have siblings above us, choose the sibling or a descendant - if (index > 0) { - // If sibling before us accepts children, select a descendant - const previousSibling = parent._children[index - 1] - if (previousSibling._children?.length) { - let target = previousSibling - while (target._children?.length) { - target = target._children[target._children.length - 1] - } - return target._id - } - - // Otherwise just select sibling - return previousSibling._id - } - - // If no siblings above us, select the parent - return parent._id - }, - getNext: () => { - const state = get(store) - const component = get(selectedComponent) - const componentId = component?._id - const screen = get(selectedScreen) - const parent = findComponentParent(screen.props, componentId) - const index = parent?._children.findIndex(x => x._id === componentId) - - // Check for screen and navigation component edge cases - const screenComponentId = `${screen._id}-screen` - const navComponentId = `${screen._id}-navigation` - if (state.selectedComponentId === screenComponentId) { - return navComponentId - } - - // If we have children, select first child - if (component._children?.length) { - return component._children[0]._id - } else if (!parent) { - return null - } - - // Otherwise select the next sibling if we have one - if (index < parent._children.length - 1) { - const nextSibling = parent._children[index + 1] - return nextSibling._id - } - - // Last child, select our parents next sibling - let target = parent - let targetParent = findComponentParent(screen.props, target._id) - let targetIndex = targetParent?._children.findIndex( - child => child._id === target._id - ) - while ( - targetParent != null && - targetIndex === targetParent._children?.length - 1 - ) { - target = targetParent - targetParent = findComponentParent(screen.props, target._id) - targetIndex = targetParent?._children.findIndex( - child => child._id === target._id - ) - } - if (targetParent) { - return targetParent._children[targetIndex + 1]._id - } else { - return null - } - }, - selectPrevious: () => { - const previousId = store.actions.components.getPrevious() - if (previousId) { - store.update(state => { - state.selectedComponentId = previousId - return state - }) - } - }, - selectNext: () => { - const nextId = store.actions.components.getNext() - if (nextId) { - store.update(state => { - state.selectedComponentId = nextId - return state - }) - } - }, - moveUp: async component => { - await store.actions.screens.patch(screen => { - const componentId = component?._id - const parent = findComponentParent(screen.props, componentId) - - // Check we aren't right at the top of the tree - const index = parent?._children.findIndex(x => x._id === componentId) - if (!parent || (index === 0 && parent._id === screen.props._id)) { - return - } - - // Copy original component and remove it from the parent - const originalComponent = cloneDeep(parent._children[index]) - parent._children = parent._children.filter( - component => component._id !== componentId - ) - - // If we have siblings above us, move up - if (index > 0) { - // If sibling before us accepts children, move to last child of - // sibling - const previousSibling = parent._children[index - 1] - const definition = store.actions.components.getDefinition( - previousSibling._component - ) - if (definition.hasChildren) { - previousSibling._children.push(originalComponent) - } - - // Otherwise just move component above sibling - else { - parent._children.splice(index - 1, 0, originalComponent) - } - } - - // If no siblings above us, go above the parent as long as it isn't - // the screen - else if (parent._id !== screen.props._id) { - const grandParent = findComponentParent(screen.props, parent._id) - const parentIndex = grandParent._children.findIndex( - child => child._id === parent._id - ) - grandParent._children.splice(parentIndex, 0, originalComponent) - } - }) - }, - moveDown: async component => { - await store.actions.screens.patch(screen => { - const componentId = component?._id - const parent = findComponentParent(screen.props, componentId) - - // Sanity check parent is found - if (!parent?._children?.length) { - return false - } - - // Check we aren't right at the bottom of the tree - const index = parent._children.findIndex(x => x._id === componentId) - if ( - index === parent._children.length - 1 && - parent._id === screen.props._id - ) { - return - } - - // Copy the original component and remove from parent - const originalComponent = cloneDeep(parent._children[index]) - parent._children = parent._children.filter( - component => component._id !== componentId - ) - - // Move below the next sibling if we are not the last sibling - if (index < parent._children.length) { - // If the next sibling has children, become the first child - const nextSibling = parent._children[index] - const definition = store.actions.components.getDefinition( - nextSibling._component - ) - if (definition.hasChildren) { - nextSibling._children.splice(0, 0, originalComponent) - } - - // Otherwise move below next sibling - else { - parent._children.splice(index + 1, 0, originalComponent) - } - } - - // Last child, so move below our parent - else { - const grandParent = findComponentParent(screen.props, parent._id) - const parentIndex = grandParent._children.findIndex( - child => child._id === parent._id - ) - grandParent._children.splice(parentIndex + 1, 0, originalComponent) - } - }) - }, - updateStyle: async (name, value) => { - await store.actions.components.patch(component => { - if (value == null || value === "") { - delete component._styles.normal[name] - } else { - component._styles.normal[name] = value - } - }) - }, - updateStyles: async (styles, id) => { - const patchFn = component => { - component._styles.normal = { - ...component._styles.normal, - ...styles, - } - } - await store.actions.components.patch(patchFn, id) - }, - updateCustomStyle: async style => { - await store.actions.components.patch(component => { - component._styles.custom = style - }) - }, - updateConditions: async conditions => { - await store.actions.components.patch(component => { - component._conditions = conditions - }) - }, - updateSetting: async (name, value) => { - await store.actions.components.patch( - store.actions.components.updateComponentSetting(name, value) - ) - }, - updateComponentSetting: (name, value) => { - return component => { - if (!name || !component) { - return false - } - // Skip update if the value is the same - if (component[name] === value) { - return false - } - - const settings = getComponentSettings(component._component) - const updatedSetting = settings.find(setting => setting.key === name) - - const resetFields = settings.filter( - setting => name === setting.resetOn - ) - resetFields?.forEach(setting => { - component[setting.key] = null - }) - - if ( - updatedSetting?.type === "dataSource" || - updatedSetting?.type === "table" - ) { - const { schema } = getSchemaForDatasource(null, value) - const columnNames = Object.keys(schema || {}) - const multifieldKeysToSelectAll = settings - .filter(setting => { - return setting.type === "multifield" && setting.selectAllFields - }) - .map(setting => setting.key) - - multifieldKeysToSelectAll.forEach(key => { - component[key] = columnNames - }) - } - component[name] = value - } - }, - requestEjectBlock: componentId => { - store.actions.preview.sendEvent("eject-block", componentId) - }, - handleEjectBlock: async (componentId, ejectedDefinition) => { - let nextSelectedComponentId - - await store.actions.screens.patch(screen => { - const block = findComponent(screen.props, componentId) - const parent = findComponentParent(screen.props, componentId) - - // Sanity check - if (!block || !parent?._children?.length) { - return false - } - - // Log event - analytics.captureEvent(Events.BLOCK_EJECTED, { - block: block._component, - }) - - // Attach block children back into ejected definition, using the - // _containsSlot flag to know where to insert them - const slotContainer = findAllMatchingComponents( - ejectedDefinition, - x => x._containsSlot - )[0] - if (slotContainer) { - delete slotContainer._containsSlot - slotContainer._children = [ - ...(slotContainer._children || []), - ...(block._children || []), - ] - } - - // Replace block with ejected definition - ejectedDefinition = makeComponentUnique(ejectedDefinition) - const index = parent._children.findIndex(x => x._id === componentId) - parent._children[index] = ejectedDefinition - nextSelectedComponentId = ejectedDefinition._id - }) - - // Select new root component - if (nextSelectedComponentId) { - store.update(state => { - state.selectedComponentId = nextSelectedComponentId - return state - }) - } - }, - addParent: async (componentId, parentType) => { - if (!componentId || !parentType) { - return - } - - // Create new parent instance - const newParentDefinition = store.actions.components.createInstance( - parentType, - null, - parent - ) - if (!newParentDefinition) { - return - } - - // Replace component with a version wrapped in a new parent - await store.actions.screens.patch(screen => { - // Get this component definition and parent definition - let definition = findComponent(screen.props, componentId) - let oldParentDefinition = findComponentParent( - screen.props, - componentId - ) - if (!definition || !oldParentDefinition) { - return false - } - - // Replace component with parent - const index = oldParentDefinition._children.findIndex( - component => component._id === componentId - ) - if (index === -1) { - return false - } - oldParentDefinition._children[index] = { - ...newParentDefinition, - _children: [definition], - } - }) - - // Select the new parent - store.update(state => { - state.selectedComponentId = newParentDefinition._id - return state - }) - }, - }, - links: { - save: async (url, title) => { - const navigation = get(store).navigation - let links = [...(navigation?.links ?? [])] - - // Skip if we have an identical link - if (links.find(link => link.url === url && link.text === title)) { - return - } - - links.push({ - text: title, - url, - }) - await store.actions.navigation.save({ - ...navigation, - links: [...links], - }) - }, - delete: async urls => { - const navigation = get(store).navigation - let links = navigation?.links - if (!links?.length) { - return - } - - // Filter out the URLs to delete - urls = Array.isArray(urls) ? urls : [urls] - links = links.filter(link => !urls.includes(link.url)) - - await store.actions.navigation.save({ - ...navigation, - links, - }) - }, - }, - settings: { - highlight: key => { - store.update(state => ({ - ...state, - highlightedSettingKey: key, - })) - }, - propertyFocus: key => { - store.update(state => ({ - ...state, - propertyFocus: key, - })) - }, - }, - dnd: { - start: component => { - store.actions.preview.sendEvent("dragging-new-component", { - dragging: true, - component, - }) - }, - stop: () => { - store.actions.preview.sendEvent("dragging-new-component", { - dragging: false, - }) - }, - }, - websocket: { - selectResource: id => { - websocket.emit(BuilderSocketEvent.SelectResource, { - resourceId: id, - }) - }, - }, - metadata: { - replace: metadata => { - store.update(state => ({ - ...state, - ...metadata, - })) - }, - }, - } - - return store -} diff --git a/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte b/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte index b80ba45086..6ca3e65d5d 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/AutomationBuilder.svelte @@ -1,5 +1,5 @@ diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte index 15dd864168..f950d91746 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/ActionModal.svelte @@ -9,11 +9,11 @@ Tags, Tag, } from "@budibase/bbui" - import { automationStore, selectedAutomation } from "builderStore" + import { automationStore, selectedAutomation } from "stores/frontend" import { admin, licensing } from "stores/portal" import { externalActions } from "./ExternalActions" import { TriggerStepID, ActionStepID } from "constants/backend/automations" - import { checkForCollectStep } from "builderStore/utils" + import { checkForCollectStep } from "builder/utils" export let blockIdx export let lastStep diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte index 63a3478ef3..8811306f05 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowChart.svelte @@ -1,5 +1,9 @@ diff --git a/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte b/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte index cce0f4eeab..585445a03a 100644 --- a/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/AutomationList.svelte @@ -4,7 +4,7 @@ automationStore, selectedAutomation, userSelectedResourceMap, - } from "builderStore" + } from "stores/frontend" import NavItem from "components/common/NavItem.svelte" import EditAutomationPopover from "./EditAutomationPopover.svelte" import { notifications } from "@budibase/bbui" diff --git a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte index 647a8081cf..ab53ff66b9 100644 --- a/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte +++ b/packages/builder/src/components/automation/AutomationPanel/CreateAutomationModal.svelte @@ -1,5 +1,5 @@ diff --git a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte index 0cc61c69e6..37bea4fb8c 100644 --- a/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte +++ b/packages/builder/src/components/backend/DatasourceNavigator/DatasourceNavigator.svelte @@ -1,14 +1,7 @@
@@ -66,6 +74,7 @@
{ + builderStore.propertyFocus(key) bindingDrawer.show() }} > @@ -74,7 +83,7 @@ {/if}
0 $: updateAvailable = - $store.upgradableVersion && - $store.version && - $store.upgradableVersion !== $store.version + $appStore.upgradableVersion && + $appStore.version && + $appStore.upgradableVersion !== $appStore.version $: canPublish = !publishing && loaded $: lastDeployed = getLastDeployedString($deploymentStore) const initialiseApp = async () => { - const applicationPkg = await API.fetchAppPackage($store.devId) - await store.actions.initialise(applicationPkg) + const applicationPkg = await API.fetchAppPackage($appStore.devId) + await initialise(applicationPkg) } const getLastDeployedString = deployments => { @@ -66,10 +73,7 @@ } const previewApp = () => { - store.update(state => ({ - ...state, - showPreview: true, - })) + previewStore.showPreview(true) } const viewApp = () => { @@ -87,7 +91,7 @@ async function publishApp() { try { publishing = true - await API.publishAppChanges($store.appId) + await API.publishAppChanges($appStore.appId) notifications.send("App published successfully", { type: "success", icon: "GlobeCheck", @@ -131,7 +135,7 @@ const completePublish = async () => { try { await apps.load() - await deploymentStore.actions.load() + await deploymentStore.load() } catch (err) { notifications.error("Error refreshing app") } @@ -151,7 +155,7 @@
{/if} @@ -161,10 +165,7 @@ quiet icon="UserGroup" on:click={() => { - store.update(state => { - state.builderSidePanel = true - return state - }) + builderStore.showBuilderSidePanel() }} > Users @@ -232,7 +233,7 @@ } }} > - {$store.url} + {$appStore.url} {#if isPublished} {:else} @@ -313,10 +314,10 @@ { await initialiseApp() diff --git a/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte b/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte index ee6b163a3e..3ea5d1bc81 100644 --- a/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte +++ b/packages/builder/src/components/deploy/CreateWebhookDeploymentModal.svelte @@ -1,5 +1,5 @@ diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DuplicateRow.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DuplicateRow.svelte index 18711497ff..7146fa5d7f 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DuplicateRow.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/DuplicateRow.svelte @@ -1,11 +1,11 @@ diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/S3Upload.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/S3Upload.svelte index 2e374f165f..0768c93843 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/S3Upload.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/S3Upload.svelte @@ -1,7 +1,7 @@ diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte index 971a5ede44..46bf0361fa 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/TriggerAutomation.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/index.js b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/index.js index ea6cc4ed37..0c86a4f58e 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/index.js +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/index.js @@ -1,6 +1,6 @@ import * as ActionComponents from "./actions" import { get } from "svelte/store" -import { store } from "builderStore" +import { appStore } from "stores/frontend" // @ts-ignore import ActionDefinitions from "./manifest.json" @@ -18,7 +18,7 @@ export const getAvailableActions = (getAllActions = false) => { if (getAllActions || !action.dependsOnFeature) { return true } - return get(store).clientFeatures?.[action.dependsOnFeature] === true + return get(appStore).clientFeatures?.[action.dependsOnFeature] === true }) .map(action => { // Then enrich the actions with real components diff --git a/packages/builder/src/components/design/settings/controls/ColorPicker.svelte b/packages/builder/src/components/design/settings/controls/ColorPicker.svelte index 5f9fcaf21a..39adb44a4d 100644 --- a/packages/builder/src/components/design/settings/controls/ColorPicker.svelte +++ b/packages/builder/src/components/design/settings/controls/ColorPicker.svelte @@ -1,8 +1,8 @@ - + diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte index 8e3079101a..d2e51156e1 100644 --- a/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/CellDrawer.svelte @@ -7,7 +7,7 @@ Layout, Label, } from "@budibase/bbui" - import { store } from "builderStore" + import { themeStore } from "stores/frontend" import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" export let column @@ -42,7 +42,7 @@ (column.background = e.detail)} - spectrumTheme={$store.theme} + spectrumTheme={$themeStore.theme} /> @@ -50,7 +50,7 @@ (column.color = e.detail)} - spectrumTheme={$store.theme} + spectrumTheme={$themeStore.theme} /> diff --git a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte index cebb429ac4..42b7dc2b4b 100644 --- a/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/ColumnEditor/ColumnEditor.svelte @@ -6,8 +6,8 @@ import { getDatasourceForProvider, getSchemaForDatasource, - } from "builderStore/dataBinding" - import { currentAsset } from "builderStore" + } from "builder/dataBinding" + import { currentAsset } from "stores/frontend" import { getFields } from "helpers/searchFields" export let componentInstance diff --git a/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte b/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte index 83255ec325..422199a1e0 100644 --- a/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataProviderSelect.svelte @@ -1,14 +1,17 @@ diff --git a/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte b/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte index 29f32aa345..73acc18dcf 100644 --- a/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte @@ -3,7 +3,7 @@ getContextProviderComponents, readableToRuntimeBinding, runtimeToReadableBinding, - } from "builderStore/dataBinding" + } from "builder/dataBinding" import { Button, Popover, @@ -20,7 +20,7 @@ notifications, } from "@budibase/bbui" import { createEventDispatcher } from "svelte" - import { store, currentAsset } from "builderStore" + import { currentAsset, componentStore } from "stores/frontend" import { tables as tablesStore, queries as queriesStore, @@ -77,7 +77,7 @@ })) $: contextProviders = getContextProviderComponents( $currentAsset, - $store.selectedComponentId + $componentStore.selectedComponentId ) $: dataProviders = contextProviders .filter(component => component._component?.endsWith("/dataprovider")) diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte index 7d2eaae478..0845df1391 100644 --- a/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/EditFieldPopover.svelte @@ -1,6 +1,6 @@ diff --git a/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte b/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte index 0010a22d15..53f20ec482 100644 --- a/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/RelationshipFilterEditor.svelte @@ -1,10 +1,10 @@ diff --git a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte index 0bff2ccce6..58b307c007 100644 --- a/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ValidationEditor/ValidationDrawer.svelte @@ -10,9 +10,9 @@ Input, DatePicker, } from "@budibase/bbui" - import { currentAsset, selectedComponent } from "builderStore" - import { findClosestMatchingComponent } from "builderStore/componentUtils" - import { getSchemaForDatasource } from "builderStore/dataBinding" + import { currentAsset, selectedComponent } from "stores/frontend" + import { findClosestMatchingComponent } from "stores/frontend/components/utils" + import { getSchemaForDatasource } from "builder/dataBinding" import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" import { generate } from "shortid" diff --git a/packages/builder/src/components/integration/QueryBindingBuilder.svelte b/packages/builder/src/components/integration/QueryBindingBuilder.svelte index af890302b0..d0f9c5bad6 100644 --- a/packages/builder/src/components/integration/QueryBindingBuilder.svelte +++ b/packages/builder/src/components/integration/QueryBindingBuilder.svelte @@ -3,7 +3,7 @@ import { readableToRuntimeBinding, runtimeToReadableBinding, - } from "builderStore/dataBinding" + } from "builder/dataBinding" import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" import { createEventDispatcher } from "svelte" diff --git a/packages/builder/src/components/integration/QueryEditor.svelte b/packages/builder/src/components/integration/QueryEditor.svelte index 51fdb4879e..97998c3d22 100644 --- a/packages/builder/src/components/integration/QueryEditor.svelte +++ b/packages/builder/src/components/integration/QueryEditor.svelte @@ -2,7 +2,7 @@ import CodeMirror from "./codemirror" import { Label } from "@budibase/bbui" import { onMount, createEventDispatcher } from "svelte" - import { themeStore } from "builderStore" + import { themeStore } from "stores/portal" const dispatch = createEventDispatcher() diff --git a/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte b/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte index 3d74e3f6b6..0cfce5fd24 100644 --- a/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte +++ b/packages/builder/src/components/integration/QueryViewerBindingBuilder.svelte @@ -1,9 +1,7 @@ diff --git a/packages/builder/src/components/start/CreateAppModal.svelte b/packages/builder/src/components/start/CreateAppModal.svelte index 9e831f5bd9..09bd628d6a 100644 --- a/packages/builder/src/components/start/CreateAppModal.svelte +++ b/packages/builder/src/components/start/CreateAppModal.svelte @@ -7,7 +7,8 @@ ModalContent, Dropzone, } from "@budibase/bbui" - import { store, automationStore } from "builderStore" + import { initialise as initialiseFrontend } from "stores/frontend" + import { initialise as initialiseBackend } from "stores/backend" import { API } from "api" import { apps, admin, auth } from "stores/portal" import { onMount } from "svelte" @@ -132,8 +133,10 @@ // Select Correct Application/DB in prep for creating user const pkg = await API.fetchAppPackage(createdApp.instance._id) - await store.actions.initialise(pkg) - await automationStore.actions.fetch() + + await initialiseFrontend(pkg) + await initialiseBackend(pkg) + // Update checklist - in case first app await admin.init() diff --git a/packages/builder/src/components/start/ImportAppModal.svelte b/packages/builder/src/components/start/ImportAppModal.svelte index 1bc32dc7a4..411e5fc739 100644 --- a/packages/builder/src/components/start/ImportAppModal.svelte +++ b/packages/builder/src/components/start/ImportAppModal.svelte @@ -9,7 +9,7 @@ Body, } from "@budibase/bbui" import { API } from "api" - import { automationStore, store } from "../../builderStore" + import { initialise } from "stores/frontend" export let app @@ -28,8 +28,8 @@ const appId = app.devId await API.updateAppFromExport(appId, data) const pkg = await API.fetchAppPackage(appId) - await store.actions.initialise(pkg) - await automationStore.actions.fetch() + await initialise(pkg) + notifications.success("App updated successfully") } catch (err) { notifications.error(`Failed to update app - ${err.message || err}`) diff --git a/packages/builder/src/helpers/formFields.js b/packages/builder/src/helpers/formFields.js index eaf260a9b6..aa22b65814 100644 --- a/packages/builder/src/helpers/formFields.js +++ b/packages/builder/src/helpers/formFields.js @@ -1,8 +1,8 @@ -import { findClosestMatchingComponent } from "builderStore/componentUtils" +import { findClosestMatchingComponent } from "stores/frontend/components/utils" import { getDatasourceForProvider, getSchemaForDatasource, -} from "builderStore/dataBinding" +} from "builder/dataBinding" export const getComponentFieldOptions = (asset, id, type, loose = true) => { const form = findClosestMatchingComponent( diff --git a/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte b/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte index a7d9584330..6ccf92a3c0 100644 --- a/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte @@ -14,7 +14,7 @@ Button, FancySelect, } from "@budibase/bbui" - import { store } from "builderStore" + import { builderStore, appStore } from "stores/frontend" import { groups, licensing, apps, users, auth, admin } from "stores/portal" import { fetchData, @@ -55,7 +55,7 @@ let inviteFailureResponse = "" $: validEmail = emailValidator(email) === true - $: prodAppId = apps.getProdAppID($store.appId) + $: prodAppId = apps.getProdAppID($appStore.appId) $: promptInvite = showInvite( filteredInvites, filteredUsers, @@ -182,7 +182,7 @@ const debouncedUpdateFetch = Utils.debounce(searchUsers, 250) $: debouncedUpdateFetch( query, - $store.builderSidePanel, + $builderStore.builderSidePanel, loaded, filterByAppAccess ) @@ -200,7 +200,7 @@ [prodAppId]: role, }, }) - await searchUsers(query, $store.builderSidePanel, loaded) + await searchUsers(query, $builderStore.builderSidePanel, loaded) } const onUpdateUser = async (user, role) => { @@ -486,7 +486,7 @@ loaded = true } - $: initSidePanel($store.builderSidePanel) + $: initSidePanel($builderStore.builderSidePanel) function handleKeyDown(evt) { if (evt.key === "Enter" && validEmail && !inviting) { @@ -523,12 +523,7 @@
{ - store.update(state => { - state.builderSidePanel = false - return state - }) - }} + use:clickOutside={builderStore.hideBuilderSidePanel} >
{ - store.update(state => { - state.builderSidePanel = false - return state - }) + builderStore.hideBuilderSidePanel() }} />
diff --git a/packages/builder/src/pages/builder/app/[application]/_components/PreviewOverlay.svelte b/packages/builder/src/pages/builder/app/[application]/_components/PreviewOverlay.svelte index eedff6c2a7..efbbcf57c6 100644 --- a/packages/builder/src/pages/builder/app/[application]/_components/PreviewOverlay.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_components/PreviewOverlay.svelte @@ -1,26 +1,25 @@ @@ -31,7 +30,7 @@ on:click|self={close} >
diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte index 1df2a90250..3bd608b5a0 100644 --- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte @@ -1,11 +1,14 @@ -{#if $store.builderSidePanel} +{#if $builderStore.builderSidePanel} {/if} -
+
- {#if $store.initialised} + {#if $appStore.initialised}
- {$store.name} + {$appStore.name}
@@ -190,7 +191,7 @@ {/await}
-{#if $store.showPreview} +{#if $previewStore.showPreview} {/if} diff --git a/packages/builder/src/pages/builder/app/[application]/automation/[automationId]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/automation/[automationId]/_layout.svelte index 3be71a1bbe..0e48a83cb5 100644 --- a/packages/builder/src/pages/builder/app/[application]/automation/[automationId]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/automation/[automationId]/_layout.svelte @@ -1,5 +1,5 @@ diff --git a/packages/builder/src/pages/builder/app/[application]/data/view/v2/[viewId]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/data/view/v2/[viewId]/_layout.svelte index 8ddd6adbd0..1a7aee2a56 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/view/v2/[viewId]/_layout.svelte +++ b/packages/builder/src/pages/builder/app/[application]/data/view/v2/[viewId]/_layout.svelte @@ -3,10 +3,10 @@ import { syncURLToState } from "helpers/urlStateSync" import * as routify from "@roxi/routify" import { onDestroy } from "svelte" - import { store } from "builderStore" + import { builderStore } from "stores/frontend" $: id = $viewsV2.selectedViewId - $: store.actions.websocket.selectResource(id) + $: builderStore.selectResource(id) const stopSyncing = syncURLToState({ urlParam: "viewId", diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsPanel.svelte index afcada4138..6daa2c4c3c 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsPanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsPanel.svelte @@ -1,6 +1,10 @@ diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte index 383026c4f8..aafea25c80 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte @@ -16,11 +16,16 @@ notifications, Select, } from "@budibase/bbui" - import { selectedScreen, store } from "builderStore" + import { + themeStore, + selectedScreen, + screenStore, + navigationStore, + } from "stores/frontend" import { DefaultAppTheme } from "constants" const updateShowNavigation = async e => { - await store.actions.screens.updateSetting( + await screenStore.updateSetting( get(selectedScreen), "showNavigation", e.detail @@ -29,9 +34,9 @@ const update = async (key, value) => { try { - let navigation = $store.navigation + let navigation = $navigationStore navigation[key] = value - await store.actions.navigation.save(navigation) + await navigationStore.save(navigation) } catch (error) { notifications.error("Error updating navigation settings") } @@ -40,7 +45,7 @@ @@ -51,13 +56,13 @@
Show nav on this screen
- {#if $selectedScreen.showNavigation} + {#if $selectedScreen?.showNavigation}
@@ -76,25 +81,25 @@
update("navigation", "Top")} /> update("navigation", "Left")} /> - {#if $store.navigation.navigation === "Top"} + {#if $navigationStore.navigation === "Top"}
update("sticky", e.detail)} />
@@ -103,7 +108,7 @@ update("logoUrl", e.detail)} updateOnChange={false} /> @@ -128,15 +133,15 @@
update("hideTitle", !e.detail)} /> - {#if !$store.navigation.hideTitle} + {#if !$navigationStore.hideTitle}
update("title", e.detail)} updateOnChange={false} /> @@ -145,8 +150,8 @@
update("navBackground", e.detail)} /> @@ -154,8 +159,8 @@
update("navTextColor", e.detail)} />
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/AppThemeSelect.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/AppThemeSelect.svelte index 86a897bf60..5690e09179 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/AppThemeSelect.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/AppThemeSelect.svelte @@ -1,11 +1,11 @@ diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte index 13a008fae0..c6b5cfbe1a 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/ThemePanel.svelte @@ -7,21 +7,17 @@ Icon, Body, } from "@budibase/bbui" - import { store } from "builderStore" - import { get } from "svelte/store" + import { themeStore, appStore } from "stores/frontend" import { DefaultAppTheme } from "constants" import AppThemeSelect from "./AppThemeSelect.svelte" import ButtonRoundnessSelect from "./ButtonRoundnessSelect.svelte" import PropertyControl from "components/design/settings/controls/PropertyControl.svelte" - $: customTheme = $store.customTheme || {} + $: customTheme = $themeStore.customTheme || {} const update = async (property, value) => { try { - store.actions.customTheme.save({ - ...get(store).customTheme, - [property]: value, - }) + themeStore.saveCustom({ [property]: value }, $appStore.appId) } catch (error) { notifications.error("Error updating custom theme") } @@ -49,7 +45,7 @@ value={customTheme.primaryColor || DefaultAppTheme.primaryColor} onChange={val => update("primaryColor", val)} props={{ - spectrumTheme: $store.theme, + spectrumTheme: $themeStore.theme, }} /> update("primaryColorHover", val)} props={{ - spectrumTheme: $store.theme, + spectrumTheme: $themeStore.theme, }} /> diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte index 778fa303cc..22376c67a1 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Screen/index.svelte @@ -1,7 +1,7 @@ - -
-
- {#each tabs as tab} - { - activeTab = tab - }} - > - {capitalise(tab)} - - {/each} +{#if $selectedScreen} + +
+
+ {#each tabs as tab} + { + activeTab = tab + }} + > + {capitalise(tab)} + + {/each} +
-
- - {#if activeTab === "theme"} - - {:else} - - {/if} - - + + {#if activeTab === "theme"} + + {:else} + + {/if} + + +{/if} diff --git a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte index a39634f9a3..e906ef445d 100644 --- a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte +++ b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte @@ -54,6 +54,7 @@ export let placeholder = null export let autocompleteEnabled = true export let autofocus = false + export let jsBindingWrapping = true // Export a function to expose caret position export const getCaretPosition = () => { @@ -187,7 +188,7 @@ ) complete.push( EditorView.inputHandler.of((view, from, to, insert) => { - if (insert === "$") { + if (jsBindingWrapping && insert === "$") { let { text } = view.state.doc.lineAt(from) const left = from ? text.substring(0, from) : "" diff --git a/packages/builder/src/components/common/CodeEditor/index.js b/packages/builder/src/components/common/CodeEditor/index.js index da0e727e4e..38d377b47a 100644 --- a/packages/builder/src/components/common/CodeEditor/index.js +++ b/packages/builder/src/components/common/CodeEditor/index.js @@ -286,13 +286,14 @@ export const hbInsert = (value, from, to, text) => { return parsedInsert } -export function jsInsert(value, from, to, text, { helper } = {}) { +export function jsInsert(value, from, to, text, { helper, disableWrapping }) { let parsedInsert = "" const left = from ? value.substring(0, from) : "" const right = to ? value.substring(to) : "" - - if (helper) { + if (disableWrapping) { + parsedInsert = text + } else if (helper) { parsedInsert = `helpers.${text}()` } else if (!left.includes('$("') || !right.includes('")')) { parsedInsert = `$("${text}")` diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index 548a71b483..e6bd2fe86a 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -29,10 +29,9 @@ hbAutocomplete, EditorModes, bindingsToCompletions, - hbInsert, - jsInsert, } from "../CodeEditor" import BindingPicker from "./BindingPicker.svelte" + import { BindingHelpers } from "./utils" const dispatch = createEventDispatcher() @@ -60,8 +59,10 @@ let targetMode = null $: usingJS = mode === "JavaScript" - $: editorMode = mode == "JavaScript" ? EditorModes.JS : EditorModes.Handlebars + $: editorMode = + mode === "JavaScript" ? EditorModes.JS : EditorModes.Handlebars $: bindingCompletions = bindingsToCompletions(bindings, editorMode) + $: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos) const updateValue = val => { valid = isValid(readableToRuntimeBinding(bindings, val)) @@ -70,31 +71,13 @@ } } - // Adds a JS/HBS helper to the expression const onSelectHelper = (helper, js) => { - const pos = getCaretPosition() - const { start, end } = pos - if (js) { - let js = decodeJSBinding(jsValue) - const insertVal = jsInsert(js, start, end, helper.text, { helper: true }) - insertAtPos({ start, end, value: insertVal }) - } else { - const insertVal = hbInsert(hbsValue, start, end, helper.text) - insertAtPos({ start, end, value: insertVal }) - } + bindingHelpers.onSelectHelper(js ? jsValue : hbsValue, helper, js) } - // Adds a data binding to the expression const onSelectBinding = (binding, { forceJS } = {}) => { - const { start, end } = getCaretPosition() - if (usingJS || forceJS) { - let js = decodeJSBinding(jsValue) - const insertVal = jsInsert(js, start, end, binding.readableBinding) - insertAtPos({ start, end, value: insertVal }) - } else { - const insertVal = hbInsert(hbsValue, start, end, binding.readableBinding) - insertAtPos({ start, end, value: insertVal }) - } + const js = usingJS || forceJS + bindingHelpers.onSelectBinding(js ? jsValue : hbsValue, binding, { js }) } const onChangeMode = e => { diff --git a/packages/builder/src/components/common/bindings/utils.js b/packages/builder/src/components/common/bindings/utils.js index 8d414ffed3..428e092842 100644 --- a/packages/builder/src/components/common/bindings/utils.js +++ b/packages/builder/src/components/common/bindings/utils.js @@ -1,38 +1,41 @@ -export function addHBSBinding(value, caretPos, binding) { - binding = typeof binding === "string" ? binding : binding.path - value = value == null ? "" : value +import { decodeJSBinding } from "@budibase/string-templates" +import { hbInsert, jsInsert } from "components/common/CodeEditor" - const left = caretPos?.start ? value.substring(0, caretPos.start) : "" - const right = caretPos?.end ? value.substring(caretPos.end) : "" - if (!left.includes("{{") || !right.includes("}}")) { - binding = `{{ ${binding} }}` +export class BindingHelpers { + constructor(getCaretPosition, insertAtPos, { disableWrapping } = {}) { + this.getCaretPosition = getCaretPosition + this.insertAtPos = insertAtPos + this.disableWrapping = disableWrapping } - if (caretPos.start) { - value = - value.substring(0, caretPos.start) + - binding + - value.substring(caretPos.end, value.length) - } else { - value += binding - } - return value -} -export function addJSBinding(value, caretPos, binding, { helper } = {}) { - binding = typeof binding === "string" ? binding : binding.path - value = value == null ? "" : value - if (!helper) { - binding = `$("${binding}")` - } else { - binding = `helpers.${binding}()` + // Adds a JS/HBS helper to the expression + onSelectHelper(value, helper, { js }) { + const pos = this.getCaretPosition() + const { start, end } = pos + if (js) { + const jsVal = decodeJSBinding(value) + const insertVal = jsInsert(jsVal, start, end, helper.text, { + helper: true, + }) + this.insertAtPos({ start, end, value: insertVal }) + } else { + const insertVal = hbInsert(value, start, end, helper.text) + this.insertAtPos({ start, end, value: insertVal }) + } } - if (caretPos.start) { - value = - value.substring(0, caretPos.start) + - binding + - value.substring(caretPos.end, value.length) - } else { - value += binding + + // Adds a data binding to the expression + onSelectBinding(value, binding, { js, decode }) { + const { start, end } = this.getCaretPosition() + if (js) { + const jsVal = decode ? decodeJSBinding(value) : value + const insertVal = jsInsert(jsVal, start, end, binding.readableBinding, { + disableWrapping: this.disableWrapping, + }) + this.insertAtPos({ start, end, value: insertVal }) + } else { + const insertVal = hbInsert(value, start, end, binding.readableBinding) + this.insertAtPos({ start, end, value: insertVal }) + } } - return value } From 332a201ae7c4e99666031ac38d57c5806ce0870b Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 2 Feb 2024 09:51:46 +0000 Subject: [PATCH 106/294] Revert "Migrate from `vm` to `isolated-vm`" --- hosting/single/Dockerfile | 2 - packages/backend-core/package.json | 2 +- packages/backend-core/src/context/types.ts | 8 +- packages/backend-core/src/timers/timers.ts | 38 ++++ .../bbui/src/Form/Core/EnvDropdown.svelte | 4 +- packages/server/Dockerfile | 2 - packages/server/nodemon.json | 4 +- packages/server/package.json | 22 +-- packages/server/scripts/test.sh | 4 +- packages/server/src/api/controllers/script.ts | 6 +- .../src/api/controllers/static/index.ts | 2 +- .../server/src/api/routes/tests/table.spec.ts | 2 +- .../automations/tests/executeScript.spec.js | 42 ++--- packages/server/src/db/newid.ts | 2 +- packages/server/src/environment.ts | 2 - packages/server/src/jsRunner.ts | 61 +++++++ packages/server/src/jsRunner/index.ts | 167 ------------------ .../src/jsRunner/tests/jsRunner.spec.ts | 75 -------- .../src/utilities/fileSystem/filesystem.ts | 2 +- packages/server/src/utilities/scriptRunner.ts | 64 ++----- packages/string-templates/package.json | 10 +- packages/string-templates/src/errors.js | 11 -- .../src/helpers/javascript.js | 2 +- packages/string-templates/src/helpers/list.js | 33 ++-- .../string-templates/src/index-helpers.js | 9 - packages/string-templates/src/index.cjs | 5 - packages/string-templates/src/index.js | 5 - packages/string-templates/src/index.mjs | 2 - .../string-templates/test/manifest.spec.js | 103 ++++++++++- packages/string-templates/test/utils.js | 111 ------------ packages/worker/Dockerfile | 2 - packages/worker/nodemon.json | 4 +- yarn.lock | 137 ++------------ 33 files changed, 281 insertions(+), 664 deletions(-) create mode 100644 packages/server/src/jsRunner.ts delete mode 100644 packages/server/src/jsRunner/index.ts delete mode 100644 packages/server/src/jsRunner/tests/jsRunner.spec.ts delete mode 100644 packages/string-templates/src/errors.js delete mode 100644 packages/string-templates/src/index-helpers.js delete mode 100644 packages/string-templates/test/utils.js diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index f9044cd124..67ac677984 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -124,8 +124,6 @@ HEALTHCHECK --interval=15s --timeout=15s --start-period=45s CMD "/healthcheck.sh # must set this just before running ENV NODE_ENV=production -# this is required for isolated-vm to work on Node 20+ -ENV NODE_OPTIONS="--no-node-snapshot" WORKDIR / CMD ["./runner.sh"] diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 13bc7011b5..85644488f5 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -54,7 +54,7 @@ "sanitize-s3-objectkey": "0.0.1", "semver": "7.3.7", "tar-fs": "2.1.1", - "uuid": "^8.3.2" + "uuid": "8.3.2" }, "devDependencies": { "@shopify/jest-koa-mocks": "5.1.1", diff --git a/packages/backend-core/src/context/types.ts b/packages/backend-core/src/context/types.ts index cc052ca505..f73dc9f5c7 100644 --- a/packages/backend-core/src/context/types.ts +++ b/packages/backend-core/src/context/types.ts @@ -1,5 +1,5 @@ import { IdentityContext } from "@budibase/types" -import { Isolate, Context, Module } from "isolated-vm" +import { ExecutionTimeTracker } from "../timers" // keep this out of Budibase types, don't want to expose context info export type ContextMap = { @@ -10,9 +10,5 @@ export type ContextMap = { isScim?: boolean automationId?: string isMigrating?: boolean - isolateRefs?: { - jsIsolate: Isolate - jsContext: Context - helpersModule: Module - } + jsExecutionTracker?: ExecutionTimeTracker } diff --git a/packages/backend-core/src/timers/timers.ts b/packages/backend-core/src/timers/timers.ts index 000be74821..9121c576cd 100644 --- a/packages/backend-core/src/timers/timers.ts +++ b/packages/backend-core/src/timers/timers.ts @@ -20,3 +20,41 @@ export function cleanup() { } intervals = [] } + +export class ExecutionTimeoutError extends Error { + public readonly name = "ExecutionTimeoutError" +} + +export class ExecutionTimeTracker { + static withLimit(limitMs: number) { + return new ExecutionTimeTracker(limitMs) + } + + constructor(readonly limitMs: number) {} + + private totalTimeMs = 0 + + track(f: () => T): T { + this.checkLimit() + const start = process.hrtime.bigint() + try { + return f() + } finally { + const end = process.hrtime.bigint() + this.totalTimeMs += Number(end - start) / 1e6 + this.checkLimit() + } + } + + get elapsedMS() { + return this.totalTimeMs + } + + checkLimit() { + if (this.totalTimeMs > this.limitMs) { + throw new ExecutionTimeoutError( + `Execution time limit of ${this.limitMs}ms exceeded: ${this.totalTimeMs}ms` + ) + } + } +} diff --git a/packages/bbui/src/Form/Core/EnvDropdown.svelte b/packages/bbui/src/Form/Core/EnvDropdown.svelte index c690ffbc6b..2edf8a5f9d 100644 --- a/packages/bbui/src/Form/Core/EnvDropdown.svelte +++ b/packages/bbui/src/Form/Core/EnvDropdown.svelte @@ -184,7 +184,7 @@ {#if environmentVariablesEnabled}
showModal()} class="add-variable">
handleUpgradePanel()} class="add-variable">
showModal()} class="add-variable">
handleUpgradePanel()} class="add-variable">
bindingsHelpers.onSelectBinding( diff --git a/packages/builder/src/components/common/bindings/BindingPicker.svelte b/packages/builder/src/components/common/bindings/BindingPicker.svelte index d85a0a2bbb..758fa322e7 100644 --- a/packages/builder/src/components/common/bindings/BindingPicker.svelte +++ b/packages/builder/src/components/common/bindings/BindingPicker.svelte @@ -9,6 +9,7 @@ export let bindings export let mode export let allowHelpers + export let noPaddingTop = false let search = "" let popover @@ -104,7 +105,7 @@ {#if selectedCategory} -
+
Date: Fri, 2 Feb 2024 17:16:45 +0000 Subject: [PATCH 119/294] PR comments. --- .../automation/SetupPanel/AutomationBlockSetup.svelte | 2 +- .../src/components/common/bindings/BindingPicker.svelte | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 6f8fccc654..1536d83a82 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -577,7 +577,6 @@
bindingsHelpers.onSelectBinding( @@ -690,5 +689,6 @@ .js-binding-picker { flex: 3; + margin-top: calc((var(--spacing-xl) * -1) + 1px); } diff --git a/packages/builder/src/components/common/bindings/BindingPicker.svelte b/packages/builder/src/components/common/bindings/BindingPicker.svelte index 758fa322e7..9daed00324 100644 --- a/packages/builder/src/components/common/bindings/BindingPicker.svelte +++ b/packages/builder/src/components/common/bindings/BindingPicker.svelte @@ -105,7 +105,7 @@ {#if selectedCategory} -
+
Date: Mon, 5 Feb 2024 10:18:49 +0100 Subject: [PATCH 120/294] Clean code --- packages/server/src/utilities/scriptRunner.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/server/src/utilities/scriptRunner.ts b/packages/server/src/utilities/scriptRunner.ts index fe59117466..b6e597cc55 100644 --- a/packages/server/src/utilities/scriptRunner.ts +++ b/packages/server/src/utilities/scriptRunner.ts @@ -25,14 +25,14 @@ class ScriptRunner { class IsolatedVM { isolate: ivm.Isolate vm: ivm.Context - jail: ivm.Reference + #jail: ivm.Reference script: any constructor({ memoryLimit }: { memoryLimit: number }) { this.isolate = new ivm.Isolate({ memoryLimit }) this.vm = this.isolate.createContextSync() - this.jail = this.vm.global - this.jail.setSync("global", this.jail.derefInto()) + this.#jail = this.vm.global + this.#jail.setSync("global", this.#jail.derefInto()) } getValue(key: string) { @@ -44,7 +44,7 @@ class IsolatedVM { set context(context: Record) { for (let key in context) { - this.jail.setSync(key, this.copyRefToVm(context[key])) + this.#jail.setSync(key, this.copyRefToVm(context[key])) } } From 62994c2026ed57dad6e5c4e2da37e47bdca9f82e Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 5 Feb 2024 10:20:12 +0100 Subject: [PATCH 121/294] Lint --- packages/server/src/jsRunner/index.ts | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index 8e529d533d..ebf90257d1 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -33,19 +33,20 @@ export function init() { }) const jsContext = jsIsolate.createContextSync() - const injectedRequire = `const require = function(val){ - switch (val) { - case "url": - return { - resolve: (...params) => urlResolveCb(...params), - parse: (...params) => urlParseCb(...params), - } - case "querystring": - return { - escape: (...params) => querystringEscapeCb(...params), - } - } - };` + const injectedRequire = ` + const require = function(val){ + switch (val) { + case "url": + return { + resolve: (...params) => urlResolveCb(...params), + parse: (...params) => urlParseCb(...params), + } + case "querystring": + return { + escape: (...params) => querystringEscapeCb(...params), + } + } + };` const global = jsContext.global global.setSync( @@ -83,9 +84,9 @@ export function init() { `${injectedRequire};${helpersSource}` ) - const cryptoModule = jsIsolate.compileModuleSync(`export default { - randomUUID: cryptoRandomUUIDCb, - }`) + const cryptoModule = jsIsolate.compileModuleSync( + `export default { randomUUID: cryptoRandomUUIDCb }` + ) cryptoModule.instantiateSync(jsContext, specifier => { throw new Error(`No imports allowed. Required: ${specifier}`) }) From 1c29620c9abaab7e8a5a9d1cb21911a452757950 Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:33:58 +0000 Subject: [PATCH 122/294] Add readonly setting to user field (#12893) --- packages/client/manifest.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 5bbf465766..313b679e49 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -6742,6 +6742,17 @@ "key": "disabled", "defaultValue": false }, + { + "type": "boolean", + "label": "Read only", + "key": "readonly", + "defaultValue": false, + "dependsOn": { + "setting": "disabled", + "value": true, + "invert": true + } + }, { "type": "select", "label": "Layout", From 79f3486180988dc57cdf0231b06b6a52ee1bdb69 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Mon, 5 Feb 2024 10:14:18 +0000 Subject: [PATCH 123/294] Bump version to 2.17.4 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 0f02995ac0..f189c78a95 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.17.3", + "version": "2.17.4", "npmClient": "yarn", "packages": [ "packages/*", From 090460a8f5972838facac2b8f7284b01ff07ccf1 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 5 Feb 2024 11:15:48 +0000 Subject: [PATCH 124/294] Run all builder data hydration API calls in parallel to speed up builder loading --- packages/builder/src/stores/builder/index.js | 27 +++++++------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/packages/builder/src/stores/builder/index.js b/packages/builder/src/stores/builder/index.js index 317e97a0ac..c7e882428e 100644 --- a/packages/builder/src/stores/builder/index.js +++ b/packages/builder/src/stores/builder/index.js @@ -82,13 +82,15 @@ export const reset = () => { } const refreshBuilderData = async () => { - await automationStore.actions.fetch() - await datasources.init() - await integrations.init() - await queries.init() - await tables.init() - await roles.fetch() - await flags.fetch() + await Promise.all([ + automationStore.actions.fetch(), + datasources.init(), + integrations.init(), + queries.init(), + tables.init(), + roles.fetch(), + flags.fetch(), + ]) } const resetBuilderHistory = () => { @@ -98,27 +100,16 @@ const resetBuilderHistory = () => { export const initialise = async pkg => { const { application } = pkg - appStore.syncAppPackage(pkg) - appStore.syncAppRoutes() - builderStore.init(application) - navigationStore.syncAppNavigation(application?.navigation) - await componentStore.refreshDefinitions(application?.appId) - themeStore.syncAppTheme(application) - screenStore.syncAppScreens(pkg) - layoutStore.syncAppLayouts(pkg) - // required for api comms database.syncAppDatabase(application) - resetBuilderHistory() - await refreshBuilderData() } From 1650f3732914760b6af2368064235fda13c9bd7e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 5 Feb 2024 11:22:33 +0000 Subject: [PATCH 125/294] Treat component store the same as other stores, and move component utils into helpers --- .../ButtonActionEditor/actions/ExportData.svelte | 5 +---- .../actions/OpenSidePanel.svelte | 2 +- .../ButtonActionEditor/actions/S3Upload.svelte | 2 +- .../ButtonActionEditor/actions/ScrollTo.svelte | 2 +- .../actions/UpdateFieldValue.svelte | 2 +- .../settings/controls/DataProviderSelect.svelte | 2 +- .../DataSourceSelect/DataSourceSelect.svelte | 2 +- .../controls/RelationshipFilterEditor.svelte | 2 +- .../settings/controls/ResetFieldsButton.svelte | 2 +- .../ValidationEditor/ValidationDrawer.svelte | 2 +- packages/builder/src/dataBinding.js | 2 +- .../components/utils.js => helpers/components.js} | 2 +- packages/builder/src/helpers/formFields.js | 2 +- .../Component/ComponentSettingsPanel.svelte | 2 +- .../[screenId]/[componentId]/_layout.svelte | 2 +- .../new/_components/NewComponentPanel.svelte | 2 +- .../[screenId]/_components/AppPreview.svelte | 5 +---- .../ComponentList/ComponentKeyHandler.svelte | 2 +- .../ComponentList/ComponentTree.svelte | 2 +- .../_components/ComponentList/dndStore.js | 5 +---- .../_components/ScreenList/DropdownMenu.svelte | 2 +- .../{components/index.js => components.js} | 15 ++++++++++----- packages/builder/src/stores/builder/screens.js | 2 +- 23 files changed, 32 insertions(+), 36 deletions(-) rename packages/builder/src/{stores/builder/components/utils.js => helpers/components.js} (99%) rename packages/builder/src/stores/builder/{components/index.js => components.js} (99%) diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte index 77dc95b1c4..f5985a0d29 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte @@ -1,9 +1,6 @@ diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte index 7a09e11b52..7513072034 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/SaveRow.svelte @@ -1,6 +1,11 @@ diff --git a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte index a366feb03b..1de5ae6cc6 100644 --- a/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataSourceSelect/DataSourceSelect.svelte @@ -22,7 +22,7 @@ queries as queriesStore, viewsV2 as viewsV2Store, views as viewsStore, - currentAsset, + selectedScreen, componentStore, datasources, integrations, @@ -76,7 +76,7 @@ ...query, type: "query", })) - $: dataProviders = findAllComponents($currentAsset.props) + $: dataProviders = findAllComponents($selectedScreen.props) .filter(component => { return ( component._component?.endsWith("/dataprovider") && diff --git a/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte b/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte index 9e55e30e46..c6b62543cb 100644 --- a/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte +++ b/packages/builder/src/components/design/settings/controls/FieldConfiguration/FieldConfiguration.svelte @@ -7,7 +7,7 @@ getBindableProperties, getComponentBindableProperties, } from "../../../../../dataBinding" - import { selectedScreen, currentAsset, componentStore } from "stores/builder" + import { selectedScreen, componentStore } from "stores/builder" import DraggableList from "../DraggableList/DraggableList.svelte" import { createEventDispatcher } from "svelte" import FieldSetting from "./FieldSetting.svelte" @@ -44,7 +44,7 @@ $: datasource = componentInstance.dataSource || - getDatasourceForProvider($currentAsset, componentInstance) + getDatasourceForProvider($selectedScreen, componentInstance) $: resourceId = datasource?.resourceId || datasource?.tableId @@ -53,7 +53,7 @@ } const updateState = value => { - schema = getSchema($currentAsset, datasource) + schema = getSchema($selectedScreen, datasource) options = Object.keys(schema || {}) sanitisedValue = getValidColumns(convertOldFieldFormat(value), options) updateSanitsedFields(sanitisedValue) diff --git a/packages/builder/src/components/design/settings/controls/FieldSelect.svelte b/packages/builder/src/components/design/settings/controls/FieldSelect.svelte index e1f63af1af..4921eb74fa 100644 --- a/packages/builder/src/components/design/settings/controls/FieldSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/FieldSelect.svelte @@ -4,7 +4,7 @@ getDatasourceForProvider, getSchemaForDatasource, } from "../../../../dataBinding" - import { currentAsset } from "stores/builder" + import { selectedScreen } from "stores/builder" import { createEventDispatcher } from "svelte" export let componentInstance = {} @@ -12,8 +12,8 @@ export let placeholder const dispatch = createEventDispatcher() - $: datasource = getDatasourceForProvider($currentAsset, componentInstance) - $: schema = getSchemaForDatasource($currentAsset, datasource).schema + $: datasource = getDatasourceForProvider($selectedScreen, componentInstance) + $: schema = getSchemaForDatasource($selectedScreen, datasource).schema $: options = Object.keys(schema || {}) $: boundValue = getValidValue(value, options) diff --git a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte index cdcb488834..b8adbd5276 100644 --- a/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte +++ b/packages/builder/src/components/design/settings/controls/FilterEditor/FilterEditor.svelte @@ -6,7 +6,7 @@ getSchemaForDatasource, } from "../../../../../dataBinding" import FilterDrawer from "./FilterDrawer.svelte" - import { currentAsset } from "stores/builder" + import { selectedScreen } from "stores/builder" const dispatch = createEventDispatcher() @@ -18,8 +18,8 @@ let drawer $: tempValue = value - $: datasource = getDatasourceForProvider($currentAsset, componentInstance) - $: dsSchema = getSchemaForDatasource($currentAsset, datasource)?.schema + $: datasource = getDatasourceForProvider($selectedScreen, componentInstance) + $: dsSchema = getSchemaForDatasource($selectedScreen, datasource)?.schema $: schemaFields = Object.values(schema || dsSchema || {}) $: text = getText(value?.filter(filter => filter.field)) diff --git a/packages/builder/src/components/design/settings/controls/FormFieldSelect.svelte b/packages/builder/src/components/design/settings/controls/FormFieldSelect.svelte index 3a7f1d73e4..b418cb3111 100644 --- a/packages/builder/src/components/design/settings/controls/FormFieldSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/FormFieldSelect.svelte @@ -1,6 +1,6 @@ - + From 792283d8b5c796138788a548190b61ed4f8bf09e Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 10:18:58 +0100 Subject: [PATCH 148/294] Add readme --- packages/server/package.json | 2 +- packages/server/src/jsRunner/bundles/README.md | 15 +++++++++++++++ ....bundle.js.txt => index-helpers.ivm.bundle.js} | 0 packages/server/src/jsRunner/index.ts | 2 +- scripts/build.js | 4 ++-- 5 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 packages/server/src/jsRunner/bundles/README.md rename packages/server/src/jsRunner/bundles/{index-helpers.ivm.bundle.js.txt => index-helpers.ivm.bundle.js} (100%) diff --git a/packages/server/package.json b/packages/server/package.json index ebfa66aeca..5591fe080f 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -13,7 +13,7 @@ "build": "node ./scripts/build.js", "postbuild": "copyfiles -f ../client/dist/budibase-client.js ../client/manifest.json client && copyfiles -f ../../yarn.lock ./dist/", "check:types": "tsc -p tsconfig.json --noEmit --paths null", - "build:isolated-vm-lib:string-templates": "esbuild --minify --bundle src/jsRunner/bundles/index-helpers.ts --outfile=src/jsRunner/bundles/index-helpers.ivm.bundle.js.txt --platform=node --format=esm --external:handlebars", + "build:isolated-vm-lib:string-templates": "esbuild --minify --bundle src/jsRunner/bundles/index-helpers.ts --outfile=src/jsRunner/bundles/index-helpers.ivm.bundle.js --platform=node --format=esm --external:handlebars", "build:isolated-vm-libs": "yarn build:isolated-vm-lib:string-templates", "build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput", "debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js", diff --git a/packages/server/src/jsRunner/bundles/README.md b/packages/server/src/jsRunner/bundles/README.md new file mode 100644 index 0000000000..fac8ebe14a --- /dev/null +++ b/packages/server/src/jsRunner/bundles/README.md @@ -0,0 +1,15 @@ +# Bundles for isolated-vm + +[Isolated-vm](https://github.com/laverdet/isolated-vm) requires for us to have some libraries, such as string-templates helpers, built in a single file without external dependencies. These libraries are pretty much static. To avoid building this in every dev command, in every test command and in every pipeline, these libraries are already compiled and commited into the repo. + +## How are they consumed? + +These libaries are compiled with a special extension: .ivm.bundle.js. This extension is configured in [esbuild](/scripts/build.js) in order to not be bundled as javascript, and to be treated as a `string` instead. This will allow us to read it's context on runtime and inject it to `isolated-vm`. + +## How to update it? + +These libraries are pretty much static, but they might require some updates from time to time when something changes on the source code. In order to do this, we just need to run the following command and commit the updated bundles: + +``` +yarn build:isolated-vm-libs +``` diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js.txt b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js similarity index 100% rename from packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js.txt rename to packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index e5d95cf200..f0ebac2ec4 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -7,7 +7,7 @@ import url from "url" import crypto from "crypto" import querystring from "querystring" -const helpersSource = require("./bundles/index-helpers.ivm.bundle.js.txt") +const helpersSource = require("./bundles/index-helpers.ivm.bundle.js") class ExecutionTimeoutError extends Error { constructor(message: string) { diff --git a/scripts/build.js b/scripts/build.js index 599585c731..ad31381684 100755 --- a/scripts/build.js +++ b/scripts/build.js @@ -49,7 +49,7 @@ function runBuild(entry, outfile) { preserveSymlinks: true, loader: { ".svelte": "copy", - ".ivm.bundle.js.txt": "text", + ".ivm.bundle.js": "text", }, metafile: true, external: [ @@ -61,7 +61,7 @@ function runBuild(entry, outfile) { "bcrypt", "bcryptjs", "graphql/*", - "bson" + "bson", ], } From e4a607b1b7928784ac1c13a40bebb26677859c60 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 10:19:52 +0100 Subject: [PATCH 149/294] Ignore bundles from lint --- .eslintignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index a79f9e2879..383b324ccd 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,4 +10,5 @@ packages/builder/.routify packages/sdk/sdk packages/account-portal/packages/server/build packages/account-portal/packages/ui/.routify -packages/account-portal/packages/ui/build \ No newline at end of file +packages/account-portal/packages/ui/build +.ivm.bundle.js \ No newline at end of file From d29b6ead5e1bd94035ed4e6733ebc65d5fb171d8 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 10:26:00 +0100 Subject: [PATCH 150/294] Ignore bundles from lint --- .eslintignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index 383b324ccd..8d4c64d960 100644 --- a/.eslintignore +++ b/.eslintignore @@ -11,4 +11,4 @@ packages/sdk/sdk packages/account-portal/packages/server/build packages/account-portal/packages/ui/.routify packages/account-portal/packages/ui/build -.ivm.bundle.js \ No newline at end of file +**/*.ivm.bundle.js \ No newline at end of file From 1dbcaf60d830e0fab3f92869c78ac6b1dce2930d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 10:28:06 +0100 Subject: [PATCH 151/294] Lint --- packages/server/src/jsRunner/bundles/index-helpers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ts b/packages/server/src/jsRunner/bundles/index-helpers.ts index 1a0eeeb566..a7596b15e0 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ts +++ b/packages/server/src/jsRunner/bundles/index-helpers.ts @@ -1,5 +1,4 @@ -import {getJsHelperList} from '@budibase/string-templates/js-helpers' - +import { getJsHelperList } from "@budibase/string-templates/js-helpers" const helpers = getJsHelperList() export default { From 190903cbed294948cf90e859c0ca9a6648177b68 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 10:31:03 +0100 Subject: [PATCH 152/294] Ignore bundles from prettier --- .prettierignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index 2444f0e753..87f0191a94 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,4 +11,5 @@ packages/sdk/sdk packages/pro/coverage packages/account-portal/packages/ui/build packages/account-portal/packages/ui/.routify -packages/account-portal/packages/server/build \ No newline at end of file +packages/account-portal/packages/server/build +**/*.ivm.bundle.js \ No newline at end of file From 6bc5bf5be15a757f2eec274ba6a6025181713cf6 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 10:42:44 +0100 Subject: [PATCH 153/294] Clean --- eslint-local-rules/index.js | 4 ++-- .../server/src/jsRunner/bundles/index-helpers.ivm.bundle.js | 2 +- packages/server/src/jsRunner/bundles/index-helpers.ts | 4 +++- packages/string-templates/package.json | 1 - 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/eslint-local-rules/index.js b/eslint-local-rules/index.js index 6806eeefe0..af02599c90 100644 --- a/eslint-local-rules/index.js +++ b/eslint-local-rules/index.js @@ -7,11 +7,11 @@ module.exports = { if ( /^@budibase\/[^/]+\/.*$/.test(importPath) && - !["@budibase/backend-core/tests","@budibase/string-templates/js-helpers"].includes(importPath) + importPath !== "@budibase/backend-core/tests" ) { context.report({ node, - message: `Importing from @budibase is not allowed, except for @budibase/backend-core/tests and @budibase/string-templates/js-helpers.`, + message: `Importing from @budibase is not allowed, except for @budibase/backend-core/tests.`, }) } }, diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js index 6df3001393..706625b757 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js +++ b/packages/server/src/jsRunner/bundles/index-helpers.ivm.bundle.js @@ -1,4 +1,4 @@ -var fn=Object.create;var xe=Object.defineProperty;var on=Object.getOwnPropertyDescriptor;var an=Object.getOwnPropertyNames;var cn=Object.getPrototypeOf,ln=Object.prototype.hasOwnProperty;var Ue=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Z=(e,t)=>()=>(e&&(t=e(e=0)),t);var U=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),dn=(e,t)=>{for(var r in t)xe(e,r,{get:t[r],enumerable:!0})},gt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of an(t))!ln.call(e,i)&&i!==r&&xe(e,i,{get:()=>t[i],enumerable:!(n=on(t,i))||n.enumerable});return e};var hn=(e,t,r)=>(r=e!=null?fn(cn(e)):{},gt(t||!e||!e.__esModule?xe(r,"default",{value:e,enumerable:!0}):r,e)),pn=e=>gt(xe({},"__esModule",{value:!0}),e);var yt=U((Te,qe)=>{(function(e,t){typeof Te=="object"&&typeof qe<"u"?qe.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs=t()})(Te,function(){"use strict";var e=1e3,t=6e4,r=36e5,n="millisecond",i="second",u="minute",s="hour",f="day",w="week",g="month",l="quarter",x="year",v="date",a="Invalid Date",T=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,E=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,I={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function($){var h=["th","st","nd","rd"],c=$%100;return"["+$+(h[(c-20)%10]||h[c]||h[0])+"]"}},Y=function($,h,c){var b=String($);return!b||b.length>=h?$:""+Array(h+1-b.length).join(c)+$},F={s:Y,z:function($){var h=-$.utcOffset(),c=Math.abs(h),b=Math.floor(c/60),d=c%60;return(h<=0?"+":"-")+Y(b,2,"0")+":"+Y(d,2,"0")},m:function $(h,c){if(h.date()1)return $(j[0])}else{var _=h.name;S[_]=h,d=_}return!b&&d&&(q=d),d||!b&&q},N=function($,h){if(o($))return $.clone();var c=typeof h=="object"?h:{};return c.date=$,c.args=arguments,new B(c)},O=F;O.l=D,O.i=o,O.w=function($,h){return N($,{locale:h.$L,utc:h.$u,x:h.$x,$offset:h.$offset})};var B=function(){function $(c){this.$L=D(c.locale,null,!0),this.parse(c),this.$x=this.$x||c.x||{},this[p]=!0}var h=$.prototype;return h.parse=function(c){this.$d=function(b){var d=b.date,M=b.utc;if(d===null)return new Date(NaN);if(O.u(d))return new Date;if(d instanceof Date)return new Date(d);if(typeof d=="string"&&!/Z$/i.test(d)){var j=d.match(T);if(j){var _=j[2]-1||0,H=(j[7]||"0").substring(0,3);return M?new Date(Date.UTC(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)):new Date(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)}}return new Date(d)}(c),this.init()},h.init=function(){var c=this.$d;this.$y=c.getFullYear(),this.$M=c.getMonth(),this.$D=c.getDate(),this.$W=c.getDay(),this.$H=c.getHours(),this.$m=c.getMinutes(),this.$s=c.getSeconds(),this.$ms=c.getMilliseconds()},h.$utils=function(){return O},h.isValid=function(){return this.$d.toString()!==a},h.isSame=function(c,b){var d=N(c);return this.startOf(b)<=d&&d<=this.endOf(b)},h.isAfter=function(c,b){return N(c){(function(e,t){typeof Ye=="object"&&typeof Ce<"u"?Ce.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_duration=t()})(Ye,function(){"use strict";var e,t,r=1e3,n=6e4,i=36e5,u=864e5,s=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,f=31536e6,w=2628e6,g=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/,l={years:f,months:w,days:u,hours:i,minutes:n,seconds:r,milliseconds:1,weeks:6048e5},x=function(S){return S instanceof F},v=function(S,p,o){return new F(S,o,p.$l)},a=function(S){return t.p(S)+"s"},T=function(S){return S<0},E=function(S){return T(S)?Math.ceil(S):Math.floor(S)},I=function(S){return Math.abs(S)},Y=function(S,p){return S?T(S)?{negative:!0,format:""+I(S)+p}:{negative:!1,format:""+S+p}:{negative:!1,format:""}},F=function(){function S(o,D,N){var O=this;if(this.$d={},this.$l=N,o===void 0&&(this.$ms=0,this.parseFromMilliseconds()),D)return v(o*l[a(D)],this);if(typeof o=="number")return this.$ms=o,this.parseFromMilliseconds(),this;if(typeof o=="object")return Object.keys(o).forEach(function($){O.$d[a($)]=o[$]}),this.calMilliseconds(),this;if(typeof o=="string"){var B=o.match(g);if(B){var J=B.slice(2).map(function($){return $!=null?Number($):0});return this.$d.years=J[0],this.$d.months=J[1],this.$d.weeks=J[2],this.$d.days=J[3],this.$d.hours=J[4],this.$d.minutes=J[5],this.$d.seconds=J[6],this.calMilliseconds(),this}}return this}var p=S.prototype;return p.calMilliseconds=function(){var o=this;this.$ms=Object.keys(this.$d).reduce(function(D,N){return D+(o.$d[N]||0)*l[N]},0)},p.parseFromMilliseconds=function(){var o=this.$ms;this.$d.years=E(o/f),o%=f,this.$d.months=E(o/w),o%=w,this.$d.days=E(o/u),o%=u,this.$d.hours=E(o/i),o%=i,this.$d.minutes=E(o/n),o%=n,this.$d.seconds=E(o/r),o%=r,this.$d.milliseconds=o},p.toISOString=function(){var o=Y(this.$d.years,"Y"),D=Y(this.$d.months,"M"),N=+this.$d.days||0;this.$d.weeks&&(N+=7*this.$d.weeks);var O=Y(N,"D"),B=Y(this.$d.hours,"H"),J=Y(this.$d.minutes,"M"),$=this.$d.seconds||0;this.$d.milliseconds&&($+=this.$d.milliseconds/1e3,$=Math.round(1e3*$)/1e3);var h=Y($,"S"),c=o.negative||D.negative||O.negative||B.negative||J.negative||h.negative,b=B.format||J.format||h.format?"T":"",d=(c?"-":"")+"P"+o.format+D.format+O.format+b+B.format+J.format+h.format;return d==="P"||d==="-P"?"P0D":d},p.toJSON=function(){return this.toISOString()},p.format=function(o){var D=o||"YYYY-MM-DDTHH:mm:ss",N={Y:this.$d.years,YY:t.s(this.$d.years,2,"0"),YYYY:t.s(this.$d.years,4,"0"),M:this.$d.months,MM:t.s(this.$d.months,2,"0"),D:this.$d.days,DD:t.s(this.$d.days,2,"0"),H:this.$d.hours,HH:t.s(this.$d.hours,2,"0"),m:this.$d.minutes,mm:t.s(this.$d.minutes,2,"0"),s:this.$d.seconds,ss:t.s(this.$d.seconds,2,"0"),SSS:t.s(this.$d.milliseconds,3,"0")};return D.replace(s,function(O,B){return B||String(N[O])})},p.as=function(o){return this.$ms/l[a(o)]},p.get=function(o){var D=this.$ms,N=a(o);return N==="milliseconds"?D%=1e3:D=N==="weeks"?E(D/l[N]):this.$d[N],D||0},p.add=function(o,D,N){var O;return O=D?o*l[a(D)]:x(o)?o.$ms:v(o,this).$ms,v(this.$ms+O*(N?-1:1),this)},p.subtract=function(o,D){return this.add(o,D,!0)},p.locale=function(o){var D=this.clone();return D.$l=o,D},p.clone=function(){return v(this.$ms,this)},p.humanize=function(o){return e().add(this.$ms,"ms").locale(this.$l).fromNow(!o)},p.valueOf=function(){return this.asMilliseconds()},p.milliseconds=function(){return this.get("milliseconds")},p.asMilliseconds=function(){return this.as("milliseconds")},p.seconds=function(){return this.get("seconds")},p.asSeconds=function(){return this.as("seconds")},p.minutes=function(){return this.get("minutes")},p.asMinutes=function(){return this.as("minutes")},p.hours=function(){return this.get("hours")},p.asHours=function(){return this.as("hours")},p.days=function(){return this.get("days")},p.asDays=function(){return this.as("days")},p.weeks=function(){return this.get("weeks")},p.asWeeks=function(){return this.as("weeks")},p.months=function(){return this.get("months")},p.asMonths=function(){return this.as("months")},p.years=function(){return this.get("years")},p.asYears=function(){return this.as("years")},S}(),q=function(S,p,o){return S.add(p.years()*o,"y").add(p.months()*o,"M").add(p.days()*o,"d").add(p.hours()*o,"h").add(p.minutes()*o,"m").add(p.seconds()*o,"s").add(p.milliseconds()*o,"ms")};return function(S,p,o){e=o,t=o().$utils(),o.duration=function(O,B){var J=o.locale();return v(O,{$l:J},B)},o.isDuration=x;var D=p.prototype.add,N=p.prototype.subtract;p.prototype.add=function(O,B){return x(O)?q(this,O,1):D.bind(this)(O,B)},p.prototype.subtract=function(O,B){return x(O)?q(this,O,-1):N.bind(this)(O,B)}}})});var $t=U((Ee,Ie)=>{(function(e,t){typeof Ee=="object"&&typeof Ie<"u"?Ie.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_advancedFormat=t()})(Ee,function(){"use strict";return function(e,t){var r=t.prototype,n=r.format;r.format=function(i){var u=this,s=this.$locale();if(!this.isValid())return n.bind(this)(i);var f=this.$utils(),w=(i||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(g){switch(g){case"Q":return Math.ceil((u.$M+1)/3);case"Do":return s.ordinal(u.$D);case"gggg":return u.weekYear();case"GGGG":return u.isoWeekYear();case"wo":return s.ordinal(u.week(),"W");case"w":case"ww":return f.s(u.week(),g==="w"?1:2,"0");case"W":case"WW":return f.s(u.isoWeek(),g==="W"?1:2,"0");case"k":case"kk":return f.s(String(u.$H===0?24:u.$H),g==="k"?1:2,"0");case"X":return Math.floor(u.$d.getTime()/1e3);case"x":return u.$d.getTime();case"z":return"["+u.offsetName()+"]";case"zzz":return"["+u.offsetName("long")+"]";default:return g}});return n.bind(this)(w)}}})});var bt=U((_e,We)=>{(function(e,t){typeof _e=="object"&&typeof We<"u"?We.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_isoWeek=t()})(_e,function(){"use strict";var e="day";return function(t,r,n){var i=function(f){return f.add(4-f.isoWeekday(),e)},u=r.prototype;u.isoWeekYear=function(){return i(this).year()},u.isoWeek=function(f){if(!this.$utils().u(f))return this.add(7*(f-this.isoWeek()),e);var w,g,l,x,v=i(this),a=(w=this.isoWeekYear(),g=this.$u,l=(g?n.utc:n)().year(w).startOf("year"),x=4-l.isoWeekday(),l.isoWeekday()>4&&(x+=7),l.add(x,e));return v.diff(a,"week")+1},u.isoWeekday=function(f){return this.$utils().u(f)?this.day()||7:this.day(this.day()%7?f:f-7)};var s=u.startOf;u.startOf=function(f,w){var g=this.$utils(),l=!!g.u(w)||w;return g.p(f)==="isoweek"?l?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):s.bind(this)(f,w)}}})});var wt=U((Fe,He)=>{(function(e,t){typeof Fe=="object"&&typeof He<"u"?He.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekYear=t()})(Fe,function(){"use strict";return function(e,t){t.prototype.weekYear=function(){var r=this.month(),n=this.week(),i=this.year();return n===1&&r===11?i+1:r===0&&n>=52?i-1:i}}})});var Ot=U((Be,Le)=>{(function(e,t){typeof Be=="object"&&typeof Le<"u"?Le.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekOfYear=t()})(Be,function(){"use strict";var e="week",t="year";return function(r,n,i){var u=n.prototype;u.week=function(s){if(s===void 0&&(s=null),s!==null)return this.add(7*(s-this.week()),"day");var f=this.$locale().yearStart||1;if(this.month()===11&&this.date()>25){var w=i(this).startOf(t).add(1,t).date(f),g=i(this).endOf(e);if(w.isBefore(g))return 1}var l=i(this).startOf(t).date(f).startOf(e).subtract(1,"millisecond"),x=this.diff(l,e,!0);return x<0?i(this).startOf("week").week():Math.ceil(x)},u.weeks=function(s){return s===void 0&&(s=null),this.week(s)}}})});var xt=U((ze,Pe)=>{(function(e,t){typeof ze=="object"&&typeof Pe<"u"?Pe.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_relativeTime=t()})(ze,function(){"use strict";return function(e,t,r){e=e||{};var n=t.prototype,i={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function u(f,w,g,l){return n.fromToBase(f,w,g,l)}r.en.relativeTime=i,n.fromToBase=function(f,w,g,l,x){for(var v,a,T,E=g.$locale().relativeTime||i,I=e.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],Y=I.length,F=0;F0,S<=q.r||!q.r){S<=1&&F>0&&(q=I[F-1]);var p=E[q.l];x&&(S=x(""+S)),a=typeof p=="string"?p.replace("%d",S):p(S,w,q.l,T);break}}if(w)return a;var o=T?E.future:E.past;return typeof o=="function"?o(a):o.replace("%s",a)},n.to=function(f,w){return u(f,w,this,!0)},n.from=function(f,w){return u(f,w,this)};var s=function(f){return f.$u?r.utc():r()};n.toNow=function(f){return this.to(s(this),f)},n.fromNow=function(f){return this.from(s(this),f)}}})});var St=U((Re,Je)=>{(function(e,t){typeof Re=="object"&&typeof Je<"u"?Je.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_utc=t()})(Re,function(){"use strict";var e="minute",t=/[+-]\d\d(?::?\d\d)?/g,r=/([+-]|\d\d)/g;return function(n,i,u){var s=i.prototype;u.utc=function(a){var T={date:a,utc:!0,args:arguments};return new i(T)},s.utc=function(a){var T=u(this.toDate(),{locale:this.$L,utc:!0});return a?T.add(this.utcOffset(),e):T},s.local=function(){return u(this.toDate(),{locale:this.$L,utc:!1})};var f=s.parse;s.parse=function(a){a.utc&&(this.$u=!0),this.$utils().u(a.$offset)||(this.$offset=a.$offset),f.call(this,a)};var w=s.init;s.init=function(){if(this.$u){var a=this.$d;this.$y=a.getUTCFullYear(),this.$M=a.getUTCMonth(),this.$D=a.getUTCDate(),this.$W=a.getUTCDay(),this.$H=a.getUTCHours(),this.$m=a.getUTCMinutes(),this.$s=a.getUTCSeconds(),this.$ms=a.getUTCMilliseconds()}else w.call(this)};var g=s.utcOffset;s.utcOffset=function(a,T){var E=this.$utils().u;if(E(a))return this.$u?0:E(this.$offset)?g.call(this):this.$offset;if(typeof a=="string"&&(a=function(q){q===void 0&&(q="");var S=q.match(t);if(!S)return null;var p=(""+S[0]).match(r)||["-",0,0],o=p[0],D=60*+p[1]+ +p[2];return D===0?0:o==="+"?D:-D}(a),a===null))return this;var I=Math.abs(a)<=16?60*a:a,Y=this;if(T)return Y.$offset=I,Y.$u=a===0,Y;if(a!==0){var F=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();(Y=this.local().add(I+F,e)).$offset=I,Y.$x.$localOffset=F}else Y=this.utc();return Y};var l=s.format;s.format=function(a){var T=a||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return l.call(this,T)},s.valueOf=function(){var a=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*a},s.isUTC=function(){return!!this.$u},s.toISOString=function(){return this.toDate().toISOString()},s.toString=function(){return this.toDate().toUTCString()};var x=s.toDate;s.toDate=function(a){return a==="s"&&this.$offset?u(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():x.call(this)};var v=s.diff;s.diff=function(a,T,E){if(a&&this.$u===a.$u)return v.call(this,a,T,E);var I=this.local(),Y=u(a).local();return v.call(I,Y,T,E)}}})});var Nt=U((Ge,Ze)=>{(function(e,t){typeof Ge=="object"&&typeof Ze<"u"?Ze.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_timezone=t()})(Ge,function(){"use strict";var e={year:0,month:1,day:2,hour:3,minute:4,second:5},t={};return function(r,n,i){var u,s=function(l,x,v){v===void 0&&(v={});var a=new Date(l),T=function(E,I){I===void 0&&(I={});var Y=I.timeZoneName||"short",F=E+"|"+Y,q=t[F];return q||(q=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:E,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:Y}),t[F]=q),q}(x,v);return T.formatToParts(a)},f=function(l,x){for(var v=s(l,x),a=[],T=0;T=0&&(a[F]=parseInt(Y,10))}var q=a[3],S=q===24?0:q,p=a[0]+"-"+a[1]+"-"+a[2]+" "+S+":"+a[4]+":"+a[5]+":000",o=+l;return(i.utc(p).valueOf()-(o-=o%1e3))/6e4},w=n.prototype;w.tz=function(l,x){l===void 0&&(l=u);var v=this.utcOffset(),a=this.toDate(),T=a.toLocaleString("en-US",{timeZone:l}),E=Math.round((a-new Date(T))/1e3/60),I=i(T,{locale:this.$L}).$set("millisecond",this.$ms).utcOffset(15*-Math.round(a.getTimezoneOffset()/15)-E,!0);if(x){var Y=I.utcOffset();I=I.add(v-Y,"minute")}return I.$x.$timezone=l,I},w.offsetName=function(l){var x=this.$x.$timezone||i.tz.guess(),v=s(this.valueOf(),x,{timeZoneName:l}).find(function(a){return a.type.toLowerCase()==="timezonename"});return v&&v.value};var g=w.startOf;w.startOf=function(l,x){if(!this.$x||!this.$x.$timezone)return g.call(this,l,x);var v=i(this.format("YYYY-MM-DD HH:mm:ss:SSS"),{locale:this.$L});return g.call(v,l,x).tz(this.$x.$timezone,!0)},i.tz=function(l,x,v){var a=v&&x,T=v||x||u,E=f(+i(),T);if(typeof l!="string")return i(l).tz(T);var I=function(S,p,o){var D=S-60*p*1e3,N=f(D,o);if(p===N)return[D,p];var O=f(D-=60*(N-p)*1e3,o);return N===O?[D,N]:[S-60*Math.min(N,O)*1e3,Math.max(N,O)]}(i.utc(l,a).valueOf(),E,T),Y=I[0],F=I[1],q=i(Y).utcOffset(F);return q.$x.$timezone=T,q},i.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},i.tz.setDefault=function(l){u=l}}})});var jt=U((Di,Ke)=>{var X=yt();X.extend(vt());X.extend($t());X.extend(bt());X.extend(wt());X.extend(Ot());X.extend(xt());X.extend(St());X.extend(Nt());function fe(e){return typeof e=="object"&&typeof e.hash=="object"}function Ve(e){return typeof e=="object"&&typeof e.options=="object"&&typeof e.app=="object"}function Qe(e,t,r){if(fe(e))return Qe({},t,e);if(fe(t))return Qe(e,r,t);let n=Ve(e)?e.context:{};r=r||{},fe(r)||(t=Object.assign({},t,r)),fe(r)&&r.hash.root===!0&&(t=Object.assign({},r.data.root,t));let i=Object.assign({},n,t,r.hash);return Ve(e)||(i=Object.assign({},e,i)),Ve(e)&&e.view&&e.view.data&&(i=Object.assign({},i,e.view.data)),i}function Xe(e,t,r){return fe(t)&&(r=t,t=null),fe(e)&&(r=e,t=null,e=null),{str:e,pattern:t,options:r}}function Mt(e,t,r){let n=Xe(e,t,r),i={lang:"en",date:new Date(n.str)},u=Qe(this,i,{});X.locale(u.lang||u.language)}Ke.exports.date=(e,t,r)=>{let n=Xe(e,t,r);if(n.str==null&&n.pattern==null)return X.locale("en"),X().format("MMMM DD, YYYY");Mt(n.str,n.pattern,n.options);let i=X(new Date(n.str));return typeof n.options=="string"?i=n.options.toLowerCase()==="utc"?i.utc():i.tz(n.options):i=i.tz(X.tz.guess()),n.pattern===""?i.toISOString():i.format(n.pattern)};Ke.exports.duration=(e,t,r)=>{let n=Xe(e,t);Mt(n.str,n.pattern);let i=X.duration(n.str,n.pattern);return r&&!fe(r)?i.format(r):i.humanize()}});var et=U((Ui,kt)=>{kt.exports=function(e){return e!=null&&(At(e)||mn(e)||!!e._isBuffer)};function At(e){return!!e.constructor&&typeof e.constructor.isBuffer=="function"&&e.constructor.isBuffer(e)}function mn(e){return typeof e.readFloatLE=="function"&&typeof e.slice=="function"&&At(e.slice(0,0))}});var Ut=U((Ti,Dt)=>{var gn=et(),yn=Object.prototype.toString;Dt.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=yn.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":gn(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var Ct=U((qi,Yt)=>{"use strict";var Tt=Ut(),qt={arguments:"an arguments object",array:"an array",boolean:"a boolean",buffer:"a buffer",date:"a date",error:"an error",float32array:"a float32array",float64array:"a float64array",function:"a function",int16array:"an int16array",int32array:"an int32array",int8array:"an int8array",map:"a Map",null:"null",number:"a number",object:"an object",regexp:"a regular expression",set:"a Set",string:"a string",symbol:"a symbol",uint16array:"an uint16array",uint32array:"an uint32array",uint8array:"an uint8array",uint8clampedarray:"an uint8clampedarray",undefined:"undefined",weakmap:"a WeakMap",weakset:"a WeakSet"};function tt(e){return qt[Tt(e)]}tt.types=qt;tt.typeOf=Tt;Yt.exports=tt});var Se=U((Yi,It)=>{var vn=Object.prototype.toString;It.exports=function(t){if(t===void 0)return"undefined";if(t===null)return"null";var r=typeof t;if(r==="boolean")return"boolean";if(r==="string")return"string";if(r==="number")return"number";if(r==="symbol")return"symbol";if(r==="function")return xn(t)?"generatorfunction":"function";if($n(t))return"array";if(Mn(t))return"buffer";if(Nn(t))return"arguments";if(wn(t))return"date";if(bn(t))return"error";if(On(t))return"regexp";switch(Et(t)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(Sn(t))return"generator";switch(r=vn.call(t),r){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return r.slice(8,-1).toLowerCase().replace(/\s/g,"")};function Et(e){return typeof e.constructor=="function"?e.constructor.name:null}function $n(e){return Array.isArray?Array.isArray(e):e instanceof Array}function bn(e){return e instanceof Error||typeof e.message=="string"&&e.constructor&&typeof e.constructor.stackTraceLimit=="number"}function wn(e){return e instanceof Date?!0:typeof e.toDateString=="function"&&typeof e.getDate=="function"&&typeof e.setDate=="function"}function On(e){return e instanceof RegExp?!0:typeof e.flags=="string"&&typeof e.ignoreCase=="boolean"&&typeof e.multiline=="boolean"&&typeof e.global=="boolean"}function xn(e,t){return Et(e)==="GeneratorFunction"}function Sn(e){return typeof e.throw=="function"&&typeof e.return=="function"&&typeof e.next=="function"}function Nn(e){try{if(typeof e.length=="number"&&typeof e.callee=="function")return!0}catch(t){if(t.message.indexOf("callee")!==-1)return!0}return!1}function Mn(e){return e.constructor&&typeof e.constructor.isBuffer=="function"?e.constructor.isBuffer(e):!1}});var ee=U((Ft,Ht)=>{"use strict";var jn=Ue("util"),_t=Ct(),An=Se(),m=Ft=Ht.exports;m.extend=Wt;m.indexOf=Yn;m.escapeExpression=Cn;m.isEmpty=Wn;m.createFrame=En;m.blockParams=In;m.appendContextPath=_n;var kn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`","=":"="},Dn=/[&<>"'`=]/g,Un=/[&<>"'`=]/;function Tn(e){return kn[e]}function Wt(e){for(var t=1;t{"use strict";var Fn=ee();he.contains=function(e,t,r){return e==null||t==null||isNaN(e.length)?!1:e.indexOf(t,r)!==-1};he.chop=function(e){if(typeof e!="string")return"";var t=/^[-_.\W\s]+|[-_.\W\s]+$/g;return e.trim().replace(t,"")};he.changecase=function(e,t){if(typeof e!="string")return"";if(e.length===1)return e.toLowerCase();e=he.chop(e).toLowerCase(),typeof t!="function"&&(t=Fn.identity);var r=/[-_.\W\s]+(\w|$)/g;return e.replace(r,function(n,i){return t(i)})};he.random=function(e,t){return e+Math.floor(Math.random()*(t-e+1))}});var Lt=U((Ei,Bt)=>{"use strict";var Hn=Ne(),V=Bt.exports;V.abs=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.abs(e)};V.add=function(e,t){return!isNaN(e)&&!isNaN(t)?Number(e)+Number(t):typeof e=="string"&&typeof t=="string"?e+t:""};V.avg=function(){let e=[].concat.apply([],arguments);return e.pop(),V.sum(e)/e.length};V.ceil=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.ceil(e)};V.divide=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)/Number(t)};V.floor=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.floor(e)};V.minus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.modulo=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)%Number(t)};V.multiply=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)*Number(t)};V.plus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)+Number(t)};V.random=function(e,t){if(isNaN(e))throw new TypeError("expected minimum to be a number");if(isNaN(t))throw new TypeError("expected maximum to be a number");return Hn.random(e,t)};V.remainder=function(e,t){return e%t};V.round=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.round(e)};V.subtract=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.sum=function(){for(var e=[].concat.apply([],arguments),t=e.length,r=0;t--;)isNaN(e[t])||(r+=Number(e[t]));return r}});var Pt=U((Ii,zt)=>{"use strict";zt.exports=function(t){return t!=null&&typeof t=="object"&&Array.isArray(t)===!1}});var Me=U((_i,Zt)=>{var Gt=Pt();Zt.exports=function(e,t,r){if(Gt(r)||(r={default:r}),!Jt(e))return typeof r.default<"u"?r.default:e;typeof t=="number"&&(t=String(t));let n=Array.isArray(t),i=typeof t=="string",u=r.separator||".",s=r.joinChar||(typeof u=="string"?u:".");if(!i&&!n)return e;if(i&&t in e)return it(t,e,r)?e[t]:r.default;let f=n?t:Bn(t,u,r),w=f.length,g=0;do{let l=f[g];for(typeof l=="number"&&(l=String(l));l&&l.slice(-1)==="\\";)l=Rt([l.slice(0,-1),f[++g]||""],s,r);if(l in e){if(!it(l,e,r))return r.default;e=e[l]}else{let x=!1,v=g+1;for(;v{"use strict";Vt.exports=function(t){if(typeof t!="object")throw new TypeError("createFrame expects data to be an object");var r=Object.assign({},t);if(r._parent=t,r.extend=function(s){Object.assign(this,s)},arguments.length>1)for(var n=[].slice.call(arguments,1),i=n.length,u=-1;++u{"use strict";var y=ee(),C=Qt.exports,oe=Me(),Ln=ut();C.after=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(t):"")};C.arrayify=function(e){return y.isUndefined(e)?[]:e?Array.isArray(e)?e:[e]:[]};C.before=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(0,t-1):"")};C.eachIndex=function(e,t){var r="";if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e))for(var n=0;n0){for(var s=0;s-1,this,r):"")};C.isArray=function(e){return Array.isArray(e)};C.itemAt=function(e,t){if(y.isUndefined(e))return null;if(e=y.result(e),Array.isArray(e)){if(t=isNaN(t)?0:+t,t<0)return e[e.length+t];if(ti[t]>u[t]?1:-1)}return""};C.withAfter=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){e=e.slice(t);for(var n="",i=0;i0){for(var i=[],u=0;u0&&u%t===0&&(n+=r.fn(i),i=[]),i.push(e[u]);n+=r.fn(i)}return n};C.withLast=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){if(y.isUndefined(t)||(t=parseFloat(y.result(t))),y.isUndefined(t))return r=t,r.fn(e[e.length-1]);e=e.slice(-t);for(var n=e.length,i=-1,u="";++ig?1:w{"use strict";var Xt=ee(),te=Kt.exports;te.bytes=function(e,t,r){if(e==null||isNaN(e)&&(e=e.length,!e))return"0 B";isNaN(t)&&(t=2);var n=["B","kB","MB","GB","TB","PB","EB","ZB","YB"];t=Math.pow(10,t),e=Number(e);for(var i=n.length-1;i-->=0;){var u=Math.pow(10,i*3);if(u<=e+1){e=Math.round(e*t/u)/t,e+=" "+n[i];break}}return e};te.addCommas=function(e){return e.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")};te.phoneNumber=function(e){return e=e.toString(),"("+e.substr(0,3)+") "+e.substr(3,3)+"-"+e.substr(6,4)};te.toAbbr=function(e,t){isNaN(e)&&(e=0),Xt.isUndefined(t)&&(t=2),e=Number(e),t=Math.pow(10,t);for(var r=["k","m","b","t","q"],n=r.length-1;n>=0;){var i=Math.pow(10,(n+1)*3);if(i<=e+1){e=Math.round(e*t/i)/t,e+=r[n];break}n--}return e};te.toExponential=function(e,t){return isNaN(e)&&(e=0),Xt.isUndefined(t)&&(t=0),Number(e).toExponential(t)};te.toFixed=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=0),Number(e).toFixed(t)};te.toFloat=function(e){return parseFloat(e)};te.toInt=function(e){return parseInt(e,10)};te.toPrecision=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=1),Number(e).toPrecision(t)}});var rr=U((Bi,tr)=>{"use strict";var st=Ue("url"),ge=ee(),zn=Ue("querystring"),ae=tr.exports;ae.encodeURI=function(e){if(ge.isString(e))return encodeURIComponent(e)};ae.escape=function(e){if(ge.isString(e))return zn.escape(e)};ae.decodeURI=function(e){if(ge.isString(e))return decodeURIComponent(e)};ae.urlResolve=function(e,t){return st.resolve(e,t)};ae.urlParse=function(e){return st.parse(e)};ae.stripQuerystring=function(e){if(ge.isString(e))return e.split("?")[0]};ae.stripProtocol=function(e){if(ge.isString(e)){var t=st.parse(e);return t.protocol="",t.format()}}});var ur=U((nr,ir)=>{"use strict";var z=ee(),ce=Ne(),A=ir.exports;A.append=function(e,t){return typeof e=="string"&&typeof t=="string"?e+t:e};A.camelcase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return t.toUpperCase()})};A.capitalize=function(e){return typeof e!="string"?"":e.charAt(0).toUpperCase()+e.slice(1)};A.capitalizeAll=function(e){if(typeof e!="string")return"";if(z.isString(e))return e.replace(/\w\S*/g,function(t){return A.capitalize(t)})};A.center=function(e,t){if(typeof e!="string")return"";for(var r="",n=0;n-1;)i++,n+=r;return i};A.pascalcase=function(e){return typeof e!="string"?"":(e=ce.changecase(e,function(t){return t.toUpperCase()}),e.charAt(0).toUpperCase()+e.slice(1))};A.pathcase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return"/"+t})};A.plusify=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=" "),e.split(t).join("+"))};A.prepend=function(e,t){return typeof e=="string"&&typeof t=="string"?t+e:e};A.raw=function(e){var t=e.fn(),r=z.options(this,e);if(r.escape!==!1)for(var n=0;(n=t.indexOf("{{",n))!==-1;)t[n-1]!=="\\"&&(t=t.slice(0,n)+"\\"+t.slice(n)),n+=3;return t};A.remove=function(e,t){return typeof e!="string"?"":z.isString(t)?e.split(t).join(""):e};A.removeFirst=function(e,t){return typeof e!="string"?"":z.isString(t)?e.replace(t,""):e};A.replace=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.split(t).join(r)):e};A.replaceFirst=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.replace(t,r)):e};A.reverse=je().reverse;A.sentence=function(e){return typeof e!="string"?"":e.replace(/((?:\S[^\.\?\!]*)[\.\?\!]*)/g,function(t){return t.charAt(0).toUpperCase()+t.substr(1).toLowerCase()})};A.snakecase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return"_"+t})};A.split=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=","),e.split(t))};A.startsWith=function(e,t,r){var n=[].slice.call(arguments);return r=n.pop(),z.isString(t)&&t.indexOf(e)===0?r.fn(this):typeof r.inverse=="function"?r.inverse(this):""};A.titleize=function(e){if(typeof e!="string")return"";for(var t=e.replace(/[- _]+/g," "),r=t.split(" "),n=r.length,i=[],u=0;n--;){var s=r[u++];i.push(nr.capitalize(s))}return i.join(" ")};A.trim=function(e){return typeof e=="string"?e.trim():""};A.trimLeft=function(e){if(z.isString(e))return e.replace(/^\s+/,"")};A.trimRight=function(e){if(z.isString(e))return e.replace(/\s+$/,"")};A.truncate=function(e,t,r){if(z.isString(e))return typeof r!="string"&&(r=""),e.length>t?e.slice(0,t-r.length)+r:e};A.truncateWords=function(e,t,r){if(z.isString(e)&&!isNaN(t)){typeof r!="string"&&(r="\u2026");var n=Number(t),i=e.split(/[ \t]/);if(n>=i.length)return e;i=i.slice(0,n);var u=i.join(" ").trim();return u+r}};A.upcase=function(){return A.uppercase.apply(this,arguments)};A.uppercase=function(e){return z.isObject(e)&&e.fn?e.fn(this).toUpperCase():typeof e!="string"?"":e.toUpperCase()}});var fr=U((Li,sr)=>{"use strict";var Pn=Se();sr.exports=function e(t){switch(Pn(t)){case"boolean":case"date":case"function":case"null":case"number":return!0;case"undefined":return!1;case"regexp":return t.source!=="(?:)"&&t.source!=="";case"buffer":return t.toString()!=="";case"error":return t.message!=="";case"string":case"arguments":return t.length!==0;case"file":case"map":case"set":return t.size!==0;case"array":case"object":for(let r of Object.keys(t))if(e(t[r]))return!0;return!1;default:return!0}}});var ar=U((zi,or)=>{"use strict";var Rn=Me(),Jn=fr();or.exports=function(e,t,r){return Gn(e)&&(typeof t=="string"||Array.isArray(t))?Jn(Rn(e,t,r)):!1};function Gn(e){return e!=null&&(typeof e=="object"||typeof e=="function"||Array.isArray(e))}});var lr=U((Pi,cr)=>{"use strict";function ft(e,t){if(!e)return!0;let r=t||ft.keywords;Array.isArray(r)||(r=[r]);let n=typeof e=="string"?e.toLowerCase():null;for(let i of r)if(i===e||i===n)return!0;return!1}ft.keywords=["0","false","nada","nil","nay","nah","negative","no","none","nope","nul","null","nix","nyet","uh-uh","veto","zero"];cr.exports=ft});var hr=U((Ri,dr)=>{"use strict";dr.exports=function(t){let r=Math.abs(t);if(isNaN(r))throw new TypeError("expected a number");if(!Number.isInteger(r))throw new Error("expected an integer");if(!Number.isSafeInteger(r))throw new Error("value exceeds maximum safe integer");return r%2===1}});var yr=U((Ji,gr)=>{"use strict";var Zn=ar(),k=ee(),Vn=Ne(),pr=lr(),mr=hr(),W=gr.exports;W.and=function(){for(var e=arguments.length-1,t=arguments[e],r=!0,n=0;n":i=e>r;break;case"<=":i=e<=r;break;case">=":i=e>=r;break;case"typeof":i=typeof e===r;break;default:throw new Error("helper {{compare}}: invalid operator: `"+t+"`")}return k.value(i,this,n)};W.contains=function(e,t,r,n){typeof r=="object"&&(n=r,r=void 0);var i=Vn.contains(e,t,r);return k.value(i,this,n)};W.default=function(){for(var e=0;et,this,r)};W.gte=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e>=t,this,r)};W.has=function(e,t,r){return k.isOptions(e)&&(r=e,t=null,e=null),k.isOptions(t)&&(r=t,t=null),e===null?k.value(!1,this,r):arguments.length===2?k.value(Zn(this,e),this,r):(Array.isArray(e)||k.isString(e))&&k.isString(t)&&e.indexOf(t)>-1?k.fn(!0,this,r):k.isObject(e)&&k.isString(t)&&t in e?k.fn(!0,this,r):k.inverse(!1,this,r)};W.isFalsey=function(e,t){return k.value(pr(e),this,t)};W.isTruthy=function(e,t){return k.value(!pr(e),this,t)};W.ifEven=function(e,t){return k.value(!mr(e),this,t)};W.ifNth=function(e,t,r){var n=!isNaN(e)&&!isNaN(t)&&t%e===0;return k.value(n,this,r)};W.ifOdd=function(e,t){return k.value(mr(e),this,t)};W.is=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e==t,this,r)};W.isnt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e!=t,this,r)};W.lt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e=t,this,r)};W.unlessGteq=function(e,t,r){return k.isOptions(t)&&(r=t,t=r.hash.compare),k.value(et,this,r)}});var $r=U((Gi,vr)=>{var Qn=et(),Xn=Object.prototype.toString;vr.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=Xn.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":Qn(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var wr=U((Zi,br)=>{"use strict";var Kn=$r();br.exports=function(t){var r=Kn(t);if(r!=="number"&&r!=="string")return!1;var n=+t;return n-n+1>=0&&t!==""}});var xr=U((Vi,Or)=>{"use strict";var ei=wr();Or.exports=function(t,r){if(!r)return t;if(!t)return{};for(var n=String(r).split(/[[.\]]/).filter(Boolean),i=n[n.length-1],u={};r=n.shift();)if(t=t[r],!t)return{};return ei(i)?[t]:(u[i]=t,u)}});var jr=U((Qi,Mr)=>{"use strict";var ti=Object.hasOwnProperty,ye=ee(),ri=je(),P=Mr.exports,ni=Me(),Sr=xr(),Nr=ut();P.extend=function(){var e=[].slice.call(arguments),t={};ye.isOptions(e[e.length-1])&&(t=e.pop().hash,e.push(t));for(var r={},n=0;n{"use strict";var ii=ee(),Ar=kr.exports,ui=Se();Ar.toRegex=function(e,t,r){var n=ii.options({},t,r);return new RegExp(e,n.flags)};Ar.test=function(e,t){if(typeof e!="string")return!1;if(ui(t)!=="regexp")throw new TypeError("expected a regular expression");return t.test(e)}});import si from"crypto";function ve(){return Ae>ke.length-16&&(si.randomFillSync(ke),Ae=0),ke.slice(Ae,Ae+=16)}var ke,Ae,ot=Z(()=>{ke=new Uint8Array(256),Ae=ke.length});var Ur,Tr=Z(()=>{Ur=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i});function fi(e){return typeof e=="string"&&Ur.test(e)}var ne,$e=Z(()=>{Tr();ne=fi});function le(e,t=0){return R[e[t+0]]+R[e[t+1]]+R[e[t+2]]+R[e[t+3]]+"-"+R[e[t+4]]+R[e[t+5]]+"-"+R[e[t+6]]+R[e[t+7]]+"-"+R[e[t+8]]+R[e[t+9]]+"-"+R[e[t+10]]+R[e[t+11]]+R[e[t+12]]+R[e[t+13]]+R[e[t+14]]+R[e[t+15]]}function oi(e,t=0){let r=le(e,t);if(!ne(r))throw TypeError("Stringified UUID is invalid");return r}var R,qr,be=Z(()=>{$e();R=[];for(let e=0;e<256;++e)R.push((e+256).toString(16).slice(1));qr=oi});function ai(e,t,r){let n=t&&r||0,i=t||new Array(16);e=e||{};let u=e.node||Yr,s=e.clockseq!==void 0?e.clockseq:at;if(u==null||s==null){let v=e.random||(e.rng||ve)();u==null&&(u=Yr=[v[0]|1,v[1],v[2],v[3],v[4],v[5]]),s==null&&(s=at=(v[6]<<8|v[7])&16383)}let f=e.msecs!==void 0?e.msecs:Date.now(),w=e.nsecs!==void 0?e.nsecs:lt+1,g=f-ct+(w-lt)/1e4;if(g<0&&e.clockseq===void 0&&(s=s+1&16383),(g<0||f>ct)&&e.nsecs===void 0&&(w=0),w>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");ct=f,lt=w,at=s,f+=122192928e5;let l=((f&268435455)*1e4+w)%4294967296;i[n++]=l>>>24&255,i[n++]=l>>>16&255,i[n++]=l>>>8&255,i[n++]=l&255;let x=f/4294967296*1e4&268435455;i[n++]=x>>>8&255,i[n++]=x&255,i[n++]=x>>>24&15|16,i[n++]=x>>>16&255,i[n++]=s>>>8|128,i[n++]=s&255;for(let v=0;v<6;++v)i[n+v]=u[v];return t||le(i)}var Yr,at,ct,lt,Cr,Er=Z(()=>{ot();be();ct=0,lt=0;Cr=ai});function ci(e){if(!ne(e))throw TypeError("Invalid UUID");let t,r=new Uint8Array(16);return r[0]=(t=parseInt(e.slice(0,8),16))>>>24,r[1]=t>>>16&255,r[2]=t>>>8&255,r[3]=t&255,r[4]=(t=parseInt(e.slice(9,13),16))>>>8,r[5]=t&255,r[6]=(t=parseInt(e.slice(14,18),16))>>>8,r[7]=t&255,r[8]=(t=parseInt(e.slice(19,23),16))>>>8,r[9]=t&255,r[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255,r[11]=t/4294967296&255,r[12]=t>>>24&255,r[13]=t>>>16&255,r[14]=t>>>8&255,r[15]=t&255,r}var De,dt=Z(()=>{$e();De=ci});function li(e){e=unescape(encodeURIComponent(e));let t=[];for(let r=0;r{be();dt();di="6ba7b810-9dad-11d1-80b4-00c04fd430c8",hi="6ba7b811-9dad-11d1-80b4-00c04fd430c8"});import pi from"crypto";function mi(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),pi.createHash("md5").update(e).digest()}var Ir,_r=Z(()=>{Ir=mi});var gi,Wr,Fr=Z(()=>{ht();_r();gi=we("v3",48,Ir),Wr=gi});import yi from"crypto";var pt,Hr=Z(()=>{pt={randomUUID:yi.randomUUID}});function vi(e,t,r){if(pt.randomUUID&&!t&&!e)return pt.randomUUID();e=e||{};let n=e.random||(e.rng||ve)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,t){r=r||0;for(let i=0;i<16;++i)t[r+i]=n[i];return t}return le(n)}var Br,Lr=Z(()=>{Hr();ot();be();Br=vi});import $i from"crypto";function bi(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),$i.createHash("sha1").update(e).digest()}var zr,Pr=Z(()=>{zr=bi});var wi,Rr,Jr=Z(()=>{ht();Pr();wi=we("v5",80,zr),Rr=wi});var Gr,Zr=Z(()=>{Gr="00000000-0000-0000-0000-000000000000"});function Oi(e){if(!ne(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var Vr,Qr=Z(()=>{$e();Vr=Oi});var Xr={};dn(Xr,{NIL:()=>Gr,parse:()=>De,stringify:()=>qr,v1:()=>Cr,v3:()=>Wr,v4:()=>Br,v5:()=>Rr,validate:()=>ne,version:()=>Vr});var Kr=Z(()=>{Er();Fr();Lr();Jr();Zr();Qr();$e();be();dt()});var tn=U((Bu,en)=>{var xi=(Kr(),pn(Xr)),Si=en.exports;Si.uuid=function(){return xi.v4()}});var un=U((Lu,mt)=>{var{date:Ni,duration:Mi}=jt(),ji={math:Lt(),array:je(),number:er(),url:rr(),string:ur(),comparison:yr(),object:jr(),regex:Dr(),uuid:tn()},nn=["sortBy"];mt.exports.helpersToRemoveForJs=nn;var rn={date:Ni,duration:Mi},ie;mt.exports.getJsHelperList=()=>{if(ie)return ie;ie={};for(let e of Object.values(ji))for(let[t,r]of Object.entries(e))ie[t]=(...n)=>r(...n,{});for(let e of Object.keys(rn))ie[e]=rn[e];for(let e of nn)delete ie[e];return Object.freeze(ie),ie}});var sn=hn(un()),Ai=(0,sn.getJsHelperList)(),zu={...Ai,stripProtocol:helpersStripProtocol};export{zu as default}; +var De=Object.defineProperty;var un=Object.getOwnPropertyDescriptor;var sn=Object.getOwnPropertyNames;var fn=Object.prototype.hasOwnProperty;var Ue=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Z=(e,t)=>()=>(e&&(t=e(e=0)),t);var U=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),on=(e,t)=>{for(var r in t)De(e,r,{get:t[r],enumerable:!0})},an=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of sn(t))!fn.call(e,i)&&i!==r&&De(e,i,{get:()=>t[i],enumerable:!(n=un(t,i))||n.enumerable});return e};var cn=e=>an(De({},"__esModule",{value:!0}),e);var gt=U((Te,qe)=>{(function(e,t){typeof Te=="object"&&typeof qe<"u"?qe.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs=t()})(Te,function(){"use strict";var e=1e3,t=6e4,r=36e5,n="millisecond",i="second",u="minute",s="hour",f="day",w="week",g="month",l="quarter",x="year",v="date",a="Invalid Date",T=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,E=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,I={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function($){var h=["th","st","nd","rd"],c=$%100;return"["+$+(h[(c-20)%10]||h[c]||h[0])+"]"}},Y=function($,h,c){var b=String($);return!b||b.length>=h?$:""+Array(h+1-b.length).join(c)+$},F={s:Y,z:function($){var h=-$.utcOffset(),c=Math.abs(h),b=Math.floor(c/60),d=c%60;return(h<=0?"+":"-")+Y(b,2,"0")+":"+Y(d,2,"0")},m:function $(h,c){if(h.date()1)return $(j[0])}else{var _=h.name;S[_]=h,d=_}return!b&&d&&(q=d),d||!b&&q},N=function($,h){if(o($))return $.clone();var c=typeof h=="object"?h:{};return c.date=$,c.args=arguments,new B(c)},O=F;O.l=D,O.i=o,O.w=function($,h){return N($,{locale:h.$L,utc:h.$u,x:h.$x,$offset:h.$offset})};var B=function(){function $(c){this.$L=D(c.locale,null,!0),this.parse(c),this.$x=this.$x||c.x||{},this[p]=!0}var h=$.prototype;return h.parse=function(c){this.$d=function(b){var d=b.date,M=b.utc;if(d===null)return new Date(NaN);if(O.u(d))return new Date;if(d instanceof Date)return new Date(d);if(typeof d=="string"&&!/Z$/i.test(d)){var j=d.match(T);if(j){var _=j[2]-1||0,H=(j[7]||"0").substring(0,3);return M?new Date(Date.UTC(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)):new Date(j[1],_,j[3]||1,j[4]||0,j[5]||0,j[6]||0,H)}}return new Date(d)}(c),this.init()},h.init=function(){var c=this.$d;this.$y=c.getFullYear(),this.$M=c.getMonth(),this.$D=c.getDate(),this.$W=c.getDay(),this.$H=c.getHours(),this.$m=c.getMinutes(),this.$s=c.getSeconds(),this.$ms=c.getMilliseconds()},h.$utils=function(){return O},h.isValid=function(){return this.$d.toString()!==a},h.isSame=function(c,b){var d=N(c);return this.startOf(b)<=d&&d<=this.endOf(b)},h.isAfter=function(c,b){return N(c){(function(e,t){typeof Ye=="object"&&typeof Ce<"u"?Ce.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_duration=t()})(Ye,function(){"use strict";var e,t,r=1e3,n=6e4,i=36e5,u=864e5,s=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,f=31536e6,w=2628e6,g=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/,l={years:f,months:w,days:u,hours:i,minutes:n,seconds:r,milliseconds:1,weeks:6048e5},x=function(S){return S instanceof F},v=function(S,p,o){return new F(S,o,p.$l)},a=function(S){return t.p(S)+"s"},T=function(S){return S<0},E=function(S){return T(S)?Math.ceil(S):Math.floor(S)},I=function(S){return Math.abs(S)},Y=function(S,p){return S?T(S)?{negative:!0,format:""+I(S)+p}:{negative:!1,format:""+S+p}:{negative:!1,format:""}},F=function(){function S(o,D,N){var O=this;if(this.$d={},this.$l=N,o===void 0&&(this.$ms=0,this.parseFromMilliseconds()),D)return v(o*l[a(D)],this);if(typeof o=="number")return this.$ms=o,this.parseFromMilliseconds(),this;if(typeof o=="object")return Object.keys(o).forEach(function($){O.$d[a($)]=o[$]}),this.calMilliseconds(),this;if(typeof o=="string"){var B=o.match(g);if(B){var J=B.slice(2).map(function($){return $!=null?Number($):0});return this.$d.years=J[0],this.$d.months=J[1],this.$d.weeks=J[2],this.$d.days=J[3],this.$d.hours=J[4],this.$d.minutes=J[5],this.$d.seconds=J[6],this.calMilliseconds(),this}}return this}var p=S.prototype;return p.calMilliseconds=function(){var o=this;this.$ms=Object.keys(this.$d).reduce(function(D,N){return D+(o.$d[N]||0)*l[N]},0)},p.parseFromMilliseconds=function(){var o=this.$ms;this.$d.years=E(o/f),o%=f,this.$d.months=E(o/w),o%=w,this.$d.days=E(o/u),o%=u,this.$d.hours=E(o/i),o%=i,this.$d.minutes=E(o/n),o%=n,this.$d.seconds=E(o/r),o%=r,this.$d.milliseconds=o},p.toISOString=function(){var o=Y(this.$d.years,"Y"),D=Y(this.$d.months,"M"),N=+this.$d.days||0;this.$d.weeks&&(N+=7*this.$d.weeks);var O=Y(N,"D"),B=Y(this.$d.hours,"H"),J=Y(this.$d.minutes,"M"),$=this.$d.seconds||0;this.$d.milliseconds&&($+=this.$d.milliseconds/1e3,$=Math.round(1e3*$)/1e3);var h=Y($,"S"),c=o.negative||D.negative||O.negative||B.negative||J.negative||h.negative,b=B.format||J.format||h.format?"T":"",d=(c?"-":"")+"P"+o.format+D.format+O.format+b+B.format+J.format+h.format;return d==="P"||d==="-P"?"P0D":d},p.toJSON=function(){return this.toISOString()},p.format=function(o){var D=o||"YYYY-MM-DDTHH:mm:ss",N={Y:this.$d.years,YY:t.s(this.$d.years,2,"0"),YYYY:t.s(this.$d.years,4,"0"),M:this.$d.months,MM:t.s(this.$d.months,2,"0"),D:this.$d.days,DD:t.s(this.$d.days,2,"0"),H:this.$d.hours,HH:t.s(this.$d.hours,2,"0"),m:this.$d.minutes,mm:t.s(this.$d.minutes,2,"0"),s:this.$d.seconds,ss:t.s(this.$d.seconds,2,"0"),SSS:t.s(this.$d.milliseconds,3,"0")};return D.replace(s,function(O,B){return B||String(N[O])})},p.as=function(o){return this.$ms/l[a(o)]},p.get=function(o){var D=this.$ms,N=a(o);return N==="milliseconds"?D%=1e3:D=N==="weeks"?E(D/l[N]):this.$d[N],D||0},p.add=function(o,D,N){var O;return O=D?o*l[a(D)]:x(o)?o.$ms:v(o,this).$ms,v(this.$ms+O*(N?-1:1),this)},p.subtract=function(o,D){return this.add(o,D,!0)},p.locale=function(o){var D=this.clone();return D.$l=o,D},p.clone=function(){return v(this.$ms,this)},p.humanize=function(o){return e().add(this.$ms,"ms").locale(this.$l).fromNow(!o)},p.valueOf=function(){return this.asMilliseconds()},p.milliseconds=function(){return this.get("milliseconds")},p.asMilliseconds=function(){return this.as("milliseconds")},p.seconds=function(){return this.get("seconds")},p.asSeconds=function(){return this.as("seconds")},p.minutes=function(){return this.get("minutes")},p.asMinutes=function(){return this.as("minutes")},p.hours=function(){return this.get("hours")},p.asHours=function(){return this.as("hours")},p.days=function(){return this.get("days")},p.asDays=function(){return this.as("days")},p.weeks=function(){return this.get("weeks")},p.asWeeks=function(){return this.as("weeks")},p.months=function(){return this.get("months")},p.asMonths=function(){return this.as("months")},p.years=function(){return this.get("years")},p.asYears=function(){return this.as("years")},S}(),q=function(S,p,o){return S.add(p.years()*o,"y").add(p.months()*o,"M").add(p.days()*o,"d").add(p.hours()*o,"h").add(p.minutes()*o,"m").add(p.seconds()*o,"s").add(p.milliseconds()*o,"ms")};return function(S,p,o){e=o,t=o().$utils(),o.duration=function(O,B){var J=o.locale();return v(O,{$l:J},B)},o.isDuration=x;var D=p.prototype.add,N=p.prototype.subtract;p.prototype.add=function(O,B){return x(O)?q(this,O,1):D.bind(this)(O,B)},p.prototype.subtract=function(O,B){return x(O)?q(this,O,-1):N.bind(this)(O,B)}}})});var vt=U((Ee,Ie)=>{(function(e,t){typeof Ee=="object"&&typeof Ie<"u"?Ie.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_advancedFormat=t()})(Ee,function(){"use strict";return function(e,t){var r=t.prototype,n=r.format;r.format=function(i){var u=this,s=this.$locale();if(!this.isValid())return n.bind(this)(i);var f=this.$utils(),w=(i||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(g){switch(g){case"Q":return Math.ceil((u.$M+1)/3);case"Do":return s.ordinal(u.$D);case"gggg":return u.weekYear();case"GGGG":return u.isoWeekYear();case"wo":return s.ordinal(u.week(),"W");case"w":case"ww":return f.s(u.week(),g==="w"?1:2,"0");case"W":case"WW":return f.s(u.isoWeek(),g==="W"?1:2,"0");case"k":case"kk":return f.s(String(u.$H===0?24:u.$H),g==="k"?1:2,"0");case"X":return Math.floor(u.$d.getTime()/1e3);case"x":return u.$d.getTime();case"z":return"["+u.offsetName()+"]";case"zzz":return"["+u.offsetName("long")+"]";default:return g}});return n.bind(this)(w)}}})});var $t=U((_e,We)=>{(function(e,t){typeof _e=="object"&&typeof We<"u"?We.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_isoWeek=t()})(_e,function(){"use strict";var e="day";return function(t,r,n){var i=function(f){return f.add(4-f.isoWeekday(),e)},u=r.prototype;u.isoWeekYear=function(){return i(this).year()},u.isoWeek=function(f){if(!this.$utils().u(f))return this.add(7*(f-this.isoWeek()),e);var w,g,l,x,v=i(this),a=(w=this.isoWeekYear(),g=this.$u,l=(g?n.utc:n)().year(w).startOf("year"),x=4-l.isoWeekday(),l.isoWeekday()>4&&(x+=7),l.add(x,e));return v.diff(a,"week")+1},u.isoWeekday=function(f){return this.$utils().u(f)?this.day()||7:this.day(this.day()%7?f:f-7)};var s=u.startOf;u.startOf=function(f,w){var g=this.$utils(),l=!!g.u(w)||w;return g.p(f)==="isoweek"?l?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):s.bind(this)(f,w)}}})});var bt=U((Fe,He)=>{(function(e,t){typeof Fe=="object"&&typeof He<"u"?He.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekYear=t()})(Fe,function(){"use strict";return function(e,t){t.prototype.weekYear=function(){var r=this.month(),n=this.week(),i=this.year();return n===1&&r===11?i+1:r===0&&n>=52?i-1:i}}})});var wt=U((Be,Le)=>{(function(e,t){typeof Be=="object"&&typeof Le<"u"?Le.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_weekOfYear=t()})(Be,function(){"use strict";var e="week",t="year";return function(r,n,i){var u=n.prototype;u.week=function(s){if(s===void 0&&(s=null),s!==null)return this.add(7*(s-this.week()),"day");var f=this.$locale().yearStart||1;if(this.month()===11&&this.date()>25){var w=i(this).startOf(t).add(1,t).date(f),g=i(this).endOf(e);if(w.isBefore(g))return 1}var l=i(this).startOf(t).date(f).startOf(e).subtract(1,"millisecond"),x=this.diff(l,e,!0);return x<0?i(this).startOf("week").week():Math.ceil(x)},u.weeks=function(s){return s===void 0&&(s=null),this.week(s)}}})});var Ot=U((ze,Pe)=>{(function(e,t){typeof ze=="object"&&typeof Pe<"u"?Pe.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_relativeTime=t()})(ze,function(){"use strict";return function(e,t,r){e=e||{};var n=t.prototype,i={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function u(f,w,g,l){return n.fromToBase(f,w,g,l)}r.en.relativeTime=i,n.fromToBase=function(f,w,g,l,x){for(var v,a,T,E=g.$locale().relativeTime||i,I=e.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],Y=I.length,F=0;F0,S<=q.r||!q.r){S<=1&&F>0&&(q=I[F-1]);var p=E[q.l];x&&(S=x(""+S)),a=typeof p=="string"?p.replace("%d",S):p(S,w,q.l,T);break}}if(w)return a;var o=T?E.future:E.past;return typeof o=="function"?o(a):o.replace("%s",a)},n.to=function(f,w){return u(f,w,this,!0)},n.from=function(f,w){return u(f,w,this)};var s=function(f){return f.$u?r.utc():r()};n.toNow=function(f){return this.to(s(this),f)},n.fromNow=function(f){return this.from(s(this),f)}}})});var xt=U((Re,Je)=>{(function(e,t){typeof Re=="object"&&typeof Je<"u"?Je.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_utc=t()})(Re,function(){"use strict";var e="minute",t=/[+-]\d\d(?::?\d\d)?/g,r=/([+-]|\d\d)/g;return function(n,i,u){var s=i.prototype;u.utc=function(a){var T={date:a,utc:!0,args:arguments};return new i(T)},s.utc=function(a){var T=u(this.toDate(),{locale:this.$L,utc:!0});return a?T.add(this.utcOffset(),e):T},s.local=function(){return u(this.toDate(),{locale:this.$L,utc:!1})};var f=s.parse;s.parse=function(a){a.utc&&(this.$u=!0),this.$utils().u(a.$offset)||(this.$offset=a.$offset),f.call(this,a)};var w=s.init;s.init=function(){if(this.$u){var a=this.$d;this.$y=a.getUTCFullYear(),this.$M=a.getUTCMonth(),this.$D=a.getUTCDate(),this.$W=a.getUTCDay(),this.$H=a.getUTCHours(),this.$m=a.getUTCMinutes(),this.$s=a.getUTCSeconds(),this.$ms=a.getUTCMilliseconds()}else w.call(this)};var g=s.utcOffset;s.utcOffset=function(a,T){var E=this.$utils().u;if(E(a))return this.$u?0:E(this.$offset)?g.call(this):this.$offset;if(typeof a=="string"&&(a=function(q){q===void 0&&(q="");var S=q.match(t);if(!S)return null;var p=(""+S[0]).match(r)||["-",0,0],o=p[0],D=60*+p[1]+ +p[2];return D===0?0:o==="+"?D:-D}(a),a===null))return this;var I=Math.abs(a)<=16?60*a:a,Y=this;if(T)return Y.$offset=I,Y.$u=a===0,Y;if(a!==0){var F=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();(Y=this.local().add(I+F,e)).$offset=I,Y.$x.$localOffset=F}else Y=this.utc();return Y};var l=s.format;s.format=function(a){var T=a||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return l.call(this,T)},s.valueOf=function(){var a=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*a},s.isUTC=function(){return!!this.$u},s.toISOString=function(){return this.toDate().toISOString()},s.toString=function(){return this.toDate().toUTCString()};var x=s.toDate;s.toDate=function(a){return a==="s"&&this.$offset?u(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():x.call(this)};var v=s.diff;s.diff=function(a,T,E){if(a&&this.$u===a.$u)return v.call(this,a,T,E);var I=this.local(),Y=u(a).local();return v.call(I,Y,T,E)}}})});var St=U((Ge,Ze)=>{(function(e,t){typeof Ge=="object"&&typeof Ze<"u"?Ze.exports=t():typeof define=="function"&&define.amd?define(t):(e=typeof globalThis<"u"?globalThis:e||self).dayjs_plugin_timezone=t()})(Ge,function(){"use strict";var e={year:0,month:1,day:2,hour:3,minute:4,second:5},t={};return function(r,n,i){var u,s=function(l,x,v){v===void 0&&(v={});var a=new Date(l),T=function(E,I){I===void 0&&(I={});var Y=I.timeZoneName||"short",F=E+"|"+Y,q=t[F];return q||(q=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:E,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:Y}),t[F]=q),q}(x,v);return T.formatToParts(a)},f=function(l,x){for(var v=s(l,x),a=[],T=0;T=0&&(a[F]=parseInt(Y,10))}var q=a[3],S=q===24?0:q,p=a[0]+"-"+a[1]+"-"+a[2]+" "+S+":"+a[4]+":"+a[5]+":000",o=+l;return(i.utc(p).valueOf()-(o-=o%1e3))/6e4},w=n.prototype;w.tz=function(l,x){l===void 0&&(l=u);var v=this.utcOffset(),a=this.toDate(),T=a.toLocaleString("en-US",{timeZone:l}),E=Math.round((a-new Date(T))/1e3/60),I=i(T,{locale:this.$L}).$set("millisecond",this.$ms).utcOffset(15*-Math.round(a.getTimezoneOffset()/15)-E,!0);if(x){var Y=I.utcOffset();I=I.add(v-Y,"minute")}return I.$x.$timezone=l,I},w.offsetName=function(l){var x=this.$x.$timezone||i.tz.guess(),v=s(this.valueOf(),x,{timeZoneName:l}).find(function(a){return a.type.toLowerCase()==="timezonename"});return v&&v.value};var g=w.startOf;w.startOf=function(l,x){if(!this.$x||!this.$x.$timezone)return g.call(this,l,x);var v=i(this.format("YYYY-MM-DD HH:mm:ss:SSS"),{locale:this.$L});return g.call(v,l,x).tz(this.$x.$timezone,!0)},i.tz=function(l,x,v){var a=v&&x,T=v||x||u,E=f(+i(),T);if(typeof l!="string")return i(l).tz(T);var I=function(S,p,o){var D=S-60*p*1e3,N=f(D,o);if(p===N)return[D,p];var O=f(D-=60*(N-p)*1e3,o);return N===O?[D,N]:[S-60*Math.min(N,O)*1e3,Math.max(N,O)]}(i.utc(l,a).valueOf(),E,T),Y=I[0],F=I[1],q=i(Y).utcOffset(F);return q.$x.$timezone=T,q},i.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},i.tz.setDefault=function(l){u=l}}})});var Mt=U((ji,Ke)=>{var X=gt();X.extend(yt());X.extend(vt());X.extend($t());X.extend(bt());X.extend(wt());X.extend(Ot());X.extend(xt());X.extend(St());function fe(e){return typeof e=="object"&&typeof e.hash=="object"}function Ve(e){return typeof e=="object"&&typeof e.options=="object"&&typeof e.app=="object"}function Qe(e,t,r){if(fe(e))return Qe({},t,e);if(fe(t))return Qe(e,r,t);let n=Ve(e)?e.context:{};r=r||{},fe(r)||(t=Object.assign({},t,r)),fe(r)&&r.hash.root===!0&&(t=Object.assign({},r.data.root,t));let i=Object.assign({},n,t,r.hash);return Ve(e)||(i=Object.assign({},e,i)),Ve(e)&&e.view&&e.view.data&&(i=Object.assign({},i,e.view.data)),i}function Xe(e,t,r){return fe(t)&&(r=t,t=null),fe(e)&&(r=e,t=null,e=null),{str:e,pattern:t,options:r}}function Nt(e,t,r){let n=Xe(e,t,r),i={lang:"en",date:new Date(n.str)},u=Qe(this,i,{});X.locale(u.lang||u.language)}Ke.exports.date=(e,t,r)=>{let n=Xe(e,t,r);if(n.str==null&&n.pattern==null)return X.locale("en"),X().format("MMMM DD, YYYY");Nt(n.str,n.pattern,n.options);let i=X(new Date(n.str));return typeof n.options=="string"?i=n.options.toLowerCase()==="utc"?i.utc():i.tz(n.options):i=i.tz(X.tz.guess()),n.pattern===""?i.toISOString():i.format(n.pattern)};Ke.exports.duration=(e,t,r)=>{let n=Xe(e,t);Nt(n.str,n.pattern);let i=X.duration(n.str,n.pattern);return r&&!fe(r)?i.format(r):i.humanize()}});var et=U((Ai,At)=>{At.exports=function(e){return e!=null&&(jt(e)||ln(e)||!!e._isBuffer)};function jt(e){return!!e.constructor&&typeof e.constructor.isBuffer=="function"&&e.constructor.isBuffer(e)}function ln(e){return typeof e.readFloatLE=="function"&&typeof e.slice=="function"&&jt(e.slice(0,0))}});var Dt=U((ki,kt)=>{var dn=et(),hn=Object.prototype.toString;kt.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=hn.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":dn(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var Yt=U((Di,qt)=>{"use strict";var Ut=Dt(),Tt={arguments:"an arguments object",array:"an array",boolean:"a boolean",buffer:"a buffer",date:"a date",error:"an error",float32array:"a float32array",float64array:"a float64array",function:"a function",int16array:"an int16array",int32array:"an int32array",int8array:"an int8array",map:"a Map",null:"null",number:"a number",object:"an object",regexp:"a regular expression",set:"a Set",string:"a string",symbol:"a symbol",uint16array:"an uint16array",uint32array:"an uint32array",uint8array:"an uint8array",uint8clampedarray:"an uint8clampedarray",undefined:"undefined",weakmap:"a WeakMap",weakset:"a WeakSet"};function tt(e){return Tt[Ut(e)]}tt.types=Tt;tt.typeOf=Ut;qt.exports=tt});var xe=U((Ui,Et)=>{var pn=Object.prototype.toString;Et.exports=function(t){if(t===void 0)return"undefined";if(t===null)return"null";var r=typeof t;if(r==="boolean")return"boolean";if(r==="string")return"string";if(r==="number")return"number";if(r==="symbol")return"symbol";if(r==="function")return $n(t)?"generatorfunction":"function";if(mn(t))return"array";if(On(t))return"buffer";if(wn(t))return"arguments";if(yn(t))return"date";if(gn(t))return"error";if(vn(t))return"regexp";switch(Ct(t)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(bn(t))return"generator";switch(r=pn.call(t),r){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return r.slice(8,-1).toLowerCase().replace(/\s/g,"")};function Ct(e){return typeof e.constructor=="function"?e.constructor.name:null}function mn(e){return Array.isArray?Array.isArray(e):e instanceof Array}function gn(e){return e instanceof Error||typeof e.message=="string"&&e.constructor&&typeof e.constructor.stackTraceLimit=="number"}function yn(e){return e instanceof Date?!0:typeof e.toDateString=="function"&&typeof e.getDate=="function"&&typeof e.setDate=="function"}function vn(e){return e instanceof RegExp?!0:typeof e.flags=="string"&&typeof e.ignoreCase=="boolean"&&typeof e.multiline=="boolean"&&typeof e.global=="boolean"}function $n(e,t){return Ct(e)==="GeneratorFunction"}function bn(e){return typeof e.throw=="function"&&typeof e.return=="function"&&typeof e.next=="function"}function wn(e){try{if(typeof e.length=="number"&&typeof e.callee=="function")return!0}catch(t){if(t.message.indexOf("callee")!==-1)return!0}return!1}function On(e){return e.constructor&&typeof e.constructor.isBuffer=="function"?e.constructor.isBuffer(e):!1}});var ee=U((Wt,Ft)=>{"use strict";var xn=Ue("util"),It=Yt(),Sn=xe(),m=Wt=Ft.exports;m.extend=_t;m.indexOf=Dn;m.escapeExpression=Un;m.isEmpty=Cn;m.createFrame=Tn;m.blockParams=qn;m.appendContextPath=Yn;var Nn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`","=":"="},Mn=/[&<>"'`=]/g,jn=/[&<>"'`=]/;function An(e){return Nn[e]}function _t(e){for(var t=1;t{"use strict";var En=ee();he.contains=function(e,t,r){return e==null||t==null||isNaN(e.length)?!1:e.indexOf(t,r)!==-1};he.chop=function(e){if(typeof e!="string")return"";var t=/^[-_.\W\s]+|[-_.\W\s]+$/g;return e.trim().replace(t,"")};he.changecase=function(e,t){if(typeof e!="string")return"";if(e.length===1)return e.toLowerCase();e=he.chop(e).toLowerCase(),typeof t!="function"&&(t=En.identity);var r=/[-_.\W\s]+(\w|$)/g;return e.replace(r,function(n,i){return t(i)})};he.random=function(e,t){return e+Math.floor(Math.random()*(t-e+1))}});var Bt=U((qi,Ht)=>{"use strict";var In=Se(),V=Ht.exports;V.abs=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.abs(e)};V.add=function(e,t){return!isNaN(e)&&!isNaN(t)?Number(e)+Number(t):typeof e=="string"&&typeof t=="string"?e+t:""};V.avg=function(){let e=[].concat.apply([],arguments);return e.pop(),V.sum(e)/e.length};V.ceil=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.ceil(e)};V.divide=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)/Number(t)};V.floor=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.floor(e)};V.minus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.modulo=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)%Number(t)};V.multiply=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)*Number(t)};V.plus=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)+Number(t)};V.random=function(e,t){if(isNaN(e))throw new TypeError("expected minimum to be a number");if(isNaN(t))throw new TypeError("expected maximum to be a number");return In.random(e,t)};V.remainder=function(e,t){return e%t};V.round=function(e){if(isNaN(e))throw new TypeError("expected a number");return Math.round(e)};V.subtract=function(e,t){if(isNaN(e))throw new TypeError("expected the first argument to be a number");if(isNaN(t))throw new TypeError("expected the second argument to be a number");return Number(e)-Number(t)};V.sum=function(){for(var e=[].concat.apply([],arguments),t=e.length,r=0;t--;)isNaN(e[t])||(r+=Number(e[t]));return r}});var zt=U((Yi,Lt)=>{"use strict";Lt.exports=function(t){return t!=null&&typeof t=="object"&&Array.isArray(t)===!1}});var Ne=U((Ci,Gt)=>{var Jt=zt();Gt.exports=function(e,t,r){if(Jt(r)||(r={default:r}),!Rt(e))return typeof r.default<"u"?r.default:e;typeof t=="number"&&(t=String(t));let n=Array.isArray(t),i=typeof t=="string",u=r.separator||".",s=r.joinChar||(typeof u=="string"?u:".");if(!i&&!n)return e;if(i&&t in e)return it(t,e,r)?e[t]:r.default;let f=n?t:_n(t,u,r),w=f.length,g=0;do{let l=f[g];for(typeof l=="number"&&(l=String(l));l&&l.slice(-1)==="\\";)l=Pt([l.slice(0,-1),f[++g]||""],s,r);if(l in e){if(!it(l,e,r))return r.default;e=e[l]}else{let x=!1,v=g+1;for(;v{"use strict";Zt.exports=function(t){if(typeof t!="object")throw new TypeError("createFrame expects data to be an object");var r=Object.assign({},t);if(r._parent=t,r.extend=function(s){Object.assign(this,s)},arguments.length>1)for(var n=[].slice.call(arguments,1),i=n.length,u=-1;++u{"use strict";var y=ee(),C=Vt.exports,oe=Ne(),Wn=ut();C.after=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(t):"")};C.arrayify=function(e){return y.isUndefined(e)?[]:e?Array.isArray(e)?e:[e]:[]};C.before=function(e,t){return y.isUndefined(e)?"":(e=y.result(e),Array.isArray(e)?e.slice(0,t-1):"")};C.eachIndex=function(e,t){var r="";if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e))for(var n=0;n0){for(var s=0;s-1,this,r):"")};C.isArray=function(e){return Array.isArray(e)};C.itemAt=function(e,t){if(y.isUndefined(e))return null;if(e=y.result(e),Array.isArray(e)){if(t=isNaN(t)?0:+t,t<0)return e[e.length+t];if(ti[t]>u[t]?1:-1)}return""};C.withAfter=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){e=e.slice(t);for(var n="",i=0;i0){for(var i=[],u=0;u0&&u%t===0&&(n+=r.fn(i),i=[]),i.push(e[u]);n+=r.fn(i)}return n};C.withLast=function(e,t,r){if(y.isUndefined(e))return"";if(e=y.result(e),Array.isArray(e)){if(y.isUndefined(t)||(t=parseFloat(y.result(t))),y.isUndefined(t))return r=t,r.fn(e[e.length-1]);e=e.slice(-t);for(var n=e.length,i=-1,u="";++ig?1:w{"use strict";var Qt=ee(),te=Xt.exports;te.bytes=function(e,t,r){if(e==null||isNaN(e)&&(e=e.length,!e))return"0 B";isNaN(t)&&(t=2);var n=["B","kB","MB","GB","TB","PB","EB","ZB","YB"];t=Math.pow(10,t),e=Number(e);for(var i=n.length-1;i-->=0;){var u=Math.pow(10,i*3);if(u<=e+1){e=Math.round(e*t/u)/t,e+=" "+n[i];break}}return e};te.addCommas=function(e){return e.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1,")};te.phoneNumber=function(e){return e=e.toString(),"("+e.substr(0,3)+") "+e.substr(3,3)+"-"+e.substr(6,4)};te.toAbbr=function(e,t){isNaN(e)&&(e=0),Qt.isUndefined(t)&&(t=2),e=Number(e),t=Math.pow(10,t);for(var r=["k","m","b","t","q"],n=r.length-1;n>=0;){var i=Math.pow(10,(n+1)*3);if(i<=e+1){e=Math.round(e*t/i)/t,e+=r[n];break}n--}return e};te.toExponential=function(e,t){return isNaN(e)&&(e=0),Qt.isUndefined(t)&&(t=0),Number(e).toExponential(t)};te.toFixed=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=0),Number(e).toFixed(t)};te.toFloat=function(e){return parseFloat(e)};te.toInt=function(e){return parseInt(e,10)};te.toPrecision=function(e,t){return isNaN(e)&&(e=0),isNaN(t)&&(t=1),Number(e).toPrecision(t)}});var tr=U((Wi,er)=>{"use strict";var st=Ue("url"),ge=ee(),Fn=Ue("querystring"),ae=er.exports;ae.encodeURI=function(e){if(ge.isString(e))return encodeURIComponent(e)};ae.escape=function(e){if(ge.isString(e))return Fn.escape(e)};ae.decodeURI=function(e){if(ge.isString(e))return decodeURIComponent(e)};ae.urlResolve=function(e,t){return st.resolve(e,t)};ae.urlParse=function(e){return st.parse(e)};ae.stripQuerystring=function(e){if(ge.isString(e))return e.split("?")[0]};ae.stripProtocol=function(e){if(ge.isString(e)){var t=st.parse(e);return t.protocol="",t.format()}}});var ir=U((rr,nr)=>{"use strict";var z=ee(),ce=Se(),A=nr.exports;A.append=function(e,t){return typeof e=="string"&&typeof t=="string"?e+t:e};A.camelcase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return t.toUpperCase()})};A.capitalize=function(e){return typeof e!="string"?"":e.charAt(0).toUpperCase()+e.slice(1)};A.capitalizeAll=function(e){if(typeof e!="string")return"";if(z.isString(e))return e.replace(/\w\S*/g,function(t){return A.capitalize(t)})};A.center=function(e,t){if(typeof e!="string")return"";for(var r="",n=0;n-1;)i++,n+=r;return i};A.pascalcase=function(e){return typeof e!="string"?"":(e=ce.changecase(e,function(t){return t.toUpperCase()}),e.charAt(0).toUpperCase()+e.slice(1))};A.pathcase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return"/"+t})};A.plusify=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=" "),e.split(t).join("+"))};A.prepend=function(e,t){return typeof e=="string"&&typeof t=="string"?t+e:e};A.raw=function(e){var t=e.fn(),r=z.options(this,e);if(r.escape!==!1)for(var n=0;(n=t.indexOf("{{",n))!==-1;)t[n-1]!=="\\"&&(t=t.slice(0,n)+"\\"+t.slice(n)),n+=3;return t};A.remove=function(e,t){return typeof e!="string"?"":z.isString(t)?e.split(t).join(""):e};A.removeFirst=function(e,t){return typeof e!="string"?"":z.isString(t)?e.replace(t,""):e};A.replace=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.split(t).join(r)):e};A.replaceFirst=function(e,t,r){return typeof e!="string"?"":z.isString(t)?(z.isString(r)||(r=""),e.replace(t,r)):e};A.reverse=Me().reverse;A.sentence=function(e){return typeof e!="string"?"":e.replace(/((?:\S[^\.\?\!]*)[\.\?\!]*)/g,function(t){return t.charAt(0).toUpperCase()+t.substr(1).toLowerCase()})};A.snakecase=function(e){return typeof e!="string"?"":ce.changecase(e,function(t){return"_"+t})};A.split=function(e,t){return typeof e!="string"?"":(z.isString(t)||(t=","),e.split(t))};A.startsWith=function(e,t,r){var n=[].slice.call(arguments);return r=n.pop(),z.isString(t)&&t.indexOf(e)===0?r.fn(this):typeof r.inverse=="function"?r.inverse(this):""};A.titleize=function(e){if(typeof e!="string")return"";for(var t=e.replace(/[- _]+/g," "),r=t.split(" "),n=r.length,i=[],u=0;n--;){var s=r[u++];i.push(rr.capitalize(s))}return i.join(" ")};A.trim=function(e){return typeof e=="string"?e.trim():""};A.trimLeft=function(e){if(z.isString(e))return e.replace(/^\s+/,"")};A.trimRight=function(e){if(z.isString(e))return e.replace(/\s+$/,"")};A.truncate=function(e,t,r){if(z.isString(e))return typeof r!="string"&&(r=""),e.length>t?e.slice(0,t-r.length)+r:e};A.truncateWords=function(e,t,r){if(z.isString(e)&&!isNaN(t)){typeof r!="string"&&(r="\u2026");var n=Number(t),i=e.split(/[ \t]/);if(n>=i.length)return e;i=i.slice(0,n);var u=i.join(" ").trim();return u+r}};A.upcase=function(){return A.uppercase.apply(this,arguments)};A.uppercase=function(e){return z.isObject(e)&&e.fn?e.fn(this).toUpperCase():typeof e!="string"?"":e.toUpperCase()}});var sr=U((Fi,ur)=>{"use strict";var Hn=xe();ur.exports=function e(t){switch(Hn(t)){case"boolean":case"date":case"function":case"null":case"number":return!0;case"undefined":return!1;case"regexp":return t.source!=="(?:)"&&t.source!=="";case"buffer":return t.toString()!=="";case"error":return t.message!=="";case"string":case"arguments":return t.length!==0;case"file":case"map":case"set":return t.size!==0;case"array":case"object":for(let r of Object.keys(t))if(e(t[r]))return!0;return!1;default:return!0}}});var or=U((Hi,fr)=>{"use strict";var Bn=Ne(),Ln=sr();fr.exports=function(e,t,r){return zn(e)&&(typeof t=="string"||Array.isArray(t))?Ln(Bn(e,t,r)):!1};function zn(e){return e!=null&&(typeof e=="object"||typeof e=="function"||Array.isArray(e))}});var cr=U((Bi,ar)=>{"use strict";function ft(e,t){if(!e)return!0;let r=t||ft.keywords;Array.isArray(r)||(r=[r]);let n=typeof e=="string"?e.toLowerCase():null;for(let i of r)if(i===e||i===n)return!0;return!1}ft.keywords=["0","false","nada","nil","nay","nah","negative","no","none","nope","nul","null","nix","nyet","uh-uh","veto","zero"];ar.exports=ft});var dr=U((Li,lr)=>{"use strict";lr.exports=function(t){let r=Math.abs(t);if(isNaN(r))throw new TypeError("expected a number");if(!Number.isInteger(r))throw new Error("expected an integer");if(!Number.isSafeInteger(r))throw new Error("value exceeds maximum safe integer");return r%2===1}});var gr=U((zi,mr)=>{"use strict";var Pn=or(),k=ee(),Rn=Se(),hr=cr(),pr=dr(),W=mr.exports;W.and=function(){for(var e=arguments.length-1,t=arguments[e],r=!0,n=0;n":i=e>r;break;case"<=":i=e<=r;break;case">=":i=e>=r;break;case"typeof":i=typeof e===r;break;default:throw new Error("helper {{compare}}: invalid operator: `"+t+"`")}return k.value(i,this,n)};W.contains=function(e,t,r,n){typeof r=="object"&&(n=r,r=void 0);var i=Rn.contains(e,t,r);return k.value(i,this,n)};W.default=function(){for(var e=0;et,this,r)};W.gte=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e>=t,this,r)};W.has=function(e,t,r){return k.isOptions(e)&&(r=e,t=null,e=null),k.isOptions(t)&&(r=t,t=null),e===null?k.value(!1,this,r):arguments.length===2?k.value(Pn(this,e),this,r):(Array.isArray(e)||k.isString(e))&&k.isString(t)&&e.indexOf(t)>-1?k.fn(!0,this,r):k.isObject(e)&&k.isString(t)&&t in e?k.fn(!0,this,r):k.inverse(!1,this,r)};W.isFalsey=function(e,t){return k.value(hr(e),this,t)};W.isTruthy=function(e,t){return k.value(!hr(e),this,t)};W.ifEven=function(e,t){return k.value(!pr(e),this,t)};W.ifNth=function(e,t,r){var n=!isNaN(e)&&!isNaN(t)&&t%e===0;return k.value(n,this,r)};W.ifOdd=function(e,t){return k.value(pr(e),this,t)};W.is=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e==t,this,r)};W.isnt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e!=t,this,r)};W.lt=function(e,t,r){return arguments.length===2&&(r=t,t=r.hash.compare),k.value(e=t,this,r)};W.unlessGteq=function(e,t,r){return k.isOptions(t)&&(r=t,t=r.hash.compare),k.value(et,this,r)}});var vr=U((Pi,yr)=>{var Jn=et(),Gn=Object.prototype.toString;yr.exports=function(t){if(typeof t>"u")return"undefined";if(t===null)return"null";if(t===!0||t===!1||t instanceof Boolean)return"boolean";if(typeof t=="string"||t instanceof String)return"string";if(typeof t=="number"||t instanceof Number)return"number";if(typeof t=="function"||t instanceof Function)return"function";if(typeof Array.isArray<"u"&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var r=Gn.call(t);return r==="[object RegExp]"?"regexp":r==="[object Date]"?"date":r==="[object Arguments]"?"arguments":r==="[object Error]"?"error":Jn(t)?"buffer":r==="[object Set]"?"set":r==="[object WeakSet]"?"weakset":r==="[object Map]"?"map":r==="[object WeakMap]"?"weakmap":r==="[object Symbol]"?"symbol":r==="[object Int8Array]"?"int8array":r==="[object Uint8Array]"?"uint8array":r==="[object Uint8ClampedArray]"?"uint8clampedarray":r==="[object Int16Array]"?"int16array":r==="[object Uint16Array]"?"uint16array":r==="[object Int32Array]"?"int32array":r==="[object Uint32Array]"?"uint32array":r==="[object Float32Array]"?"float32array":r==="[object Float64Array]"?"float64array":"object"}});var br=U((Ri,$r)=>{"use strict";var Zn=vr();$r.exports=function(t){var r=Zn(t);if(r!=="number"&&r!=="string")return!1;var n=+t;return n-n+1>=0&&t!==""}});var Or=U((Ji,wr)=>{"use strict";var Vn=br();wr.exports=function(t,r){if(!r)return t;if(!t)return{};for(var n=String(r).split(/[[.\]]/).filter(Boolean),i=n[n.length-1],u={};r=n.shift();)if(t=t[r],!t)return{};return Vn(i)?[t]:(u[i]=t,u)}});var Mr=U((Gi,Nr)=>{"use strict";var Qn=Object.hasOwnProperty,ye=ee(),Xn=Me(),P=Nr.exports,Kn=Ne(),xr=Or(),Sr=ut();P.extend=function(){var e=[].slice.call(arguments),t={};ye.isOptions(e[e.length-1])&&(t=e.pop().hash,e.push(t));for(var r={},n=0;n{"use strict";var ei=ee(),jr=Ar.exports,ti=xe();jr.toRegex=function(e,t,r){var n=ei.options({},t,r);return new RegExp(e,n.flags)};jr.test=function(e,t){if(typeof e!="string")return!1;if(ti(t)!=="regexp")throw new TypeError("expected a regular expression");return t.test(e)}});import ri from"crypto";function ve(){return je>Ae.length-16&&(ri.randomFillSync(Ae),je=0),Ae.slice(je,je+=16)}var Ae,je,ot=Z(()=>{Ae=new Uint8Array(256),je=Ae.length});var Dr,Ur=Z(()=>{Dr=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i});function ni(e){return typeof e=="string"&&Dr.test(e)}var ne,$e=Z(()=>{Ur();ne=ni});function le(e,t=0){return R[e[t+0]]+R[e[t+1]]+R[e[t+2]]+R[e[t+3]]+"-"+R[e[t+4]]+R[e[t+5]]+"-"+R[e[t+6]]+R[e[t+7]]+"-"+R[e[t+8]]+R[e[t+9]]+"-"+R[e[t+10]]+R[e[t+11]]+R[e[t+12]]+R[e[t+13]]+R[e[t+14]]+R[e[t+15]]}function ii(e,t=0){let r=le(e,t);if(!ne(r))throw TypeError("Stringified UUID is invalid");return r}var R,Tr,be=Z(()=>{$e();R=[];for(let e=0;e<256;++e)R.push((e+256).toString(16).slice(1));Tr=ii});function ui(e,t,r){let n=t&&r||0,i=t||new Array(16);e=e||{};let u=e.node||qr,s=e.clockseq!==void 0?e.clockseq:at;if(u==null||s==null){let v=e.random||(e.rng||ve)();u==null&&(u=qr=[v[0]|1,v[1],v[2],v[3],v[4],v[5]]),s==null&&(s=at=(v[6]<<8|v[7])&16383)}let f=e.msecs!==void 0?e.msecs:Date.now(),w=e.nsecs!==void 0?e.nsecs:lt+1,g=f-ct+(w-lt)/1e4;if(g<0&&e.clockseq===void 0&&(s=s+1&16383),(g<0||f>ct)&&e.nsecs===void 0&&(w=0),w>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");ct=f,lt=w,at=s,f+=122192928e5;let l=((f&268435455)*1e4+w)%4294967296;i[n++]=l>>>24&255,i[n++]=l>>>16&255,i[n++]=l>>>8&255,i[n++]=l&255;let x=f/4294967296*1e4&268435455;i[n++]=x>>>8&255,i[n++]=x&255,i[n++]=x>>>24&15|16,i[n++]=x>>>16&255,i[n++]=s>>>8|128,i[n++]=s&255;for(let v=0;v<6;++v)i[n+v]=u[v];return t||le(i)}var qr,at,ct,lt,Yr,Cr=Z(()=>{ot();be();ct=0,lt=0;Yr=ui});function si(e){if(!ne(e))throw TypeError("Invalid UUID");let t,r=new Uint8Array(16);return r[0]=(t=parseInt(e.slice(0,8),16))>>>24,r[1]=t>>>16&255,r[2]=t>>>8&255,r[3]=t&255,r[4]=(t=parseInt(e.slice(9,13),16))>>>8,r[5]=t&255,r[6]=(t=parseInt(e.slice(14,18),16))>>>8,r[7]=t&255,r[8]=(t=parseInt(e.slice(19,23),16))>>>8,r[9]=t&255,r[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255,r[11]=t/4294967296&255,r[12]=t>>>24&255,r[13]=t>>>16&255,r[14]=t>>>8&255,r[15]=t&255,r}var ke,dt=Z(()=>{$e();ke=si});function fi(e){e=unescape(encodeURIComponent(e));let t=[];for(let r=0;r{be();dt();oi="6ba7b810-9dad-11d1-80b4-00c04fd430c8",ai="6ba7b811-9dad-11d1-80b4-00c04fd430c8"});import ci from"crypto";function li(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),ci.createHash("md5").update(e).digest()}var Er,Ir=Z(()=>{Er=li});var di,_r,Wr=Z(()=>{ht();Ir();di=we("v3",48,Er),_r=di});import hi from"crypto";var pt,Fr=Z(()=>{pt={randomUUID:hi.randomUUID}});function pi(e,t,r){if(pt.randomUUID&&!t&&!e)return pt.randomUUID();e=e||{};let n=e.random||(e.rng||ve)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,t){r=r||0;for(let i=0;i<16;++i)t[r+i]=n[i];return t}return le(n)}var Hr,Br=Z(()=>{Fr();ot();be();Hr=pi});import mi from"crypto";function gi(e){return Array.isArray(e)?e=Buffer.from(e):typeof e=="string"&&(e=Buffer.from(e,"utf8")),mi.createHash("sha1").update(e).digest()}var Lr,zr=Z(()=>{Lr=gi});var yi,Pr,Rr=Z(()=>{ht();zr();yi=we("v5",80,Lr),Pr=yi});var Jr,Gr=Z(()=>{Jr="00000000-0000-0000-0000-000000000000"});function vi(e){if(!ne(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var Zr,Vr=Z(()=>{$e();Zr=vi});var Qr={};on(Qr,{NIL:()=>Jr,parse:()=>ke,stringify:()=>Tr,v1:()=>Yr,v3:()=>_r,v4:()=>Hr,v5:()=>Pr,validate:()=>ne,version:()=>Zr});var Xr=Z(()=>{Cr();Wr();Br();Rr();Gr();Vr();$e();be();dt()});var en=U((Wu,Kr)=>{var $i=(Xr(),cn(Qr)),bi=Kr.exports;bi.uuid=function(){return $i.v4()}});var nn=U((Fu,mt)=>{var{date:wi,duration:Oi}=Mt(),xi={math:Bt(),array:Me(),number:Kt(),url:tr(),string:ir(),comparison:gr(),object:Mr(),regex:kr(),uuid:en()},rn=["sortBy"];mt.exports.helpersToRemoveForJs=rn;var tn={date:wi,duration:Oi},ie;mt.exports.getJsHelperList=()=>{if(ie)return ie;ie={};for(let e of Object.values(xi))for(let[t,r]of Object.entries(e))ie[t]=(...n)=>r(...n,{});for(let e of Object.keys(tn))ie[e]=tn[e];for(let e of rn)delete ie[e];return Object.freeze(ie),ie}});var{getJsHelperList:Si}=nn(),Ni=Si(),Hu={...Ni,stripProtocol:helpersStripProtocol};export{Hu as default}; /*! Bundled license information: is-buffer/index.js: diff --git a/packages/server/src/jsRunner/bundles/index-helpers.ts b/packages/server/src/jsRunner/bundles/index-helpers.ts index a7596b15e0..fc3c860f20 100644 --- a/packages/server/src/jsRunner/bundles/index-helpers.ts +++ b/packages/server/src/jsRunner/bundles/index-helpers.ts @@ -1,4 +1,6 @@ -import { getJsHelperList } from "@budibase/string-templates/js-helpers" +const { + getJsHelperList, +} = require("../../../../string-templates/src/helpers/list.js") const helpers = getJsHelperList() export default { diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index bbd5cf0a85..a6179234de 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -12,7 +12,6 @@ "import": "./dist/bundle.mjs" }, "./package.json": "./package.json", - "./js-helpers": "./src/helpers/list.js", "./test/utils": "./test/utils.js" }, "files": [ From bfc0cd305e1c140a52655c1fb2dcc8cebe87fe75 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Tue, 6 Feb 2024 09:47:50 +0000 Subject: [PATCH 154/294] Bump version to 2.17.6 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index c5c7f533ad..ee152030df 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.17.5", + "version": "2.17.6", "npmClient": "yarn", "packages": [ "packages/*", From 4df738acb797976adf1a5d2278840f3a262e14c9 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 10:49:11 +0100 Subject: [PATCH 155/294] Fix tests --- packages/server/src/jsRunner/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index f0ebac2ec4..aaf8ccce65 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -7,8 +7,6 @@ import url from "url" import crypto from "crypto" import querystring from "querystring" -const helpersSource = require("./bundles/index-helpers.ivm.bundle.js") - class ExecutionTimeoutError extends Error { constructor(message: string) { super(message) @@ -76,6 +74,7 @@ export function init() { }) ) + const helpersSource = require("./bundles/index-helpers.ivm.bundle.js") const helpersModule = jsIsolate.compileModuleSync( `${injectedRequire};${helpersSource}` ) From fde2af9a2891bee90212cc55525a706f913acbec Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 6 Feb 2024 11:30:44 +0100 Subject: [PATCH 156/294] Add helpers in order to fix tests --- packages/server/src/jsRunner/bundles/index.ts | 24 +++++++++++++++++++ packages/server/src/jsRunner/index.ts | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 packages/server/src/jsRunner/bundles/index.ts diff --git a/packages/server/src/jsRunner/bundles/index.ts b/packages/server/src/jsRunner/bundles/index.ts new file mode 100644 index 0000000000..7fe37604bc --- /dev/null +++ b/packages/server/src/jsRunner/bundles/index.ts @@ -0,0 +1,24 @@ +import { utils } from "@budibase/shared-core" +import environment from "../../environment" +import fs from "fs" + +export enum BundleType { + HELPERS = "helpers", +} + +const bundleSourceCode = { + [BundleType.HELPERS]: "../bundles/index-helpers.ivm.bundle.js", +} + +export function loadBundle(type: BundleType) { + if (environment.isJest()) { + return fs.readFileSync(require.resolve(bundleSourceCode[type]), "utf-8") + } + + switch (type) { + case BundleType.HELPERS: + return require("../bundles/index-helpers.ivm.bundle.js") + default: + utils.unreachable(type) + } +} diff --git a/packages/server/src/jsRunner/index.ts b/packages/server/src/jsRunner/index.ts index aaf8ccce65..9c54779567 100644 --- a/packages/server/src/jsRunner/index.ts +++ b/packages/server/src/jsRunner/index.ts @@ -6,6 +6,7 @@ import tracer from "dd-trace" import url from "url" import crypto from "crypto" import querystring from "querystring" +import { BundleType, loadBundle } from "./bundles" class ExecutionTimeoutError extends Error { constructor(message: string) { @@ -15,6 +16,7 @@ class ExecutionTimeoutError extends Error { } export function init() { + const helpersSource = loadBundle(BundleType.HELPERS) setJSRunner((js: string, ctx: Record) => { return tracer.trace("runJS", {}, span => { try { @@ -74,7 +76,6 @@ export function init() { }) ) - const helpersSource = require("./bundles/index-helpers.ivm.bundle.js") const helpersModule = jsIsolate.compileModuleSync( `${injectedRequire};${helpersSource}` ) From 8bb25c471504134c0004e988a80acc59ad720c44 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 6 Feb 2024 10:47:47 +0000 Subject: [PATCH 157/294] More MongoDB query tests. --- .../api/routes/tests/queries/mongodb.spec.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/packages/server/src/api/routes/tests/queries/mongodb.spec.ts b/packages/server/src/api/routes/tests/queries/mongodb.spec.ts index 8184f40b88..a9c35cba7d 100644 --- a/packages/server/src/api/routes/tests/queries/mongodb.spec.ts +++ b/packages/server/src/api/routes/tests/queries/mongodb.spec.ts @@ -154,6 +154,55 @@ describe("/queries", () => { expect(result.data).toEqual([{ _id: expect.anything(), name: "one" }]) }) + it("should execute a findOneAndUpdate query", async () => { + const query = await createQuery({ + fields: { + json: { + filter: { name: { $eq: "one" } }, + update: { $set: { name: "newName" } }, + }, + extra: { + actionType: "findOneAndUpdate", + }, + }, + }) + + const result = await config.api.query.execute(query._id!) + + expect(result.data).toEqual([ + { + lastErrorObject: { n: 1, updatedExisting: true }, + ok: 1, + value: { _id: expect.anything(), name: "one" }, + }, + ]) + + await withCollection(async collection => { + expect(await collection.countDocuments()).toBe(5) + + const doc = await collection.findOne({ name: { $eq: "newName" } }) + expect(doc).toEqual({ + _id: expect.anything(), + name: "newName", + }) + }) + }) + + it("should execute a distinct query", async () => { + const query = await createQuery({ + fields: { + json: "name", + extra: { + actionType: "distinct", + }, + }, + }) + + const result = await config.api.query.execute(query._id!) + const values = result.data.map(o => o.value).sort() + expect(values).toEqual(["five", "four", "one", "three", "two"]) + }) + it("should execute a create query with parameters", async () => { const query = await createQuery({ fields: { From e27772d93f16bfc2ece25690f230de8d2340e63c Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:08:37 +0000 Subject: [PATCH 158/294] Allow logo in top navigation to be a link (#12868) * Add support for logo link * Add link to logo --------- Co-authored-by: Andrew Kingston --- .../_components/Navigation/index.svelte | 63 ++++++++++++++----- .../client/src/components/app/Layout.svelte | 30 ++++++++- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte index 383026c4f8..f9f994ce67 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/index.svelte @@ -15,10 +15,15 @@ Checkbox, notifications, Select, + Combobox, } from "@budibase/bbui" import { selectedScreen, store } from "builderStore" import { DefaultAppTheme } from "constants" + $: screenRouteOptions = $store.screens + .map(screen => screen.routing?.route) + .filter(x => x != null) + const updateShowNavigation = async e => { await store.actions.screens.updateSetting( get(selectedScreen), @@ -107,23 +112,6 @@ on:change={e => update("navWidth", e.detail)} /> {/if} -
- -
- update("hideLogo", !e.detail)} - /> - {#if !$store.navigation.hideLogo} -
- -
- update("logoUrl", e.detail)} - updateOnChange={false} - /> - {/if}
@@ -160,6 +148,47 @@ />
+ +
+
+
+ Logo +
+
+
+ +
+ update("hideLogo", !e.detail)} + /> + {#if !$store.navigation.hideLogo} +
+ +
+ update("logoUrl", e.detail)} + updateOnChange={false} + /> +
+ +
+ update("logoLinkUrl", e.detail)} + options={screenRouteOptions} + /> +
+ +
+ update("openLogoLinkInNewTab", !!e.detail)} + /> + {/if} +
+
{/if} diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index bdab0dd9ab..2ca57a3dde 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -33,6 +33,8 @@ export let navTextColor export let navWidth export let pageWidth + export let logoLinkUrl + export let openLogoLinkInNewTab export let embedded = false @@ -150,6 +152,16 @@ } return style } + + const getSanitizedUrl = (url, openInNewTab) => { + if (!isInternal(url)) { + return ensureExternal(url) + } + if (openInNewTab) { + return `#${url}` + } + return url + }