@elyx-code/editor-ui 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/package.json +109 -0
- package/src/App.tsx +31 -0
- package/src/Router.tsx +115 -0
- package/src/__mocks__/defaultModuleMock.ts +1 -0
- package/src/__mocks__/fileMock.ts +1 -0
- package/src/__mocks__/styleMock.ts +1 -0
- package/src/assets/Clock-11.1s-18px.svg +16 -0
- package/src/assets/Clock-11.1s-28px.svg +16 -0
- package/src/assets/authentication.svg +1 -0
- package/src/assets/canvas-backdrop-0.png +0 -0
- package/src/assets/canvas-backdrop-1.png +0 -0
- package/src/assets/canvas-backdrop-2.png +0 -0
- package/src/assets/canvas-backdrop-3.png +0 -0
- package/src/assets/canvas-backdrop-4.png +0 -0
- package/src/assets/canvas-backdrop-5.png +0 -0
- package/src/assets/canvas-backdrop.png +0 -0
- package/src/assets/checkmark-animation.gif +0 -0
- package/src/assets/checkmark-animation.mp4 +0 -0
- package/src/assets/code-formatting/format-black.svg +6 -0
- package/src/assets/code-formatting/format-dark-grey.svg +6 -0
- package/src/assets/code-formatting/format-light-grey.svg +6 -0
- package/src/assets/code-formatting/format-white.svg +6 -0
- package/src/assets/code-formatting/inline-black.svg +5 -0
- package/src/assets/code-formatting/inline-dark-grey.svg +5 -0
- package/src/assets/code-formatting/inline-light-grey.svg +5 -0
- package/src/assets/code-formatting/inline-white.svg +5 -0
- package/src/assets/contained-logo-full-word.png +0 -0
- package/src/assets/cron-job-color.png +0 -0
- package/src/assets/cron-job.png +0 -0
- package/src/assets/database-table-color.png +0 -0
- package/src/assets/database-table.png +0 -0
- package/src/assets/datatype-icons/black/any.svg +1 -0
- package/src/assets/datatype-icons/black/binary.svg +1 -0
- package/src/assets/datatype-icons/black/boolean.svg +3 -0
- package/src/assets/datatype-icons/black/date-time.svg +3 -0
- package/src/assets/datatype-icons/black/definition-entity.svg +6 -0
- package/src/assets/datatype-icons/black/key-file.svg +1 -0
- package/src/assets/datatype-icons/black/list.svg +3 -0
- package/src/assets/datatype-icons/black/null.svg +3 -0
- package/src/assets/datatype-icons/black/number.svg +13 -0
- package/src/assets/datatype-icons/black/project.svg +12 -0
- package/src/assets/datatype-icons/black/sql-program.svg +2 -0
- package/src/assets/datatype-icons/black/text.svg +3 -0
- package/src/assets/datatype-icons/black/unknown.svg +3 -0
- package/src/assets/datatype-icons/black/uuid.svg +4 -0
- package/src/assets/datatype-icons/black/void.svg +1 -0
- package/src/assets/datatype-icons/dark-grey/any.svg +1 -0
- package/src/assets/datatype-icons/dark-grey/boolean.svg +3 -0
- package/src/assets/datatype-icons/dark-grey/date-time.svg +3 -0
- package/src/assets/datatype-icons/dark-grey/definition-entity.svg +6 -0
- package/src/assets/datatype-icons/dark-grey/list.svg +3 -0
- package/src/assets/datatype-icons/dark-grey/null.svg +3 -0
- package/src/assets/datatype-icons/dark-grey/number.svg +13 -0
- package/src/assets/datatype-icons/dark-grey/project.svg +12 -0
- package/src/assets/datatype-icons/dark-grey/sql-program.svg +2 -0
- package/src/assets/datatype-icons/dark-grey/text.svg +3 -0
- package/src/assets/datatype-icons/dark-grey/unknown.svg +3 -0
- package/src/assets/datatype-icons/dark-grey/uuid.svg +4 -0
- package/src/assets/datatype-icons/dark-grey/void.svg +1 -0
- package/src/assets/datatype-icons/light-grey/any.svg +1 -0
- package/src/assets/datatype-icons/light-grey/boolean.svg +3 -0
- package/src/assets/datatype-icons/light-grey/date-time.svg +3 -0
- package/src/assets/datatype-icons/light-grey/definition-entity.svg +6 -0
- package/src/assets/datatype-icons/light-grey/list.svg +3 -0
- package/src/assets/datatype-icons/light-grey/null.svg +3 -0
- package/src/assets/datatype-icons/light-grey/number.svg +13 -0
- package/src/assets/datatype-icons/light-grey/project.svg +12 -0
- package/src/assets/datatype-icons/light-grey/sql-program.svg +2 -0
- package/src/assets/datatype-icons/light-grey/text.svg +3 -0
- package/src/assets/datatype-icons/light-grey/unknown.svg +3 -0
- package/src/assets/datatype-icons/light-grey/uuid.svg +4 -0
- package/src/assets/datatype-icons/light-grey/void.svg +1 -0
- package/src/assets/edit.png +0 -0
- package/src/assets/execution.svg +13 -0
- package/src/assets/favicon.svg +14 -0
- package/src/assets/file-search.svg +1 -0
- package/src/assets/http-endpoint.png +0 -0
- package/src/assets/image-input-placeholder.png +0 -0
- package/src/assets/logo-full-word-white.png +0 -0
- package/src/assets/logo-full-word.png +0 -0
- package/src/assets/password.svg +85 -0
- package/src/assets/pencil.png +0 -0
- package/src/assets/publish-project-rich-icon-2.svg +1 -0
- package/src/assets/publish-project-rich-icon.svg +1 -0
- package/src/assets/relational-database.png +0 -0
- package/src/assets/resources.svg +3 -0
- package/src/assets/resume-icon-14px.png +0 -0
- package/src/assets/server.png +0 -0
- package/src/assets/small-status/checkmark.svg +4 -0
- package/src/assets/small-status/error.svg +4 -0
- package/src/assets/small-status/loading.svg +4 -0
- package/src/assets/small-status/skipped.svg +11 -0
- package/src/assets/sql-connection-config.svg +1 -0
- package/src/assets/sql-row-transformer.svg +1 -0
- package/src/assets/ssl-certificate-config.svg +1 -0
- package/src/assets/sync.svg +1 -0
- package/src/assets/testing-logic-icon.svg +1 -0
- package/src/assets/versions.svg +25 -0
- package/src/assets/visual-programming-icon.svg +1 -0
- package/src/assets/warning-sign-24px.png +0 -0
- package/src/auth/index.ts +318 -0
- package/src/components/DialogLoader.tsx +94 -0
- package/src/components/EntityDialogHeader.tsx +110 -0
- package/src/components/EntityDialogSectionHeader.tsx +214 -0
- package/src/components/GalleryAddExternalIntegrationInfoDialog.tsx +87 -0
- package/src/components/GenerateProjectStartingLogicPromptDialog.tsx +281 -0
- package/src/components/LegacyRouteRedirector.tsx +55 -0
- package/src/components/ProPlanChip.tsx +23 -0
- package/src/components/ReportBugDialog.tsx +412 -0
- package/src/components/RequestIntegrationAccessDialog.tsx +261 -0
- package/src/components/UseTemplateProjectDialog.tsx +193 -0
- package/src/components/WorkspaceLayout.tsx +152 -0
- package/src/components/animated-svg/AnimatedCheckmark.tsx +41 -0
- package/src/components/animated-svg/AnimatedCrossmark.tsx +51 -0
- package/src/components/animated-svg/AnimatedEmailSending.tsx +38 -0
- package/src/components/animated-svg/AnimatedLoading.tsx +72 -0
- package/src/components/animated-svg/animated-svg.css +239 -0
- package/src/components/canvas/Canvas.tsx +16 -0
- package/src/components/canvas/CreateEntityMenu.tsx +2020 -0
- package/src/components/canvas/canvas.css +10 -0
- package/src/components/canvas/create-entity-menu.css +579 -0
- package/src/components/canvas-search/CanvasSearch.tsx +501 -0
- package/src/components/canvas-search/canvas-search.css +126 -0
- package/src/components/canvas-settings-menu/CanvasSettingsMenuButton.tsx +515 -0
- package/src/components/canvas-settings-menu/canvas-settings-menu.css +96 -0
- package/src/components/circular-image-upload/CircularImageUpload.tsx +113 -0
- package/src/components/circular-image-upload/circular-image-upload.css +69 -0
- package/src/components/costs/CostsDialog.tsx +459 -0
- package/src/components/data-type/DataTypeBuilder.tsx +3127 -0
- package/src/components/data-type/data-type-builder.css +45 -0
- package/src/components/dialogs/BetaAcknowledgeDialog.tsx +43 -0
- package/src/components/dialogs/ComplexDataDialog.tsx +458 -0
- package/src/components/dialogs/CronBuilderDialog.tsx +2145 -0
- package/src/components/dialogs/ExternalIntegrationConnections.tsx +565 -0
- package/src/components/dialogs/JsonEditorDialog.tsx +1392 -0
- package/src/components/dialogs/StringEditorDialog.tsx +268 -0
- package/src/components/dialogs/argument-declaration/ArgumentDeclaration.tsx +1167 -0
- package/src/components/dialogs/argument-declaration/ArgumentDeclarationDialogContent.tsx +128 -0
- package/src/components/dialogs/beta-dialog.css +165 -0
- package/src/components/dialogs/condition/Condition.tsx +431 -0
- package/src/components/dialogs/condition/ConditionDialogContent.tsx +126 -0
- package/src/components/dialogs/definition-entity/DefinitionEntityDialogContent.tsx +973 -0
- package/src/components/dialogs/function-call/FunctionCall.tsx +442 -0
- package/src/components/dialogs/function-call/FunctionCallDialogContent.tsx +126 -0
- package/src/components/dialogs/function-declaration/FunctionDeclaration.tsx +926 -0
- package/src/components/dialogs/function-declaration/FunctionDeclarationDialogContent.tsx +124 -0
- package/src/components/dialogs/generating-project-starting-logic-overlay/GeneratingProjectStartingLogicOverlay.tsx +176 -0
- package/src/components/dialogs/generating-project-starting-logic-overlay/generating-project-starting-logic-overlay.css +13 -0
- package/src/components/dialogs/global-event/GlobalEvent.tsx +475 -0
- package/src/components/dialogs/global-event/GlobalEventDialogContent.tsx +126 -0
- package/src/components/dialogs/help/HelpDialog.tsx +217 -0
- package/src/components/dialogs/help/HelpDilalogHomeContent.tsx +178 -0
- package/src/components/dialogs/help/help-dialog.css +116 -0
- package/src/components/dialogs/help/help-icon/HelpIconButton.tsx +41 -0
- package/src/components/dialogs/help/help-icon/help-icon.css +9 -0
- package/src/components/dialogs/input-map/InputMap.tsx +635 -0
- package/src/components/dialogs/input-map/InputMapDialogContent.tsx +126 -0
- package/src/components/dialogs/json-editor-dialog.css +4 -0
- package/src/components/dialogs/loop/Loop.tsx +650 -0
- package/src/components/dialogs/loop/LoopDialogContent.tsx +122 -0
- package/src/components/dialogs/operation/Operation.tsx +440 -0
- package/src/components/dialogs/operation/OperationDialogContent.tsx +126 -0
- package/src/components/dialogs/output-map/OutputMap.tsx +536 -0
- package/src/components/dialogs/output-map/OutputMapDialogContent.tsx +126 -0
- package/src/components/dialogs/property/Property.tsx +1490 -0
- package/src/components/dialogs/property/PropertyDialogContent.tsx +106 -0
- package/src/components/dialogs/search-statement/ColumnSelector.tsx +334 -0
- package/src/components/dialogs/search-statement/ConditionBuilder.tsx +750 -0
- package/src/components/dialogs/search-statement/DataAggregationSection.tsx +621 -0
- package/src/components/dialogs/search-statement/DataSourceSelection.tsx +734 -0
- package/src/components/dialogs/search-statement/EntityMetadataSection.tsx +135 -0
- package/src/components/dialogs/search-statement/FilterConditionsSection.tsx +151 -0
- package/src/components/dialogs/search-statement/InlineInputMap.tsx +153 -0
- package/src/components/dialogs/search-statement/LiteralValue.tsx +616 -0
- package/src/components/dialogs/search-statement/MainSourceAndInputsSection.tsx +271 -0
- package/src/components/dialogs/search-statement/NestedSearchStatementBuilder.tsx +170 -0
- package/src/components/dialogs/search-statement/OutputFormatSection.tsx +1779 -0
- package/src/components/dialogs/search-statement/ResultsSection.tsx +344 -0
- package/src/components/dialogs/search-statement/SearchStatementBuilder.tsx +251 -0
- package/src/components/dialogs/search-statement/SearchStatementDialogContent.tsx +398 -0
- package/src/components/dialogs/search-statement/ValueSelector.tsx +766 -0
- package/src/components/dialogs/search-statement/search-statement-context.tsx +1630 -0
- package/src/components/dialogs/search-statement/search-statement-dialog.css +56 -0
- package/src/components/dialogs/search-statement/test.sql +111 -0
- package/src/components/dialogs/value-descriptor/ValueDescriptor.tsx +824 -0
- package/src/components/dialogs/value-descriptor/ValueDescriptorDialogContent.tsx +124 -0
- package/src/components/dialogs/variable-declaration/VariableDeclaration.tsx +836 -0
- package/src/components/dialogs/variable-declaration/VariableDeclarationDialogContent.tsx +106 -0
- package/src/components/dialogs/variable-instance/VariableInstance.tsx +443 -0
- package/src/components/dialogs/variable-instance/VariableInstanceDialogContent.tsx +124 -0
- package/src/components/draggable-entity-card/ArgumentDeclaration.tsx +736 -0
- package/src/components/draggable-entity-card/CollapseEntityButton.tsx +170 -0
- package/src/components/draggable-entity-card/ConditionCard.tsx +1062 -0
- package/src/components/draggable-entity-card/ConnectionDeleteButton.tsx +309 -0
- package/src/components/draggable-entity-card/DataTypeIcon.tsx +624 -0
- package/src/components/draggable-entity-card/DraggableEntityCard.tsx +617 -0
- package/src/components/draggable-entity-card/ErrorMapProperty.tsx +464 -0
- package/src/components/draggable-entity-card/EventCard.tsx +700 -0
- package/src/components/draggable-entity-card/ExecutionInProgressValue.tsx +327 -0
- package/src/components/draggable-entity-card/FunctionDeclarationCard.tsx +819 -0
- package/src/components/draggable-entity-card/InputMapProperty.tsx +1067 -0
- package/src/components/draggable-entity-card/InternalCall.tsx +978 -0
- package/src/components/draggable-entity-card/InternalCallExecutionNode.tsx +643 -0
- package/src/components/draggable-entity-card/LogicScopeCallerNode.tsx +262 -0
- package/src/components/draggable-entity-card/LoopCard.tsx +791 -0
- package/src/components/draggable-entity-card/MainValueInput.tsx +523 -0
- package/src/components/draggable-entity-card/MainValueOutput.tsx +458 -0
- package/src/components/draggable-entity-card/MethodDeclaration.tsx +1088 -0
- package/src/components/draggable-entity-card/NestedCondition.tsx +1025 -0
- package/src/components/draggable-entity-card/OutputMapProperty.tsx +843 -0
- package/src/components/draggable-entity-card/PassthroughEntityCard.tsx +1247 -0
- package/src/components/draggable-entity-card/ReturnedError.tsx +549 -0
- package/src/components/draggable-entity-card/SmallSuccessFailureNodes.tsx +523 -0
- package/src/components/draggable-entity-card/SuccessFailureNodes.tsx +509 -0
- package/src/components/draggable-entity-card/TestEntityButton.tsx +946 -0
- package/src/components/draggable-entity-card/TestMenu.tsx +523 -0
- package/src/components/draggable-entity-card/TestMenuValidationDropdown.tsx +84 -0
- package/src/components/draggable-entity-card/UnreachableMarker.tsx +114 -0
- package/src/components/draggable-entity-card/VariableCard.tsx +1577 -0
- package/src/components/draggable-entity-card/VariableScopeMarker.tsx +117 -0
- package/src/components/draggable-entity-card/collapse-entity-button.css +44 -0
- package/src/components/draggable-entity-card/definition-entity/DefinitionEntityCard.tsx +1181 -0
- package/src/components/draggable-entity-card/definition-entity/DefinitionEntityIcon.tsx +36 -0
- package/src/components/draggable-entity-card/definition-entity/DefinitionEntityProperty.tsx +478 -0
- package/src/components/draggable-entity-card/definition-entity/DynamicFooterActions.tsx +112 -0
- package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/ExportCredentialsFooterAction.tsx +461 -0
- package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/RestablishConnectionFooterAction.tsx +199 -0
- package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/restablish-connection-footer-action.css +85 -0
- package/src/components/draggable-entity-card/definition-entity/actions/google-drive/GoogleDriveFilePickerAPIFooterAction.tsx +277 -0
- package/src/components/draggable-entity-card/definition-entity/actions/google-drive/google-drive-file-picker-api-footer-action.css +107 -0
- package/src/components/draggable-entity-card/definition-entity/actions/persisted-entity/DatabaseFooterAction.tsx +452 -0
- package/src/components/draggable-entity-card/definition-entity/actions/persisted-entity/database-footer-action.css +86 -0
- package/src/components/draggable-entity-card/definition-entity/definition-entity-card.css +17 -0
- package/src/components/draggable-entity-card/draggable-entity-card.css +1140 -0
- package/src/components/draggable-entity-card/entity-locked-icon/EntityLockedIcon.tsx +133 -0
- package/src/components/draggable-entity-card/entity-locked-icon/entity-locked.css +8 -0
- package/src/components/draggable-entity-card/expand-properties-icon-button/ExpandPropertiesIconButton.tsx +84 -0
- package/src/components/draggable-entity-card/expand-properties-icon-button/expand-properties-icon-button.css +21 -0
- package/src/components/draggable-entity-card/implement-entity-icon/ImplementEntityIcon.tsx +74 -0
- package/src/components/draggable-entity-card/implement-entity-icon/implement-entity-icon.css +13 -0
- package/src/components/draggable-entity-card/logic-error/LogicErrorIconMenu.tsx +424 -0
- package/src/components/draggable-entity-card/logic-error/logic-error.css +23 -0
- package/src/components/draggable-entity-card/new-card-input-button/NewCardInputButton.tsx +193 -0
- package/src/components/draggable-entity-card/new-card-input-button/NewDynamicInputButton.tsx +214 -0
- package/src/components/draggable-entity-card/new-card-input-button/new-card-input-button.css +71 -0
- package/src/components/draggable-entity-card/new-card-output-button/NewCardOutputButton.tsx +192 -0
- package/src/components/draggable-entity-card/new-card-output-button/new-card-output-button.css +71 -0
- package/src/components/draggable-entity-card/termination-statement/TerminationStatementCard.tsx +1543 -0
- package/src/components/draggable-entity-card/termination-statement/termination-statement-card.css +17 -0
- package/src/components/draggable-entity-card/test-entity-button.css +55 -0
- package/src/components/draggable-entity-card/test-menu.css +181 -0
- package/src/components/draggable-entity-card/unreachable-marker.css +43 -0
- package/src/components/draggable-entity-card/variable-scope-marker.css +22 -0
- package/src/components/dynamic-value/DynamicValue.tsx +2395 -0
- package/src/components/dynamic-value/DynamicValueEntry.tsx +1957 -0
- package/src/components/dynamic-value/dynamic-value.css +230 -0
- package/src/components/editor/ElyxMonacoEditor.tsx +38 -0
- package/src/components/entity-error/EntityErrorListItem.tsx +47 -0
- package/src/components/entity-error/entity-error.css +198 -0
- package/src/components/entity-icon/EntityIcon.tsx +292 -0
- package/src/components/entity-icon/entity-icon.css +39 -0
- package/src/components/gallery-card/CreateNewProject.tsx +222 -0
- package/src/components/gallery-card/GalleryCard.tsx +171 -0
- package/src/components/gallery-card/MarketplaceCard.tsx +87 -0
- package/src/components/gallery-card/ProjectDuplicationCard.tsx +575 -0
- package/src/components/gallery-card/gallery-card.css +25 -0
- package/src/components/notifications/NotificationsIconButton.tsx +124 -0
- package/src/components/notifications/NotificationsPanel.tsx +385 -0
- package/src/components/notifications/notifications.css +189 -0
- package/src/components/online-users/LocalOnlineUsers.tsx +175 -0
- package/src/components/online-users/PageOnlineUsers.tsx +297 -0
- package/src/components/online-users/online-users.css +72 -0
- package/src/components/page-backdrop/PageBackdrop.tsx +8 -0
- package/src/components/page-backdrop/page-backdrop.css +7 -0
- package/src/components/project-configuration/DeleteProjectConfirmationDialog.tsx +134 -0
- package/src/components/project-configuration/ProjectConfigurationDialog.tsx +972 -0
- package/src/components/project-configuration/ProjectDataForm.tsx +121 -0
- package/src/components/project-configuration/UnpublishProjectConfirmationDialog.tsx +162 -0
- package/src/components/project-configuration/project-configuration-content.css +209 -0
- package/src/components/project-name/ProjectName.tsx +2025 -0
- package/src/components/project-name/project-name.css +599 -0
- package/src/components/publishing/Publication.tsx +133 -0
- package/src/components/publishing/history/PublicationHistoryContent.tsx +414 -0
- package/src/components/publishing/history/PublicationHistoryDialog.tsx +234 -0
- package/src/components/publishing/preview/PublicationPreviewDialog.tsx +1158 -0
- package/src/components/publishing/preview/PublishingPriceForecast.tsx +160 -0
- package/src/components/publishing/preview/PublishingResourcesDetails.tsx +91 -0
- package/src/components/publishing/publication-sequence/PublishingSequenceContent.tsx +375 -0
- package/src/components/publishing/publication-sequence/PublishingSequenceDialog.tsx +344 -0
- package/src/components/publishing/publishing-dialog.css +142 -0
- package/src/components/publishing/utils.ts +227 -0
- package/src/components/resources/ResourcesDialog.tsx +591 -0
- package/src/components/resources/UpgradeBanner.tsx +102 -0
- package/src/components/resources/codebase/CodebaseDetails.tsx +156 -0
- package/src/components/resources/cron-job/CronJobsList.tsx +532 -0
- package/src/components/resources/functions/FunctionsList.tsx +454 -0
- package/src/components/resources/http-api/HttpAPI.tsx +566 -0
- package/src/components/resources/http-api/HttpAPIClientModule.tsx +37 -0
- package/src/components/resources/logs/LogsViewer.tsx +768 -0
- package/src/components/resources/query.ts +74 -0
- package/src/components/resources/relational-database/DatabaseTable.tsx +905 -0
- package/src/components/resources/relational-database/RelationalDatabase.tsx +83 -0
- package/src/components/resources/relational-database/RelationalDatabaseSecrets.tsx +361 -0
- package/src/components/resources/resources-dialog.css +74 -0
- package/src/components/test-relational-database/DatabaseTable.tsx +913 -0
- package/src/components/test-relational-database/TestDatabaseDialogContent.tsx +670 -0
- package/src/components/test-relational-database/query.ts +74 -0
- package/src/components/toolbar/ToolBar.tsx +236 -0
- package/src/components/toolbar/toolbar.css +78 -0
- package/src/components/transaction-history/TransactionHistoryDialog.tsx +268 -0
- package/src/components/user/CurrentUserAvatar.tsx +65 -0
- package/src/components/user/UserChip.tsx +62 -0
- package/src/components/user/user.css +39 -0
- package/src/components/user-profile/ChangePasswordForm.tsx +67 -0
- package/src/components/user-profile/OwnUserProfileContent.tsx +665 -0
- package/src/components/user-profile/PublicUserProfileContent.tsx +99 -0
- package/src/components/user-profile/UserDataForm.tsx +75 -0
- package/src/components/user-profile/UserProfileDialog.tsx +110 -0
- package/src/components/user-profile/user-profile-content.css +25 -0
- package/src/config.ts +130 -0
- package/src/globals.d.ts +13 -0
- package/src/index.html +27 -0
- package/src/index.tsx +23 -0
- package/src/lib/badge/Badge.tsx +35 -0
- package/src/lib/badge/badge.css +32 -0
- package/src/lib/button/Button.tsx +129 -0
- package/src/lib/button/button.css +145 -0
- package/src/lib/canvas/canvas-undo-redo.ts +263 -0
- package/src/lib/canvas/defs.ts +170 -0
- package/src/lib/canvas/index.test.ts +189 -0
- package/src/lib/canvas/index.ts +6999 -0
- package/src/lib/canvas/utils.ts +59 -0
- package/src/lib/card/Card.tsx +62 -0
- package/src/lib/card/LoadingCard.tsx +82 -0
- package/src/lib/card/card.css +259 -0
- package/src/lib/chip/Chip.tsx +79 -0
- package/src/lib/chip/chip.css +0 -0
- package/src/lib/dialog/Dialog.tsx +122 -0
- package/src/lib/dialog/SmallDialog.tsx +61 -0
- package/src/lib/dialog/dialog.css +40 -0
- package/src/lib/display-data-structure/index.tsx +21 -0
- package/src/lib/dropdown/CanvasDropdownMenuCard.tsx +68 -0
- package/src/lib/dropdown/CanvasDropdownMenuCardOption.tsx +136 -0
- package/src/lib/dropdown/DropdownButton.tsx +104 -0
- package/src/lib/dropdown/DropdownMenuCard.tsx +324 -0
- package/src/lib/dropdown/DropdownMenuPopup.tsx +27 -0
- package/src/lib/dropdown/dropdown-button.css +76 -0
- package/src/lib/dropdown/dropdown-menu.css +151 -0
- package/src/lib/json-editor/RawJsonEditor.tsx +137 -0
- package/src/lib/json-editor/json-editor.css +35 -0
- package/src/lib/loader/Loader.tsx +120 -0
- package/src/lib/loader/loader.css +38 -0
- package/src/lib/pagination/Pagination.tsx +64 -0
- package/src/lib/popup/CanvasPopupBaseComponent.tsx +103 -0
- package/src/lib/popup/Popup.tsx +243 -0
- package/src/lib/popup/popup.css +16 -0
- package/src/lib/table/RowForm.tsx +301 -0
- package/src/lib/table/Table.tsx +1069 -0
- package/src/lib/table/table.css +249 -0
- package/src/lib/table/types.ts +108 -0
- package/src/lib/text-area/TextArea.tsx +183 -0
- package/src/lib/text-area/text-area.css +156 -0
- package/src/lib/text-field/TextField.tsx +218 -0
- package/src/lib/text-field/index.ts +8 -0
- package/src/lib/text-field/text-field.css +201 -0
- package/src/lib/tooltip/Tooltip.tsx +24 -0
- package/src/lib/tooltip/tooltip.css +17 -0
- package/src/localization/index.ts +47 -0
- package/src/main.css +343 -0
- package/src/pages/Auth.tsx +848 -0
- package/src/pages/Editor.tsx +883 -0
- package/src/pages/ErrorPage.tsx +179 -0
- package/src/pages/Gallery.tsx +1693 -0
- package/src/pages/NewPaymentMethodCallback.tsx +53 -0
- package/src/pages/NotFoundPage.tsx +126 -0
- package/src/pages/PricingPlans.tsx +155 -0
- package/src/pages/auth.css +304 -0
- package/src/pages/gallery.css +421 -0
- package/src/payments/index.ts +187 -0
- package/src/popup-notification/index.ts +90 -0
- package/src/services/database/index.ts +1 -0
- package/src/services/database/utils.ts +1301 -0
- package/src/services/editor/CanvasElement.tsx +2934 -0
- package/src/services/editor/CanvasElementConnectionDeleteButton.ts +204 -0
- package/src/services/editor/CanvasPopup.tsx +749 -0
- package/src/services/editor/EditorService.ts +8157 -0
- package/src/services/editor/area.ts +1312 -0
- package/src/services/editor/connections.ts +1019 -0
- package/src/services/editor/create/condition.ts +25 -0
- package/src/services/editor/create/definition-entity.ts +29 -0
- package/src/services/editor/create/function-call.ts +25 -0
- package/src/services/editor/create/global-event.ts +33 -0
- package/src/services/editor/create/loop.ts +25 -0
- package/src/services/editor/create/operation.ts +30 -0
- package/src/services/editor/create/utils.ts +140 -0
- package/src/services/editor/create/variable-declaration.ts +135 -0
- package/src/services/editor/create/variable-instance.ts +100 -0
- package/src/services/editor/editor-ui-extensions-context.ts +43 -0
- package/src/services/editor/entities-metadata.json +9310 -0
- package/src/services/editor/icons.ts +1093 -0
- package/src/services/editor/index.ts +1 -0
- package/src/services/editor/layout.ts +102 -0
- package/src/services/editor/modules/built-in-function-implementations/base.ts +14 -0
- package/src/services/editor/modules/built-in-function-implementations/create-persisted-entity/index.ts +56 -0
- package/src/services/editor/modules/built-in-function-implementations/delete-persisted-entity/index.ts +55 -0
- package/src/services/editor/modules/built-in-function-implementations/index.ts +4 -0
- package/src/services/editor/modules/built-in-function-implementations/update-persisted-entity/index.ts +56 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/get-files.ts +183 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/list-drives.ts +124 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/list-root-folders.ts +125 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/smart-fetch-document.ts +702 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/upload-document.ts +535 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-gemini/generate-content.ts +193 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-mail/get-emails.ts +586 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/google-mail/send-email.ts +386 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/index.ts +12 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/slack/channels.ts +240 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/slack/messages.ts +210 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/slack/replies.ts +200 -0
- package/src/services/editor/modules/operations-implementations/external-integrations/slack/send-message.ts +177 -0
- package/src/services/editor/modules/operations-implementations/index.ts +1 -0
- package/src/services/editor/modules/search-node-implementation/index.ts +42 -0
- package/src/services/editor/modules/sql-migrations-generation.tsx +1054 -0
- package/src/services/editor/publication/publication.ts +578 -0
- package/src/services/editor/ui.ts +1348 -0
- package/src/services/editor/utils.ts +5868 -0
- package/src/services/editor/value-store.ts +619 -0
- package/src/services/execution/built-in-function-implementations.ts +422 -0
- package/src/services/execution/index.ts +4747 -0
- package/src/services/execution/logic.ts +121 -0
- package/src/services/execution/test-instance.tsx +2296 -0
- package/src/services/execution/utils.ts +33 -0
- package/src/services/execution/value-resolution.test.ts +424 -0
- package/src/services/execution/value-resolution.ts +4087 -0
- package/src/services/integrations/ExternalIntegrationsService.ts +439 -0
- package/src/services/integrations/api.ts +175 -0
- package/src/services/local-relational-database/idb_helper.ts +66 -0
- package/src/services/local-relational-database/index.ts +3308 -0
- package/src/services/local-relational-database/utils.ts +403 -0
- package/src/services/notifications/index.ts +525 -0
- package/src/services/user/index.ts +144 -0
- package/src/setupTests.ts +1 -0
- package/src/socket/socket.ts +248 -0
- package/src/socket/utils.ts +10 -0
- package/src/store/workspace.ts +12 -0
- package/src/theme.ts +19 -0
- package/src/utils/DOM.ts +39 -0
- package/src/utils/date.ts +169 -0
- package/src/utils/index.ts +158 -0
- package/src/utils/react.tsx +679 -0
- package/src/utils/testing.ts +103 -0
|
@@ -0,0 +1,1301 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BUILT_IN_BASE_ENTITY_IDS,
|
|
3
|
+
DefinitionEntityState,
|
|
4
|
+
DataTypeState,
|
|
5
|
+
EntityType,
|
|
6
|
+
getDatabaseEntities,
|
|
7
|
+
PrimitiveTypes,
|
|
8
|
+
isObject,
|
|
9
|
+
searchStatementDefs,
|
|
10
|
+
searchStatementFunctions
|
|
11
|
+
} from '@elyx-code/project-logic-tree';
|
|
12
|
+
import { IJoinQuery, IOrderQuery, IWhereQuery } from 'jsstore';
|
|
13
|
+
import {
|
|
14
|
+
Column,
|
|
15
|
+
Database,
|
|
16
|
+
ISelectQueryResult,
|
|
17
|
+
Table
|
|
18
|
+
} from '../local-relational-database';
|
|
19
|
+
import { resolveColumnTypeFromDataTypeEntity } from '../local-relational-database/utils';
|
|
20
|
+
import { TableColumnType } from '../../lib/table/types';
|
|
21
|
+
import { EditorService } from '../editor';
|
|
22
|
+
import {
|
|
23
|
+
SQLAST as SQLASTLib,
|
|
24
|
+
searchStatementState as searchStatementStateLib,
|
|
25
|
+
searchStatementUtils
|
|
26
|
+
} from '@elyx-code/project-logic-tree';
|
|
27
|
+
import { isEmpty } from '../../utils';
|
|
28
|
+
|
|
29
|
+
const { ColumnRef } = searchStatementStateLib;
|
|
30
|
+
const { SearchLiteralValueType, SearchStatementNodeType } = searchStatementDefs;
|
|
31
|
+
const { getFunctionDefinition } = searchStatementFunctions;
|
|
32
|
+
|
|
33
|
+
type ColumnRef = searchStatementStateLib.ColumnRef;
|
|
34
|
+
type FunctionCall = searchStatementStateLib.FunctionCall;
|
|
35
|
+
type SearchLiteralValueType = searchStatementDefs.SearchLiteralValueType;
|
|
36
|
+
|
|
37
|
+
type SelectStmt = SQLASTLib.SelectStmt;
|
|
38
|
+
type JoinExpr = SQLASTLib.JoinExpr;
|
|
39
|
+
type OrderByClause = SQLASTLib.OrderByClause;
|
|
40
|
+
type SortSpecification = SQLASTLib.SortSpecification;
|
|
41
|
+
type Keyword<T extends string = string> = SQLASTLib.Keyword<T>;
|
|
42
|
+
type SelectClause = SQLASTLib.SelectClause;
|
|
43
|
+
type WhereClause = SQLASTLib.WhereClause;
|
|
44
|
+
type Expr = SQLASTLib.Expr;
|
|
45
|
+
type PostgresqlOperatorExpr = SQLASTLib.PostgresqlOperatorExpr;
|
|
46
|
+
|
|
47
|
+
export function fromColumnMappingsToJsStore(
|
|
48
|
+
columnMappings: (
|
|
49
|
+
| searchStatementUtils.IShallowColumnMapping
|
|
50
|
+
| searchStatementUtils.IColumnMapping
|
|
51
|
+
)[]
|
|
52
|
+
): {
|
|
53
|
+
[columnName: string]: string;
|
|
54
|
+
} {
|
|
55
|
+
return columnMappings.reduce(
|
|
56
|
+
(acc, columnMapping) => {
|
|
57
|
+
acc[
|
|
58
|
+
(columnMapping as searchStatementUtils.IColumnMapping).column
|
|
59
|
+
?.columnName ||
|
|
60
|
+
(
|
|
61
|
+
columnMapping as searchStatementUtils.IShallowColumnMapping
|
|
62
|
+
).from
|
|
63
|
+
] =
|
|
64
|
+
(columnMapping as searchStatementUtils.IColumnMapping).as ||
|
|
65
|
+
(columnMapping as searchStatementUtils.IShallowColumnMapping)
|
|
66
|
+
.to;
|
|
67
|
+
|
|
68
|
+
return acc;
|
|
69
|
+
},
|
|
70
|
+
{} as { [columnName: string]: string }
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function fromColumnRefToTableColumnType(
|
|
75
|
+
column: ColumnRef | FunctionCall
|
|
76
|
+
): TableColumnType {
|
|
77
|
+
if (column.type === SearchStatementNodeType.FunctionCall) {
|
|
78
|
+
const fc = column as FunctionCall;
|
|
79
|
+
const def = fc.functionName
|
|
80
|
+
? getFunctionDefinition(fc.functionName)
|
|
81
|
+
: null;
|
|
82
|
+
if (def) {
|
|
83
|
+
switch (def.returnType) {
|
|
84
|
+
case 'string':
|
|
85
|
+
return TableColumnType.String;
|
|
86
|
+
case 'number':
|
|
87
|
+
return TableColumnType.Number;
|
|
88
|
+
case 'boolean':
|
|
89
|
+
return TableColumnType.Boolean;
|
|
90
|
+
case 'date':
|
|
91
|
+
return TableColumnType.Date;
|
|
92
|
+
default:
|
|
93
|
+
return TableColumnType.String;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return TableColumnType.String;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const col = column as ColumnRef;
|
|
100
|
+
if (!!col.property) {
|
|
101
|
+
const dataType: DataTypeState = col.property?.dataType;
|
|
102
|
+
|
|
103
|
+
if (!dataType) {
|
|
104
|
+
return TableColumnType.String;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!dataType.entity) {
|
|
108
|
+
return TableColumnType.String;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// If the 'entity' of the data type is of type primitive entity,
|
|
112
|
+
// then map to primitive types
|
|
113
|
+
// Otherwise, it is a foreign key reference to an entity, so we map to string
|
|
114
|
+
if (dataType.entity?.type === EntityType.PrimitiveEntity) {
|
|
115
|
+
switch (dataType.entity.name) {
|
|
116
|
+
case PrimitiveTypes.String:
|
|
117
|
+
return TableColumnType.String;
|
|
118
|
+
case PrimitiveTypes.Number:
|
|
119
|
+
return TableColumnType.Number;
|
|
120
|
+
case PrimitiveTypes.Boolean:
|
|
121
|
+
return TableColumnType.Boolean;
|
|
122
|
+
case PrimitiveTypes.Date:
|
|
123
|
+
return TableColumnType.Date;
|
|
124
|
+
case PrimitiveTypes.UUID:
|
|
125
|
+
return TableColumnType.UUID;
|
|
126
|
+
default:
|
|
127
|
+
return TableColumnType.String;
|
|
128
|
+
}
|
|
129
|
+
} else if (dataType.entity?.type === EntityType.DefinitionEntity) {
|
|
130
|
+
return TableColumnType.Relation;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return TableColumnType.String;
|
|
134
|
+
} else if (!!col.literalValue) {
|
|
135
|
+
switch (col.literalValue.valueType) {
|
|
136
|
+
case SearchLiteralValueType.String:
|
|
137
|
+
return TableColumnType.String;
|
|
138
|
+
case SearchLiteralValueType.Number:
|
|
139
|
+
return TableColumnType.Number;
|
|
140
|
+
case SearchLiteralValueType.Date:
|
|
141
|
+
return TableColumnType.Date;
|
|
142
|
+
case SearchLiteralValueType.Boolean:
|
|
143
|
+
return TableColumnType.Boolean;
|
|
144
|
+
case SearchLiteralValueType.Null:
|
|
145
|
+
return TableColumnType.String;
|
|
146
|
+
default:
|
|
147
|
+
return TableColumnType.String;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return TableColumnType.String;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
enum ResolvedOperator {
|
|
154
|
+
And = 'and',
|
|
155
|
+
Or = 'or',
|
|
156
|
+
Like = 'like',
|
|
157
|
+
Not = 'not',
|
|
158
|
+
In = 'in',
|
|
159
|
+
Equal = '=',
|
|
160
|
+
Between = '-',
|
|
161
|
+
BiggerThan = '>',
|
|
162
|
+
SmallerThan = '<',
|
|
163
|
+
BiggerThanOrEqualTo = '>=',
|
|
164
|
+
SmallerThanOrEqualTo = '<=',
|
|
165
|
+
NotEqual = '!='
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function resolveJsstoreOperatorCharacterFromAstOperator(
|
|
169
|
+
operator: searchStatementUtils.SupportedOperators
|
|
170
|
+
): ResolvedOperator | null {
|
|
171
|
+
let resolvedOperator: ResolvedOperator = null;
|
|
172
|
+
|
|
173
|
+
if (typeof operator === 'string') {
|
|
174
|
+
// For simple operators like '=', '>', '<', '<=', etc.
|
|
175
|
+
resolvedOperator = operator as ResolvedOperator;
|
|
176
|
+
} else if (Array.isArray(operator)) {
|
|
177
|
+
// For operators like 'IS NOT' or 'IS DISTINCT FROM', etc.
|
|
178
|
+
const [first, second, third, fourth] = operator;
|
|
179
|
+
const resolvedFirst = resolveJsstoreOperatorCharacterFromAstOperator(
|
|
180
|
+
first as searchStatementUtils.SupportedOperators
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
if (resolvedFirst === '=') {
|
|
184
|
+
resolvedOperator = ResolvedOperator.Equal;
|
|
185
|
+
} else {
|
|
186
|
+
resolvedOperator = resolvedFirst as ResolvedOperator;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (second) {
|
|
190
|
+
const resolvedSecond =
|
|
191
|
+
resolveJsstoreOperatorCharacterFromAstOperator(
|
|
192
|
+
second as searchStatementUtils.SupportedOperators
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
if (
|
|
196
|
+
resolvedFirst === ResolvedOperator.Equal &&
|
|
197
|
+
resolvedSecond === ResolvedOperator.Not
|
|
198
|
+
) {
|
|
199
|
+
resolvedOperator = ResolvedOperator.NotEqual;
|
|
200
|
+
} else {
|
|
201
|
+
resolvedOperator = (resolvedSecond +
|
|
202
|
+
resolvedOperator) as ResolvedOperator;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// if (third) {
|
|
207
|
+
// const resolvedThird = resolveJsstoreOperatorCharacterFromAstOperator(
|
|
208
|
+
// third as Keyword<'DISTINCT'> | Keyword<'FROM'>
|
|
209
|
+
// );
|
|
210
|
+
// }
|
|
211
|
+
} else if (isObject(operator)) {
|
|
212
|
+
// For single keyword operators like 'IS', 'IN', 'LIKE', 'NOT', etc.
|
|
213
|
+
const resolvedKeywordOperator = (operator as Keyword).name;
|
|
214
|
+
|
|
215
|
+
const sanitizedKeywordOperator = resolvedKeywordOperator.toLowerCase();
|
|
216
|
+
|
|
217
|
+
switch (sanitizedKeywordOperator) {
|
|
218
|
+
case 'between': {
|
|
219
|
+
resolvedOperator = ResolvedOperator.Between;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
case 'is': {
|
|
223
|
+
resolvedOperator = ResolvedOperator.Equal;
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
case 'not': {
|
|
227
|
+
resolvedOperator = ResolvedOperator.Not;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
default: {
|
|
231
|
+
resolvedOperator = sanitizedKeywordOperator as ResolvedOperator;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return resolvedOperator;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function fromWhereExprToJsStoreWhereObject(
|
|
241
|
+
whereExpr: Expr,
|
|
242
|
+
knownColumns: searchStatementUtils.IColumnMapping[]
|
|
243
|
+
): IWhereQuery | null {
|
|
244
|
+
if (!whereExpr) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/*
|
|
249
|
+
The Jsstore where object,
|
|
250
|
+
by default assumes any properties to be column names, and the values to be matched exactly for the condition to be met
|
|
251
|
+
All properties are assumed to be ANDed together
|
|
252
|
+
|
|
253
|
+
For 'or', a property called 'or' with a nested object of the same structure is used
|
|
254
|
+
For 'in', a property called 'in' with an array of values is used
|
|
255
|
+
For 'like', a property called 'like' with a literal string value is used such as 'like': '%value%'
|
|
256
|
+
For 'regex', a property called 'regex' with a JS regex value is used such as 'regex': /value/i
|
|
257
|
+
For 'between', a property called '-' with an object with exactly two properties 'low' and 'high' is used such as '-': { low: 0, high: 10 }
|
|
258
|
+
For any columns with date types, the value can be a JS Date object
|
|
259
|
+
|
|
260
|
+
For any common SQL operators, the where object can be passed properties which are the characters of the operator, for example '>': 10
|
|
261
|
+
*/
|
|
262
|
+
let whereObject: IWhereQuery & {
|
|
263
|
+
[key: string]: any;
|
|
264
|
+
} = {};
|
|
265
|
+
|
|
266
|
+
// The current condition is the "right" side of the expression
|
|
267
|
+
if (whereExpr.type === 'binary_expr') {
|
|
268
|
+
const left = whereExpr.left;
|
|
269
|
+
const right = whereExpr.right;
|
|
270
|
+
let leftVarName: string = '';
|
|
271
|
+
let rightVarName: string = '';
|
|
272
|
+
let leftLiteralValue!: string | number | null | boolean | Date;
|
|
273
|
+
let rightLiteralValue!: string | number | null | boolean | Date;
|
|
274
|
+
let previousSiblingObject: IWhereQuery | null = null;
|
|
275
|
+
let nestedObject: IWhereQuery | null = null;
|
|
276
|
+
|
|
277
|
+
const operator: ResolvedOperator | null =
|
|
278
|
+
resolveJsstoreOperatorCharacterFromAstOperator(
|
|
279
|
+
whereExpr.operator as searchStatementUtils.SupportedOperators
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
let objectKey: string = '';
|
|
283
|
+
|
|
284
|
+
if (left.type === 'member_expr') {
|
|
285
|
+
if (left.object.type === 'identifier') {
|
|
286
|
+
// leftVarName += left.object.text;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (left.property.type === 'identifier') {
|
|
290
|
+
leftVarName += left.property.text;
|
|
291
|
+
// leftVarName += '.' + left.property.text;
|
|
292
|
+
}
|
|
293
|
+
} else if (left.type === 'identifier') {
|
|
294
|
+
leftVarName = left.text;
|
|
295
|
+
} else if (left.type === 'number_literal') {
|
|
296
|
+
leftLiteralValue = left.value;
|
|
297
|
+
} else if (left.type === 'string_literal') {
|
|
298
|
+
leftLiteralValue = left.value;
|
|
299
|
+
} else if (left.type === 'boolean_literal') {
|
|
300
|
+
leftLiteralValue = left.value;
|
|
301
|
+
} else if (left.type === 'null_literal') {
|
|
302
|
+
leftLiteralValue = left.value;
|
|
303
|
+
// } else if (left.type === 'paren_expr') {
|
|
304
|
+
// previousSiblingObject = fromWhereExprToJsStoreWhereObject(
|
|
305
|
+
// left.expr as Expr
|
|
306
|
+
// );
|
|
307
|
+
} else if (left.type === 'binary_expr') {
|
|
308
|
+
previousSiblingObject = fromWhereExprToJsStoreWhereObject(
|
|
309
|
+
left,
|
|
310
|
+
knownColumns
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (leftVarName === 'manager') {
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (right.type === 'member_expr') {
|
|
318
|
+
if (right.object.type === 'identifier') {
|
|
319
|
+
// rightVarName += right.object.text;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (right.property.type === 'identifier') {
|
|
323
|
+
// rightVarName += '.' + right.property.text;
|
|
324
|
+
rightVarName += right.property.text;
|
|
325
|
+
}
|
|
326
|
+
} else if (right.type === 'identifier') {
|
|
327
|
+
rightVarName = right.text;
|
|
328
|
+
} else if (right.type === 'number_literal') {
|
|
329
|
+
rightLiteralValue = right.value;
|
|
330
|
+
} else if (right.type === 'string_literal') {
|
|
331
|
+
rightLiteralValue = right.value;
|
|
332
|
+
} else if (right.type === 'boolean_literal') {
|
|
333
|
+
rightLiteralValue = right.value;
|
|
334
|
+
} else if (right.type === 'null_literal') {
|
|
335
|
+
rightLiteralValue = right.value;
|
|
336
|
+
} else if (right.type === 'paren_expr') {
|
|
337
|
+
nestedObject = fromWhereExprToJsStoreWhereObject(
|
|
338
|
+
right.expr as Expr,
|
|
339
|
+
knownColumns
|
|
340
|
+
);
|
|
341
|
+
} else if (right.type === 'binary_expr') {
|
|
342
|
+
nestedObject = fromWhereExprToJsStoreWhereObject(
|
|
343
|
+
right,
|
|
344
|
+
knownColumns
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Sanitize value if needed, based on column type.
|
|
349
|
+
// E.g. if column is a date, the value should be a Date object
|
|
350
|
+
// If column is a number, the value should be a number, etc.
|
|
351
|
+
const foundColumn = knownColumns.find(
|
|
352
|
+
(column) => column.column.columnName === leftVarName
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
const columnType = foundColumn?.column.property?.dataType
|
|
356
|
+
? resolveColumnTypeFromDataTypeEntity(
|
|
357
|
+
foundColumn.column.property.dataType
|
|
358
|
+
)
|
|
359
|
+
: TableColumnType.String;
|
|
360
|
+
|
|
361
|
+
if (columnType === TableColumnType.Date) {
|
|
362
|
+
if (rightLiteralValue) {
|
|
363
|
+
rightLiteralValue = new Date(rightLiteralValue as string);
|
|
364
|
+
}
|
|
365
|
+
if (leftLiteralValue) {
|
|
366
|
+
leftLiteralValue = new Date(leftLiteralValue as string);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Jsstore doens't take null as a value, so we need to convert it to the "empty" value of the type
|
|
371
|
+
if (rightLiteralValue === null) {
|
|
372
|
+
if (
|
|
373
|
+
columnType === TableColumnType.Date ||
|
|
374
|
+
columnType === TableColumnType.String ||
|
|
375
|
+
columnType === TableColumnType.Number ||
|
|
376
|
+
columnType === TableColumnType.UUID ||
|
|
377
|
+
columnType === TableColumnType.Relation ||
|
|
378
|
+
columnType === TableColumnType.Boolean
|
|
379
|
+
) {
|
|
380
|
+
// Padding literal null with empty string
|
|
381
|
+
rightLiteralValue = '';
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (!!operator) {
|
|
386
|
+
if (
|
|
387
|
+
operator === ResolvedOperator.And ||
|
|
388
|
+
operator === ResolvedOperator.Equal
|
|
389
|
+
) {
|
|
390
|
+
objectKey = leftVarName;
|
|
391
|
+
|
|
392
|
+
if (previousSiblingObject) {
|
|
393
|
+
whereObject = {
|
|
394
|
+
...previousSiblingObject,
|
|
395
|
+
...whereObject
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (nestedObject) {
|
|
400
|
+
whereObject = {
|
|
401
|
+
...whereObject,
|
|
402
|
+
...nestedObject
|
|
403
|
+
};
|
|
404
|
+
} else if (rightVarName) {
|
|
405
|
+
whereObject[objectKey] = rightVarName;
|
|
406
|
+
} else {
|
|
407
|
+
whereObject[objectKey] = rightLiteralValue;
|
|
408
|
+
}
|
|
409
|
+
} else if (operator === ResolvedOperator.Or) {
|
|
410
|
+
whereObject.or = {};
|
|
411
|
+
|
|
412
|
+
if (previousSiblingObject) {
|
|
413
|
+
whereObject = {
|
|
414
|
+
...previousSiblingObject,
|
|
415
|
+
...whereObject
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
objectKey = leftVarName;
|
|
420
|
+
|
|
421
|
+
if (nestedObject) {
|
|
422
|
+
whereObject.or = {
|
|
423
|
+
...whereObject.or,
|
|
424
|
+
...nestedObject
|
|
425
|
+
};
|
|
426
|
+
} else if (rightVarName) {
|
|
427
|
+
whereObject.or[objectKey] = rightVarName;
|
|
428
|
+
} else {
|
|
429
|
+
whereObject.or[objectKey] = rightLiteralValue;
|
|
430
|
+
}
|
|
431
|
+
} else if (operator === ResolvedOperator.Like) {
|
|
432
|
+
objectKey = leftVarName;
|
|
433
|
+
|
|
434
|
+
if (previousSiblingObject) {
|
|
435
|
+
whereObject = { ...previousSiblingObject, ...whereObject };
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (nestedObject) {
|
|
439
|
+
whereObject.like = {
|
|
440
|
+
...nestedObject
|
|
441
|
+
};
|
|
442
|
+
} else if (rightVarName) {
|
|
443
|
+
whereObject[objectKey] = {
|
|
444
|
+
like: rightVarName
|
|
445
|
+
};
|
|
446
|
+
} else {
|
|
447
|
+
whereObject[objectKey] = {
|
|
448
|
+
like: rightLiteralValue
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
} else if (['>', '<', '>=', '<=', '!='].includes(operator)) {
|
|
452
|
+
objectKey = leftVarName;
|
|
453
|
+
|
|
454
|
+
if (previousSiblingObject) {
|
|
455
|
+
whereObject = {
|
|
456
|
+
...previousSiblingObject,
|
|
457
|
+
...whereObject
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (nestedObject) {
|
|
462
|
+
whereObject[operator] = {
|
|
463
|
+
...(whereObject[operator] || {}),
|
|
464
|
+
...nestedObject
|
|
465
|
+
};
|
|
466
|
+
} else if (rightVarName) {
|
|
467
|
+
whereObject[objectKey] = {
|
|
468
|
+
[operator]: rightVarName
|
|
469
|
+
};
|
|
470
|
+
} else {
|
|
471
|
+
whereObject[objectKey] = {
|
|
472
|
+
[operator]: rightLiteralValue
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
} else if (operator === ResolvedOperator.In) {
|
|
476
|
+
objectKey = leftVarName;
|
|
477
|
+
|
|
478
|
+
if (previousSiblingObject) {
|
|
479
|
+
whereObject = {
|
|
480
|
+
...previousSiblingObject,
|
|
481
|
+
...whereObject
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (nestedObject) {
|
|
486
|
+
whereObject.in = {
|
|
487
|
+
...nestedObject
|
|
488
|
+
};
|
|
489
|
+
} else if (rightVarName) {
|
|
490
|
+
whereObject[objectKey] = {
|
|
491
|
+
in: rightVarName
|
|
492
|
+
};
|
|
493
|
+
} else {
|
|
494
|
+
whereObject[objectKey] = {
|
|
495
|
+
in: rightLiteralValue
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
} else if (operator === ResolvedOperator.Between) {
|
|
499
|
+
// TODO: implement between, currently it is treated like other operators
|
|
500
|
+
// but we should resolve the two values 'low' and 'high' and add them as keys in the object under the '-' (between) property
|
|
501
|
+
objectKey = leftVarName;
|
|
502
|
+
|
|
503
|
+
if (previousSiblingObject) {
|
|
504
|
+
whereObject = {
|
|
505
|
+
...previousSiblingObject,
|
|
506
|
+
...whereObject
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (nestedObject) {
|
|
511
|
+
whereObject[ResolvedOperator.Between] = {
|
|
512
|
+
...nestedObject
|
|
513
|
+
};
|
|
514
|
+
} else if (rightVarName) {
|
|
515
|
+
whereObject[objectKey] = {
|
|
516
|
+
[ResolvedOperator.Between]: rightVarName
|
|
517
|
+
};
|
|
518
|
+
} else {
|
|
519
|
+
whereObject[objectKey] = {
|
|
520
|
+
[ResolvedOperator.Between]: rightLiteralValue
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return whereObject;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
export function fromWhereClauseToJsStoreWhereObject(
|
|
531
|
+
whereClause: WhereClause,
|
|
532
|
+
knownColumns: searchStatementUtils.IColumnMapping[]
|
|
533
|
+
): IWhereQuery | null {
|
|
534
|
+
if (!whereClause) {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/*
|
|
539
|
+
The Jsstore where object,
|
|
540
|
+
by default assumes any properties to be column names, and the values to be matched exactly for the condition to be met
|
|
541
|
+
All properties are assumed to be ANDed together
|
|
542
|
+
|
|
543
|
+
For 'or', a property called 'or' with a nested object of the same structure is used
|
|
544
|
+
For 'in', a property called 'in' with an array of values is used
|
|
545
|
+
For 'like', a property called 'like' with a literal string value is used such as 'like': '%value%'
|
|
546
|
+
For 'regex', a property called 'regex' with a JS regex value is used such as 'regex': /value/i
|
|
547
|
+
For 'between', a property called '-' with an object with exactly two properties 'low' and 'high' is used such as '-': { low: 0, high: 10 }
|
|
548
|
+
For any columns with date types, the value can be a JS Date object
|
|
549
|
+
|
|
550
|
+
For any common SQL operators, the where object can be passed properties which are the characters of the operator, for example '>': 10
|
|
551
|
+
*/
|
|
552
|
+
const whereObject: IWhereQuery & {
|
|
553
|
+
[key: string]: any;
|
|
554
|
+
} = fromWhereExprToJsStoreWhereObject(whereClause.expr, knownColumns);
|
|
555
|
+
|
|
556
|
+
return whereObject;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
export async function fromOrderByClauseToJsStore(
|
|
560
|
+
orderByClause: OrderByClause,
|
|
561
|
+
parentQuery: SelectStmt,
|
|
562
|
+
helpers: {
|
|
563
|
+
onNestedSelect?: (
|
|
564
|
+
selectStatement: SelectStmt
|
|
565
|
+
) => ISelectQueryResult | Promise<ISelectQueryResult>;
|
|
566
|
+
onDescribeTable?: (tableName: string) => Promise<Table>;
|
|
567
|
+
} = {
|
|
568
|
+
onNestedSelect: () => ({
|
|
569
|
+
columns: [],
|
|
570
|
+
rows: [],
|
|
571
|
+
tableName: null,
|
|
572
|
+
entity: null,
|
|
573
|
+
total: 0
|
|
574
|
+
}),
|
|
575
|
+
onDescribeTable: () => null
|
|
576
|
+
}
|
|
577
|
+
): Promise<IOrderQuery[]> {
|
|
578
|
+
const mainSource =
|
|
579
|
+
searchStatementUtils.getMainSourceFromSelectStatement(parentQuery);
|
|
580
|
+
|
|
581
|
+
return Promise.all(
|
|
582
|
+
(orderByClause.specifications.items as SortSpecification[]).map(
|
|
583
|
+
async (sortSpec) => {
|
|
584
|
+
let type: 'asc' | 'desc';
|
|
585
|
+
|
|
586
|
+
let fullKeyString: string = '';
|
|
587
|
+
|
|
588
|
+
if (sortSpec.direction?.type === 'sort_direction_asc') {
|
|
589
|
+
type = 'asc';
|
|
590
|
+
} else if (sortSpec.direction?.type === 'sort_direction_desc') {
|
|
591
|
+
type = 'desc';
|
|
592
|
+
} else {
|
|
593
|
+
type = 'asc';
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (sortSpec.expr.type === 'member_expr') {
|
|
597
|
+
if (sortSpec.expr.object.type === 'identifier') {
|
|
598
|
+
fullKeyString += sortSpec.expr.object.text;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (sortSpec.expr.property.type === 'identifier') {
|
|
602
|
+
fullKeyString += '.' + sortSpec.expr.property.text;
|
|
603
|
+
}
|
|
604
|
+
} else if (sortSpec.expr.type === 'identifier') {
|
|
605
|
+
fullKeyString = sortSpec.expr.text;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
const mainSelectHasJoins = await hasJoinsInSelectStatement(
|
|
609
|
+
parentQuery,
|
|
610
|
+
helpers
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
if (mainSource.type === 'table' && !mainSelectHasJoins) {
|
|
614
|
+
fullKeyString = fullKeyString.replace(
|
|
615
|
+
mainSource.name + '.',
|
|
616
|
+
''
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return {
|
|
621
|
+
by: fullKeyString,
|
|
622
|
+
type: type
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
)
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
export async function hasJoinsInSelectStatement(
|
|
630
|
+
selectStatement: SelectStmt,
|
|
631
|
+
helpers: {
|
|
632
|
+
onNestedSelect?: (
|
|
633
|
+
selectStatement: SelectStmt
|
|
634
|
+
) => ISelectQueryResult | Promise<ISelectQueryResult>;
|
|
635
|
+
onDescribeTable?: (tableName: string) => Promise<Table>;
|
|
636
|
+
} = {
|
|
637
|
+
onNestedSelect: () => ({
|
|
638
|
+
columns: [],
|
|
639
|
+
rows: [],
|
|
640
|
+
tableName: null,
|
|
641
|
+
entity: null,
|
|
642
|
+
total: 0
|
|
643
|
+
}),
|
|
644
|
+
onDescribeTable: () => null
|
|
645
|
+
}
|
|
646
|
+
): Promise<boolean> {
|
|
647
|
+
const result = await getJoinClausesFromSelectStatement(
|
|
648
|
+
selectStatement,
|
|
649
|
+
helpers
|
|
650
|
+
);
|
|
651
|
+
|
|
652
|
+
return !!result.joins.length;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
export function getAllSelectedColumnNamesFromSelectClause(
|
|
656
|
+
selectClause: SelectClause
|
|
657
|
+
): string[] {
|
|
658
|
+
return selectClause.columns.items.reduce((acc, column) => {
|
|
659
|
+
if (column.type === 'alias') {
|
|
660
|
+
const alias = column.alias.text;
|
|
661
|
+
|
|
662
|
+
acc.push(alias);
|
|
663
|
+
} else if (column.type === 'member_expr') {
|
|
664
|
+
if (column.property.type === 'identifier') {
|
|
665
|
+
acc.push(column.property.text);
|
|
666
|
+
}
|
|
667
|
+
} else if (column.type === 'identifier') {
|
|
668
|
+
acc.push(column.text);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return acc;
|
|
672
|
+
}, [] as string[]);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Turns the nested AST structure into a simplified list of flat join query descriptions in the jsstore format
|
|
676
|
+
// Uses the parent statement to find any alias mappings so they can be added to the join query 'as' property
|
|
677
|
+
// If any join clause is a subquery, it will have to be executed separatly by jsstore
|
|
678
|
+
// and passed to the join query as in the 'store' property with the resulting list of rows from that subquery
|
|
679
|
+
export async function flattenJoinExpr(
|
|
680
|
+
joinExpr: JoinExpr,
|
|
681
|
+
parentQuery: SelectStmt,
|
|
682
|
+
helpers: {
|
|
683
|
+
onNestedSelect?: (
|
|
684
|
+
selectStatement: SelectStmt
|
|
685
|
+
) => ISelectQueryResult | Promise<ISelectQueryResult>;
|
|
686
|
+
onDescribeTable?: (tableName: string) => Promise<Table>;
|
|
687
|
+
} = {
|
|
688
|
+
onNestedSelect: () => ({
|
|
689
|
+
columns: [],
|
|
690
|
+
rows: [],
|
|
691
|
+
tableName: null,
|
|
692
|
+
entity: null,
|
|
693
|
+
total: 0
|
|
694
|
+
}),
|
|
695
|
+
onDescribeTable: () => null
|
|
696
|
+
}
|
|
697
|
+
): Promise<{
|
|
698
|
+
joins: IJoinQuery[];
|
|
699
|
+
columnMappings: searchStatementUtils.IColumnMapping[];
|
|
700
|
+
}> {
|
|
701
|
+
// const mainSource = getMainSourceFromSelectStatement(parentQuery);
|
|
702
|
+
let joinExprs: IJoinQuery[] = [];
|
|
703
|
+
let resultingColumnMappings: searchStatementUtils.IColumnMapping[] = [];
|
|
704
|
+
|
|
705
|
+
const joinTable = searchStatementUtils.getJoinTableFromJoinClause(joinExpr);
|
|
706
|
+
|
|
707
|
+
if (!joinTable) {
|
|
708
|
+
return {
|
|
709
|
+
joins: joinExprs,
|
|
710
|
+
columnMappings: resultingColumnMappings
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const joinType = searchStatementUtils.getJoinTypeFromJoinClause(joinExpr);
|
|
715
|
+
|
|
716
|
+
const joinOn = getJoinOnSpecificationAsTextFromJoinExpr(joinExpr);
|
|
717
|
+
|
|
718
|
+
const selectClause =
|
|
719
|
+
searchStatementUtils.getSelectClauseFromSelectStatement(parentQuery);
|
|
720
|
+
|
|
721
|
+
const ownMappings =
|
|
722
|
+
searchStatementUtils.fromSelectClauseColumnsToColumnMappings(
|
|
723
|
+
selectClause,
|
|
724
|
+
joinTable
|
|
725
|
+
);
|
|
726
|
+
|
|
727
|
+
if (joinExpr.left.type === 'join_expr') {
|
|
728
|
+
const newJoinsResult = await flattenJoinExpr(
|
|
729
|
+
joinExpr.left as JoinExpr,
|
|
730
|
+
parentQuery,
|
|
731
|
+
helpers
|
|
732
|
+
);
|
|
733
|
+
|
|
734
|
+
joinExprs.push(...newJoinsResult.joins);
|
|
735
|
+
resultingColumnMappings.push(...newJoinsResult.columnMappings);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
if (joinExpr.right.type === 'alias') {
|
|
739
|
+
if (
|
|
740
|
+
joinExpr.right.expr.type === 'paren_expr' &&
|
|
741
|
+
joinExpr.right.expr.expr.type === 'select_stmt'
|
|
742
|
+
) {
|
|
743
|
+
const result = await helpers.onNestedSelect?.(
|
|
744
|
+
joinExpr.right.expr.expr
|
|
745
|
+
);
|
|
746
|
+
const nestedAlias = joinExpr.right.alias.text;
|
|
747
|
+
|
|
748
|
+
if (!!(result.rows || []).length && !!nestedAlias) {
|
|
749
|
+
const nestedMappings =
|
|
750
|
+
searchStatementUtils.fromSelectClauseColumnsToColumnMappings(
|
|
751
|
+
selectClause,
|
|
752
|
+
nestedAlias
|
|
753
|
+
);
|
|
754
|
+
|
|
755
|
+
const nested: IJoinQuery = {
|
|
756
|
+
type: joinType,
|
|
757
|
+
store: result.rows,
|
|
758
|
+
meta: {
|
|
759
|
+
primaryKey: result.columns.find(
|
|
760
|
+
(col) => col.column.primaryKey
|
|
761
|
+
)?.column.columnName
|
|
762
|
+
},
|
|
763
|
+
with: null,
|
|
764
|
+
on: joinOn
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
const ownAsObject = fromColumnMappingsToJsStore(nestedMappings);
|
|
768
|
+
|
|
769
|
+
if (!isEmpty(ownAsObject)) {
|
|
770
|
+
nested.as = ownAsObject;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// const newMappedColumns: searchStatementUtils.IColumnMapping[] = result.columns.map((col) => {
|
|
774
|
+
// const mapping = nestedMappings.find(
|
|
775
|
+
// (mapping) => mapping.from === col.columnName
|
|
776
|
+
// );
|
|
777
|
+
|
|
778
|
+
// if (mapping) {
|
|
779
|
+
// return {
|
|
780
|
+
// as: mapping.to,
|
|
781
|
+
// column: col,
|
|
782
|
+
// };
|
|
783
|
+
// }
|
|
784
|
+
|
|
785
|
+
// return {
|
|
786
|
+
// as: col.as,
|
|
787
|
+
// column: col,
|
|
788
|
+
// }
|
|
789
|
+
// });
|
|
790
|
+
|
|
791
|
+
joinExprs.push(nested);
|
|
792
|
+
resultingColumnMappings.push(...result.columns);
|
|
793
|
+
}
|
|
794
|
+
} else if (joinExpr.right.expr.type === 'identifier') {
|
|
795
|
+
const nestedAsJoin: IJoinQuery = {
|
|
796
|
+
type: joinType,
|
|
797
|
+
with: joinTable,
|
|
798
|
+
on: joinOn
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
const nestedAsObject = fromColumnMappingsToJsStore(ownMappings);
|
|
802
|
+
|
|
803
|
+
if (!isEmpty(nestedAsObject)) {
|
|
804
|
+
nestedAsJoin.as = nestedAsObject;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// TODO: Get all columns of this table, then map the ones that changed to the new names
|
|
808
|
+
const table = await helpers.onDescribeTable?.(joinTable);
|
|
809
|
+
|
|
810
|
+
if (table) {
|
|
811
|
+
const newMappedColumns: searchStatementUtils.IColumnMapping[] =
|
|
812
|
+
table.columns.map((col) => {
|
|
813
|
+
const mapping = ownMappings.find(
|
|
814
|
+
(mapping) => mapping.from === col.columnName
|
|
815
|
+
);
|
|
816
|
+
|
|
817
|
+
if (mapping) {
|
|
818
|
+
return {
|
|
819
|
+
as: mapping.to,
|
|
820
|
+
column: col
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
return {
|
|
825
|
+
as: col.columnName,
|
|
826
|
+
column: col
|
|
827
|
+
};
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
resultingColumnMappings.push(...newMappedColumns);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
joinExprs.push(nestedAsJoin);
|
|
834
|
+
}
|
|
835
|
+
} else if (joinExpr.right.type === 'identifier') {
|
|
836
|
+
const nestedAsJoin: IJoinQuery = {
|
|
837
|
+
type: joinType,
|
|
838
|
+
with: joinTable,
|
|
839
|
+
on: joinOn
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
const nestedAsObject = fromColumnMappingsToJsStore(ownMappings);
|
|
843
|
+
|
|
844
|
+
if (!isEmpty(nestedAsObject)) {
|
|
845
|
+
nestedAsJoin.as = nestedAsObject;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// TODO: Get all columns of this table, then map the ones that changed to the new names
|
|
849
|
+
const table = await helpers.onDescribeTable?.(joinTable);
|
|
850
|
+
|
|
851
|
+
if (table) {
|
|
852
|
+
const newMappedColumns: searchStatementUtils.IColumnMapping[] =
|
|
853
|
+
table.columns.map((col) => {
|
|
854
|
+
const mapping = ownMappings.find(
|
|
855
|
+
(mapping) => mapping.from === col.columnName
|
|
856
|
+
);
|
|
857
|
+
// const columnUITransfer = fromColumnInstanceToColumnTransfer(
|
|
858
|
+
// col
|
|
859
|
+
// );
|
|
860
|
+
|
|
861
|
+
if (mapping) {
|
|
862
|
+
return {
|
|
863
|
+
as: mapping.to,
|
|
864
|
+
column: col
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
return {
|
|
869
|
+
as: col.columnName,
|
|
870
|
+
column: col
|
|
871
|
+
};
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
resultingColumnMappings.push(...newMappedColumns);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
joinExprs.push(nestedAsJoin);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
return {
|
|
881
|
+
joins: joinExprs,
|
|
882
|
+
columnMappings: resultingColumnMappings
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
export function flattenJoinExprSync(
|
|
887
|
+
joinExpr: JoinExpr,
|
|
888
|
+
parentQuery: SelectStmt,
|
|
889
|
+
helpers: {
|
|
890
|
+
onDescribeTable?: (tableName: string) => Table;
|
|
891
|
+
} = {
|
|
892
|
+
onDescribeTable: () => null
|
|
893
|
+
}
|
|
894
|
+
): {
|
|
895
|
+
joins: IJoinQuery[];
|
|
896
|
+
columnMappings: searchStatementUtils.IColumnMapping[];
|
|
897
|
+
} {
|
|
898
|
+
let joinExprs: IJoinQuery[] = [];
|
|
899
|
+
let resultingColumnMappings: searchStatementUtils.IColumnMapping[] = [];
|
|
900
|
+
|
|
901
|
+
const joinTable = searchStatementUtils.getJoinTableFromJoinClause(joinExpr);
|
|
902
|
+
|
|
903
|
+
if (!joinTable) {
|
|
904
|
+
return {
|
|
905
|
+
joins: joinExprs,
|
|
906
|
+
columnMappings: resultingColumnMappings
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
const joinType = searchStatementUtils.getJoinTypeFromJoinClause(joinExpr);
|
|
911
|
+
|
|
912
|
+
const joinOn = getJoinOnSpecificationAsTextFromJoinExpr(joinExpr);
|
|
913
|
+
|
|
914
|
+
const selectClause =
|
|
915
|
+
searchStatementUtils.getSelectClauseFromSelectStatement(parentQuery);
|
|
916
|
+
|
|
917
|
+
const ownMappings =
|
|
918
|
+
searchStatementUtils.fromSelectClauseColumnsToColumnMappings(
|
|
919
|
+
selectClause,
|
|
920
|
+
joinTable
|
|
921
|
+
);
|
|
922
|
+
|
|
923
|
+
if (joinExpr.left.type === 'join_expr') {
|
|
924
|
+
const newJoinsResult = flattenJoinExprSync(
|
|
925
|
+
joinExpr.left as JoinExpr,
|
|
926
|
+
parentQuery,
|
|
927
|
+
helpers
|
|
928
|
+
);
|
|
929
|
+
|
|
930
|
+
joinExprs.push(...newJoinsResult.joins);
|
|
931
|
+
resultingColumnMappings.push(...newJoinsResult.columnMappings);
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (joinExpr.right.type === 'alias') {
|
|
935
|
+
if (
|
|
936
|
+
joinExpr.right.expr.type === 'paren_expr' &&
|
|
937
|
+
joinExpr.right.expr.expr.type === 'select_stmt'
|
|
938
|
+
) {
|
|
939
|
+
const mainSubSelect = joinExpr.right.expr.expr as SelectStmt;
|
|
940
|
+
const mainSubQuery =
|
|
941
|
+
searchStatementUtils.getMainSourceFromSelectStatement(
|
|
942
|
+
mainSubSelect
|
|
943
|
+
);
|
|
944
|
+
|
|
945
|
+
const result: ISelectQueryResult = {
|
|
946
|
+
columns: [],
|
|
947
|
+
rows: [],
|
|
948
|
+
tableName: null,
|
|
949
|
+
entity: null,
|
|
950
|
+
total: 0
|
|
951
|
+
};
|
|
952
|
+
|
|
953
|
+
if (mainSubQuery?.type === 'table') {
|
|
954
|
+
const table = helpers.onDescribeTable?.(mainSubQuery.name);
|
|
955
|
+
const selectClause =
|
|
956
|
+
searchStatementUtils.getSelectClauseFromSelectStatement(
|
|
957
|
+
mainSubSelect
|
|
958
|
+
);
|
|
959
|
+
const subQueryMappings =
|
|
960
|
+
searchStatementUtils.fromSelectClauseColumnsToColumnMappings(
|
|
961
|
+
selectClause,
|
|
962
|
+
mainSubQuery.name
|
|
963
|
+
);
|
|
964
|
+
|
|
965
|
+
if (table) {
|
|
966
|
+
result.columns = table.columns.map((col) => {
|
|
967
|
+
const mapping = subQueryMappings.find(
|
|
968
|
+
(mapping) => mapping.from === col.columnName
|
|
969
|
+
);
|
|
970
|
+
|
|
971
|
+
if (mapping) {
|
|
972
|
+
return {
|
|
973
|
+
as: mapping.to,
|
|
974
|
+
column: col
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
return {
|
|
979
|
+
as: col.columnName,
|
|
980
|
+
column: col
|
|
981
|
+
};
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
resultingColumnMappings.push(...result.columns);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
const nestedAlias = joinExpr.right.alias.text;
|
|
989
|
+
|
|
990
|
+
if (!!(result.rows || []).length && !!nestedAlias) {
|
|
991
|
+
const nestedMappings =
|
|
992
|
+
searchStatementUtils.fromSelectClauseColumnsToColumnMappings(
|
|
993
|
+
selectClause,
|
|
994
|
+
nestedAlias
|
|
995
|
+
);
|
|
996
|
+
|
|
997
|
+
const nested: IJoinQuery = {
|
|
998
|
+
type: joinType,
|
|
999
|
+
store: result.rows,
|
|
1000
|
+
meta: {
|
|
1001
|
+
primaryKey: result.columns.find(
|
|
1002
|
+
(col) => col.column.primaryKey
|
|
1003
|
+
)?.column.columnName
|
|
1004
|
+
},
|
|
1005
|
+
with: null,
|
|
1006
|
+
on: joinOn
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
const ownAsObject = fromColumnMappingsToJsStore(nestedMappings);
|
|
1010
|
+
|
|
1011
|
+
if (!isEmpty(ownAsObject)) {
|
|
1012
|
+
nested.as = ownAsObject;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
joinExprs.push(nested);
|
|
1016
|
+
}
|
|
1017
|
+
} else if (joinExpr.right.expr.type === 'identifier') {
|
|
1018
|
+
const nestedAsJoin: IJoinQuery = {
|
|
1019
|
+
type: joinType,
|
|
1020
|
+
with: joinTable,
|
|
1021
|
+
on: joinOn
|
|
1022
|
+
};
|
|
1023
|
+
|
|
1024
|
+
const nestedAsObject = fromColumnMappingsToJsStore(ownMappings);
|
|
1025
|
+
|
|
1026
|
+
if (!isEmpty(nestedAsObject)) {
|
|
1027
|
+
nestedAsJoin.as = nestedAsObject;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
const table = helpers.onDescribeTable?.(joinTable);
|
|
1031
|
+
|
|
1032
|
+
if (table) {
|
|
1033
|
+
const newMappedColumns: searchStatementUtils.IColumnMapping[] =
|
|
1034
|
+
table.columns.map((col) => {
|
|
1035
|
+
const mapping = ownMappings.find(
|
|
1036
|
+
(mapping) => mapping.from === col.columnName
|
|
1037
|
+
);
|
|
1038
|
+
|
|
1039
|
+
if (mapping) {
|
|
1040
|
+
return {
|
|
1041
|
+
as: mapping.to,
|
|
1042
|
+
column: col
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
return {
|
|
1047
|
+
as: col.columnName,
|
|
1048
|
+
column: col
|
|
1049
|
+
};
|
|
1050
|
+
});
|
|
1051
|
+
|
|
1052
|
+
resultingColumnMappings.push(...newMappedColumns);
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
joinExprs.push(nestedAsJoin);
|
|
1056
|
+
}
|
|
1057
|
+
} else if (joinExpr.right.type === 'identifier') {
|
|
1058
|
+
const nestedAsJoin: IJoinQuery = {
|
|
1059
|
+
type: joinType,
|
|
1060
|
+
with: joinTable,
|
|
1061
|
+
on: joinOn
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1064
|
+
const nestedAsObject = fromColumnMappingsToJsStore(ownMappings);
|
|
1065
|
+
|
|
1066
|
+
if (!isEmpty(nestedAsObject)) {
|
|
1067
|
+
nestedAsJoin.as = nestedAsObject;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
const table = helpers.onDescribeTable?.(joinTable);
|
|
1071
|
+
|
|
1072
|
+
if (table) {
|
|
1073
|
+
const newMappedColumns: searchStatementUtils.IColumnMapping[] =
|
|
1074
|
+
table.columns.map((col) => {
|
|
1075
|
+
const mapping = ownMappings.find(
|
|
1076
|
+
(mapping) => mapping.from === col.columnName
|
|
1077
|
+
);
|
|
1078
|
+
|
|
1079
|
+
if (mapping) {
|
|
1080
|
+
return {
|
|
1081
|
+
as: mapping.to,
|
|
1082
|
+
column: col
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
return {
|
|
1087
|
+
as: col.columnName,
|
|
1088
|
+
column: col
|
|
1089
|
+
};
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
resultingColumnMappings.push(...newMappedColumns);
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
joinExprs.push(nestedAsJoin);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
return {
|
|
1099
|
+
joins: joinExprs,
|
|
1100
|
+
columnMappings: resultingColumnMappings
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
export function getJoinClausesFromSelectStatementSync(
|
|
1105
|
+
selectStatement: SelectStmt,
|
|
1106
|
+
helpers: {
|
|
1107
|
+
onDescribeTable?: (tableName: string) => Table;
|
|
1108
|
+
} = {
|
|
1109
|
+
onDescribeTable: () => null
|
|
1110
|
+
}
|
|
1111
|
+
): {
|
|
1112
|
+
joins: IJoinQuery[];
|
|
1113
|
+
// Returns any selected columns in the joins with their alias names
|
|
1114
|
+
// So we can map them to the correct column names in the resulting rows
|
|
1115
|
+
columnMappings: searchStatementUtils.IColumnMapping[];
|
|
1116
|
+
} {
|
|
1117
|
+
const fromClause =
|
|
1118
|
+
searchStatementUtils.getFromClauseFromSelectStatement(selectStatement);
|
|
1119
|
+
|
|
1120
|
+
if (!fromClause) {
|
|
1121
|
+
return {
|
|
1122
|
+
joins: [],
|
|
1123
|
+
columnMappings: []
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
if (fromClause.expr.type === 'join_expr') {
|
|
1128
|
+
return flattenJoinExprSync(
|
|
1129
|
+
fromClause.expr as JoinExpr,
|
|
1130
|
+
selectStatement,
|
|
1131
|
+
helpers
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
return {
|
|
1136
|
+
joins: [],
|
|
1137
|
+
columnMappings: []
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
export async function getJoinClausesFromSelectStatement(
|
|
1142
|
+
selectStatement: SelectStmt,
|
|
1143
|
+
helpers: {
|
|
1144
|
+
onNestedSelect?: (
|
|
1145
|
+
selectStatement: SelectStmt
|
|
1146
|
+
) => ISelectQueryResult | Promise<ISelectQueryResult>;
|
|
1147
|
+
onDescribeTable?: (tableName: string) => Promise<Table>;
|
|
1148
|
+
} = {
|
|
1149
|
+
onNestedSelect: () => ({
|
|
1150
|
+
columns: [],
|
|
1151
|
+
rows: [],
|
|
1152
|
+
tableName: null,
|
|
1153
|
+
entity: null,
|
|
1154
|
+
total: 0
|
|
1155
|
+
}),
|
|
1156
|
+
onDescribeTable: () => null
|
|
1157
|
+
}
|
|
1158
|
+
): Promise<{
|
|
1159
|
+
joins: IJoinQuery[];
|
|
1160
|
+
// Returns any selected columns in the joins with their alias names
|
|
1161
|
+
// So we can map them to the correct column names in the resulting rows
|
|
1162
|
+
columnMappings: searchStatementUtils.IColumnMapping[];
|
|
1163
|
+
}> {
|
|
1164
|
+
const fromClause =
|
|
1165
|
+
searchStatementUtils.getFromClauseFromSelectStatement(selectStatement);
|
|
1166
|
+
|
|
1167
|
+
if (!fromClause) {
|
|
1168
|
+
return {
|
|
1169
|
+
joins: [],
|
|
1170
|
+
columnMappings: []
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
if (fromClause.expr.type === 'join_expr') {
|
|
1175
|
+
return flattenJoinExpr(
|
|
1176
|
+
fromClause.expr as JoinExpr,
|
|
1177
|
+
selectStatement,
|
|
1178
|
+
helpers
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
return {
|
|
1183
|
+
joins: [],
|
|
1184
|
+
columnMappings: []
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
export function getJoinOnSpecificationAsTextFromJoinExpr(
|
|
1189
|
+
joinClause: JoinExpr
|
|
1190
|
+
): string {
|
|
1191
|
+
let text = '';
|
|
1192
|
+
|
|
1193
|
+
if (joinClause.specification?.expr.type === 'binary_expr') {
|
|
1194
|
+
if (joinClause.specification.expr.left.type === 'member_expr') {
|
|
1195
|
+
if (
|
|
1196
|
+
joinClause.specification.expr.left.object.type === 'identifier'
|
|
1197
|
+
) {
|
|
1198
|
+
text += joinClause.specification.expr.left.object.text;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
if (
|
|
1202
|
+
joinClause.specification.expr.left.property.type ===
|
|
1203
|
+
'identifier'
|
|
1204
|
+
) {
|
|
1205
|
+
text += '.' + joinClause.specification.expr.left.property.text;
|
|
1206
|
+
}
|
|
1207
|
+
} else if (joinClause.specification.expr.left.type === 'identifier') {
|
|
1208
|
+
text += joinClause.specification.expr.left.text;
|
|
1209
|
+
} else if (
|
|
1210
|
+
joinClause.specification.expr.left.type === 'number_literal'
|
|
1211
|
+
) {
|
|
1212
|
+
text += joinClause.specification.expr.left.value;
|
|
1213
|
+
} else if (
|
|
1214
|
+
joinClause.specification.expr.left.type === 'string_literal'
|
|
1215
|
+
) {
|
|
1216
|
+
text += `'` + joinClause.specification.expr.left.value + `'`;
|
|
1217
|
+
} else if (
|
|
1218
|
+
joinClause.specification.expr.left.type === 'boolean_literal'
|
|
1219
|
+
) {
|
|
1220
|
+
text += joinClause.specification.expr.left.value;
|
|
1221
|
+
} else if (joinClause.specification.expr.left.type === 'null_literal') {
|
|
1222
|
+
text += joinClause.specification.expr.left.value;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
text += joinClause.specification.expr.operator;
|
|
1226
|
+
|
|
1227
|
+
if (joinClause.specification.expr.right.type === 'member_expr') {
|
|
1228
|
+
if (
|
|
1229
|
+
joinClause.specification.expr.right.object.type === 'identifier'
|
|
1230
|
+
) {
|
|
1231
|
+
text += joinClause.specification.expr.right.object.text;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
if (
|
|
1235
|
+
joinClause.specification.expr.right.property.type ===
|
|
1236
|
+
'identifier'
|
|
1237
|
+
) {
|
|
1238
|
+
text += '.' + joinClause.specification.expr.right.property.text;
|
|
1239
|
+
}
|
|
1240
|
+
} else if (joinClause.specification.expr.right.type === 'identifier') {
|
|
1241
|
+
text += joinClause.specification.expr.right.text;
|
|
1242
|
+
} else if (
|
|
1243
|
+
joinClause.specification.expr.right.type === 'number_literal'
|
|
1244
|
+
) {
|
|
1245
|
+
text += joinClause.specification.expr.right.value;
|
|
1246
|
+
} else if (
|
|
1247
|
+
joinClause.specification.expr.right.type === 'string_literal'
|
|
1248
|
+
) {
|
|
1249
|
+
text += `'` + joinClause.specification.expr.right.value + `'`;
|
|
1250
|
+
} else if (
|
|
1251
|
+
joinClause.specification.expr.right.type === 'boolean_literal'
|
|
1252
|
+
) {
|
|
1253
|
+
text += joinClause.specification.expr.right.value;
|
|
1254
|
+
} else if (
|
|
1255
|
+
joinClause.specification.expr.right.type === 'null_literal'
|
|
1256
|
+
) {
|
|
1257
|
+
text += joinClause.specification.expr.right.value;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
return text;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
export function resolveDatabase(
|
|
1265
|
+
project: EditorService,
|
|
1266
|
+
entity?: DefinitionEntityState
|
|
1267
|
+
): Database {
|
|
1268
|
+
if (!!entity) {
|
|
1269
|
+
return project.localDatabaseStore?.getDatabaseForPersistedEntity(
|
|
1270
|
+
entity
|
|
1271
|
+
);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
const databaseEntities = getDatabaseEntities(project.logic);
|
|
1275
|
+
|
|
1276
|
+
const defaultDatabase = databaseEntities.find((dbEntity) => {
|
|
1277
|
+
const defaultProperty = dbEntity.properties.find((propt) => {
|
|
1278
|
+
return propt.implements.find(
|
|
1279
|
+
(impl) =>
|
|
1280
|
+
impl.id ===
|
|
1281
|
+
BUILT_IN_BASE_ENTITY_IDS['built-in-base-entity']
|
|
1282
|
+
.BUILT_IN_RELATIONAL_DATABASE_ENTITY.properties.default
|
|
1283
|
+
.id
|
|
1284
|
+
);
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
const value = defaultProperty?.getDefaultValue()?.value;
|
|
1288
|
+
|
|
1289
|
+
return value === true;
|
|
1290
|
+
});
|
|
1291
|
+
|
|
1292
|
+
if (!!defaultDatabase) {
|
|
1293
|
+
return project.localDatabaseStore?.getDatabase(defaultDatabase.id);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
if (!!databaseEntities.length) {
|
|
1297
|
+
return project.localDatabaseStore?.getDatabase(databaseEntities[0].id);
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
return null;
|
|
1301
|
+
}
|