@rebasepro/studio 0.0.1-canary.09e5ec5
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/LICENSE +114 -0
- package/README.md +159 -0
- package/dist/ApiExplorer-gMJt5JrS.js +1053 -0
- package/dist/ApiExplorer-gMJt5JrS.js.map +1 -0
- package/dist/AuthSimulationSelector-BF4rkRGp.js +118 -0
- package/dist/AuthSimulationSelector-BF4rkRGp.js.map +1 -0
- package/dist/BranchesView-DcHZtvXo.js +292 -0
- package/dist/BranchesView-DcHZtvXo.js.map +1 -0
- package/dist/CronJobsView-CijCToeK.js +456 -0
- package/dist/CronJobsView-CijCToeK.js.map +1 -0
- package/dist/JSEditor-D8nVp3Lp.js +1308 -0
- package/dist/JSEditor-D8nVp3Lp.js.map +1 -0
- package/dist/MonacoEditor-CMYEjiRf.js +161 -0
- package/dist/MonacoEditor-CMYEjiRf.js.map +1 -0
- package/dist/RLSEditor-DBH09u9v.js +1831 -0
- package/dist/RLSEditor-DBH09u9v.js.map +1 -0
- package/dist/SQLEditor-CkVx9vgr.js +1792 -0
- package/dist/SQLEditor-CkVx9vgr.js.map +1 -0
- package/dist/SchemaVisualizer-BgD5Zb77.js +1069 -0
- package/dist/SchemaVisualizer-BgD5Zb77.js.map +1 -0
- package/dist/StorageView-CTqGFhY9.js +907 -0
- package/dist/StorageView-CTqGFhY9.js.map +1 -0
- package/dist/common/src/collections/CollectionRegistry.d.ts +56 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/data/buildRebaseData.d.ts +14 -0
- package/dist/common/src/index.d.ts +3 -0
- package/dist/common/src/util/builders.d.ts +57 -0
- package/dist/common/src/util/callbacks.d.ts +6 -0
- package/dist/common/src/util/collections.d.ts +11 -0
- package/dist/common/src/util/common.d.ts +2 -0
- package/dist/common/src/util/conditions.d.ts +26 -0
- package/dist/common/src/util/entities.d.ts +58 -0
- package/dist/common/src/util/enums.d.ts +3 -0
- package/dist/common/src/util/index.d.ts +16 -0
- package/dist/common/src/util/navigation_from_path.d.ts +34 -0
- package/dist/common/src/util/navigation_utils.d.ts +20 -0
- package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
- package/dist/common/src/util/paths.d.ts +14 -0
- package/dist/common/src/util/permissions.d.ts +5 -0
- package/dist/common/src/util/references.d.ts +2 -0
- package/dist/common/src/util/relations.d.ts +22 -0
- package/dist/common/src/util/resolutions.d.ts +72 -0
- package/dist/common/src/util/storage.d.ts +24 -0
- package/dist/core/src/components/AIIcon.d.ts +16 -0
- package/dist/core/src/components/ConfirmationDialog.d.ts +9 -0
- package/dist/core/src/components/Debug/UIReferenceView.d.ts +1 -0
- package/dist/core/src/components/Debug/UIStyleGuide.d.ts +1 -0
- package/dist/core/src/components/ErrorTooltip.d.ts +2 -0
- package/dist/core/src/components/ErrorView.d.ts +21 -0
- package/dist/core/src/components/LanguageToggle.d.ts +1 -0
- package/dist/core/src/components/LoginView/LoginView.d.ts +68 -0
- package/dist/core/src/components/LoginView/index.d.ts +2 -0
- package/dist/core/src/components/NotFoundPage.d.ts +1 -0
- package/dist/core/src/components/RebaseAuth.d.ts +10 -0
- package/dist/core/src/components/RebaseLogo.d.ts +7 -0
- package/dist/core/src/components/UnsavedChangesDialog.d.ts +9 -0
- package/dist/core/src/components/UserDisplay.d.ts +7 -0
- package/dist/core/src/components/UserSelectPopover.d.ts +62 -0
- package/dist/core/src/components/UserSettingsView.d.ts +1 -0
- package/dist/core/src/components/common/index.d.ts +6 -0
- package/dist/core/src/components/common/table_height.d.ts +5 -0
- package/dist/core/src/components/common/types.d.ts +63 -0
- package/dist/core/src/components/common/useColumnsIds.d.ts +9 -0
- package/dist/core/src/components/common/useDataTableController.d.ts +45 -0
- package/dist/core/src/components/common/useDebouncedData.d.ts +9 -0
- package/dist/core/src/components/common/useScrollRestoration.d.ts +14 -0
- package/dist/core/src/components/index.d.ts +16 -0
- package/dist/core/src/contexts/AdminModeController.d.ts +4 -0
- package/dist/core/src/contexts/AnalyticsContext.d.ts +3 -0
- package/dist/core/src/contexts/AuthControllerContext.d.ts +3 -0
- package/dist/core/src/contexts/CustomizationControllerContext.d.ts +3 -0
- package/dist/core/src/contexts/DataDriverContext.d.ts +3 -0
- package/dist/core/src/contexts/DatabaseAdminContext.d.ts +3 -0
- package/dist/core/src/contexts/DialogsProvider.d.ts +4 -0
- package/dist/core/src/contexts/EffectiveRoleController.d.ts +4 -0
- package/dist/core/src/contexts/InternalUserManagementContext.d.ts +3 -0
- package/dist/core/src/contexts/ModeController.d.ts +4 -0
- package/dist/core/src/contexts/RebaseClientInstanceContext.d.ts +6 -0
- package/dist/core/src/contexts/RebaseDataContext.d.ts +3 -0
- package/dist/core/src/contexts/SnackbarProvider.d.ts +2 -0
- package/dist/core/src/contexts/StorageSourceContext.d.ts +3 -0
- package/dist/core/src/contexts/UserConfigurationPersistenceContext.d.ts +3 -0
- package/dist/core/src/contexts/index.d.ts +13 -0
- package/dist/core/src/core/PluginLifecycleManager.d.ts +17 -0
- package/dist/core/src/core/PluginProviderStack.d.ts +21 -0
- package/dist/core/src/core/Rebase.d.ts +14 -0
- package/dist/core/src/core/RebaseProps.d.ts +136 -0
- package/dist/core/src/core/RebaseRouter.d.ts +4 -0
- package/dist/core/src/core/RebaseRoutes.d.ts +17 -0
- package/dist/core/src/core/index.d.ts +4 -0
- package/dist/core/src/hooks/ApiConfigContext.d.ts +24 -0
- package/dist/core/src/hooks/data/delete.d.ts +31 -0
- package/dist/core/src/hooks/data/save.d.ts +34 -0
- package/dist/core/src/hooks/data/useCollectionFetch.d.ts +51 -0
- package/dist/core/src/hooks/data/useData.d.ts +13 -0
- package/dist/core/src/hooks/data/useDataOrder.d.ts +12 -0
- package/dist/core/src/hooks/data/useEntityFetch.d.ts +38 -0
- package/dist/core/src/hooks/data/useRelationSelector.d.ts +52 -0
- package/dist/core/src/hooks/data/useUserSelector.d.ts +31 -0
- package/dist/core/src/hooks/index.d.ts +37 -0
- package/dist/core/src/hooks/useAdminModeController.d.ts +19 -0
- package/dist/core/src/hooks/useAnalyticsController.d.ts +5 -0
- package/dist/core/src/hooks/useAuthController.d.ts +11 -0
- package/dist/core/src/hooks/useAuthSubscription.d.ts +2 -0
- package/dist/core/src/hooks/useBackendStorageSource.d.ts +30 -0
- package/dist/core/src/hooks/useBridgeRegistration.d.ts +18 -0
- package/dist/core/src/hooks/useBrowserTitleAndIcon.d.ts +6 -0
- package/dist/core/src/hooks/useBuildAdminModeController.d.ts +6 -0
- package/dist/core/src/hooks/useBuildEffectiveRoleController.d.ts +8 -0
- package/dist/core/src/hooks/useBuildLocalConfigurationPersistence.d.ts +2 -0
- package/dist/core/src/hooks/useBuildModeController.d.ts +6 -0
- package/dist/core/src/hooks/useClipboard.d.ts +57 -0
- package/dist/core/src/hooks/useCollapsedGroups.d.ts +12 -0
- package/dist/core/src/hooks/useCustomizationController.d.ts +11 -0
- package/dist/core/src/hooks/useDialogsController.d.ts +11 -0
- package/dist/core/src/hooks/useEffectiveRoleController.d.ts +7 -0
- package/dist/core/src/hooks/useInternalUserManagementController.d.ts +12 -0
- package/dist/core/src/hooks/useLargeLayout.d.ts +1 -0
- package/dist/core/src/hooks/useModeController.d.ts +19 -0
- package/dist/core/src/hooks/usePermissions.d.ts +12 -0
- package/dist/core/src/hooks/useRebaseClient.d.ts +5 -0
- package/dist/core/src/hooks/useRebaseContext.d.ts +11 -0
- package/dist/core/src/hooks/useRebaseRegistry.d.ts +34 -0
- package/dist/core/src/hooks/useSlot.d.ts +18 -0
- package/dist/core/src/hooks/useSnackbarController.d.ts +20 -0
- package/dist/core/src/hooks/useStorageSource.d.ts +7 -0
- package/dist/core/src/hooks/useStudioBridge.d.ts +91 -0
- package/dist/core/src/hooks/useTranslation.d.ts +17 -0
- package/dist/core/src/hooks/useUnsavedChangesDialog.d.ts +12 -0
- package/dist/core/src/hooks/useUserConfigurationPersistence.d.ts +8 -0
- package/dist/core/src/hooks/useValidateAuthenticator.d.ts +21 -0
- package/dist/core/src/i18n/RebaseI18nProvider.d.ts +33 -0
- package/dist/core/src/index.d.ts +15 -0
- package/dist/core/src/internal/common.d.ts +3 -0
- package/dist/core/src/internal/useRestoreScroll.d.ts +6 -0
- package/dist/core/src/locales/de.d.ts +2 -0
- package/dist/core/src/locales/en.d.ts +10 -0
- package/dist/core/src/locales/es.d.ts +10 -0
- package/dist/core/src/locales/fr.d.ts +2 -0
- package/dist/core/src/locales/hi.d.ts +2 -0
- package/dist/core/src/locales/it.d.ts +2 -0
- package/dist/core/src/locales/pt.d.ts +7 -0
- package/dist/core/src/util/constants.d.ts +1 -0
- package/dist/core/src/util/createFormexStub.d.ts +2 -0
- package/dist/core/src/util/entity_cache.d.ts +27 -0
- package/dist/core/src/util/enums.d.ts +5 -0
- package/dist/core/src/util/icon_list.d.ts +5 -0
- package/dist/core/src/util/icon_synonyms.d.ts +1 -0
- package/dist/core/src/util/icons.d.ts +20 -0
- package/dist/core/src/util/index.d.ts +10 -0
- package/dist/core/src/util/previews.d.ts +4 -0
- package/dist/core/src/util/useStorageUploadController.d.ts +38 -0
- package/dist/core/src/util/useTraceUpdate.d.ts +2 -0
- package/dist/formex/src/Field.d.ts +52 -0
- package/dist/formex/src/Formex.d.ts +7 -0
- package/dist/formex/src/index.d.ts +5 -0
- package/dist/formex/src/types.d.ts +40 -0
- package/dist/formex/src/useCreateFormex.d.ts +14 -0
- package/dist/formex/src/utils.d.ts +16 -0
- package/dist/index.es.js +726 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +9647 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/studio/src/components/ApiExplorer/ApiExplorer.d.ts +9 -0
- package/dist/studio/src/components/ApiExplorer/EndpointDetail.d.ts +9 -0
- package/dist/studio/src/components/ApiExplorer/TryItPanel.d.ts +15 -0
- package/dist/studio/src/components/ApiExplorer/parseSpec.d.ts +16 -0
- package/dist/studio/src/components/ApiExplorer/types.d.ts +90 -0
- package/dist/studio/src/components/AuthSimulationSelector.d.ts +11 -0
- package/dist/studio/src/components/Branches/BranchesView.d.ts +1 -0
- package/dist/studio/src/components/CronJobs/CronJobsView.d.ts +1 -0
- package/dist/studio/src/components/JSEditor/JSEditor.d.ts +1 -0
- package/dist/studio/src/components/JSEditor/JSEditorSidebar.d.ts +21 -0
- package/dist/studio/src/components/JSEditor/JSMonacoEditor.d.ts +18 -0
- package/dist/studio/src/components/RLSEditor/PolicyEditor.d.ts +9 -0
- package/dist/studio/src/components/RLSEditor/RLSEditor.d.ts +19 -0
- package/dist/studio/src/components/RLSEditor/index.d.ts +1 -0
- package/dist/studio/src/components/RebaseStudio.d.ts +2 -0
- package/dist/studio/src/components/SQLEditor/ExplainVisualizer.d.ts +24 -0
- package/dist/studio/src/components/SQLEditor/MonacoEditor.d.ts +17 -0
- package/dist/studio/src/components/SQLEditor/SQLEditor.d.ts +11 -0
- package/dist/studio/src/components/SQLEditor/SQLEditorSidebar.d.ts +21 -0
- package/dist/studio/src/components/SQLEditor/SchemaBrowser.d.ts +8 -0
- package/dist/studio/src/components/SchemaVisualizer/RelationEdge.d.ts +3 -0
- package/dist/studio/src/components/SchemaVisualizer/SchemaVisualizer.d.ts +2 -0
- package/dist/studio/src/components/SchemaVisualizer/TableNode.d.ts +3 -0
- package/dist/studio/src/components/SchemaVisualizer/index.d.ts +5 -0
- package/dist/studio/src/components/SchemaVisualizer/schema-visualizer.utils.d.ts +42 -0
- package/dist/studio/src/components/SchemaVisualizer/useSchemaGraph.d.ts +37 -0
- package/dist/studio/src/components/StorageView/StorageView.d.ts +1 -0
- package/dist/studio/src/components/StudioHomePage.d.ts +9 -0
- package/dist/studio/src/index.d.ts +4 -0
- package/dist/studio/src/utils/entities.d.ts +0 -0
- package/dist/studio/src/utils/pgColumnToProperty.d.ts +6 -0
- package/dist/studio/src/utils/sql_utils.d.ts +52 -0
- package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
- package/dist/types/src/controllers/auth.d.ts +119 -0
- package/dist/types/src/controllers/client.d.ts +170 -0
- package/dist/types/src/controllers/collection_registry.d.ts +45 -0
- package/dist/types/src/controllers/customization_controller.d.ts +60 -0
- package/dist/types/src/controllers/data.d.ts +168 -0
- package/dist/types/src/controllers/data_driver.d.ts +160 -0
- package/dist/types/src/controllers/database_admin.d.ts +11 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
- package/dist/types/src/controllers/effective_role.d.ts +4 -0
- package/dist/types/src/controllers/email.d.ts +34 -0
- package/dist/types/src/controllers/index.d.ts +18 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
- package/dist/types/src/controllers/navigation.d.ts +213 -0
- package/dist/types/src/controllers/registry.d.ts +54 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts +90 -0
- package/dist/types/src/controllers/snackbar.d.ts +24 -0
- package/dist/types/src/controllers/storage.d.ts +171 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/rebase_context.d.ts +105 -0
- package/dist/types/src/types/backend.d.ts +536 -0
- package/dist/types/src/types/builders.d.ts +15 -0
- package/dist/types/src/types/chips.d.ts +5 -0
- package/dist/types/src/types/collections.d.ts +856 -0
- package/dist/types/src/types/cron.d.ts +102 -0
- package/dist/types/src/types/data_source.d.ts +64 -0
- package/dist/types/src/types/entities.d.ts +145 -0
- package/dist/types/src/types/entity_actions.d.ts +98 -0
- package/dist/types/src/types/entity_callbacks.d.ts +173 -0
- package/dist/types/src/types/entity_link_builder.d.ts +7 -0
- package/dist/types/src/types/entity_overrides.d.ts +10 -0
- package/dist/types/src/types/entity_views.d.ts +61 -0
- package/dist/types/src/types/export_import.d.ts +21 -0
- package/dist/types/src/types/index.d.ts +23 -0
- package/dist/types/src/types/locales.d.ts +4 -0
- package/dist/types/src/types/modify_collections.d.ts +5 -0
- package/dist/types/src/types/plugins.d.ts +279 -0
- package/dist/types/src/types/properties.d.ts +1176 -0
- package/dist/types/src/types/property_config.d.ts +70 -0
- package/dist/types/src/types/relations.d.ts +336 -0
- package/dist/types/src/types/slots.d.ts +252 -0
- package/dist/types/src/types/translations.d.ts +870 -0
- package/dist/types/src/types/user_management_delegate.d.ts +121 -0
- package/dist/types/src/types/websockets.d.ts +78 -0
- package/dist/types/src/users/index.d.ts +2 -0
- package/dist/types/src/users/roles.d.ts +22 -0
- package/dist/types/src/users/user.d.ts +46 -0
- package/dist/ui/src/components/Alert.d.ts +12 -0
- package/dist/ui/src/components/Autocomplete.d.ts +21 -0
- package/dist/ui/src/components/Avatar.d.ts +11 -0
- package/dist/ui/src/components/Badge.d.ts +8 -0
- package/dist/ui/src/components/BooleanSwitch.d.ts +14 -0
- package/dist/ui/src/components/BooleanSwitchWithLabel.d.ts +17 -0
- package/dist/ui/src/components/Button.d.ts +14 -0
- package/dist/ui/src/components/Card.d.ts +9 -0
- package/dist/ui/src/components/CenteredView.d.ts +9 -0
- package/dist/ui/src/components/Checkbox.d.ts +13 -0
- package/dist/ui/src/components/Chip.d.ts +26 -0
- package/dist/ui/src/components/CircularProgress.d.ts +5 -0
- package/dist/ui/src/components/CircularProgressCenter.d.ts +11 -0
- package/dist/ui/src/components/Collapse.d.ts +9 -0
- package/dist/ui/src/components/ColorPicker.d.ts +30 -0
- package/dist/ui/src/components/Container.d.ts +8 -0
- package/dist/ui/src/components/DateTimeField.d.ts +24 -0
- package/dist/ui/src/components/DebouncedTextField.d.ts +2 -0
- package/dist/ui/src/components/Dialog.d.ts +39 -0
- package/dist/ui/src/components/DialogActions.d.ts +7 -0
- package/dist/ui/src/components/DialogContent.d.ts +7 -0
- package/dist/ui/src/components/DialogTitle.d.ts +10 -0
- package/dist/ui/src/components/ErrorBoundary.d.ts +11 -0
- package/dist/ui/src/components/ExpandablePanel.d.ts +12 -0
- package/dist/ui/src/components/FileUpload.d.ts +23 -0
- package/dist/ui/src/components/IconButton.d.ts +12 -0
- package/dist/ui/src/components/InfoLabel.d.ts +5 -0
- package/dist/ui/src/components/InputLabel.d.ts +11 -0
- package/dist/ui/src/components/Label.d.ts +7 -0
- package/dist/ui/src/components/LoadingButton.d.ts +7 -0
- package/dist/ui/src/components/Markdown.d.ts +10 -0
- package/dist/ui/src/components/Menu.d.ts +23 -0
- package/dist/ui/src/components/Menubar.d.ts +80 -0
- package/dist/ui/src/components/MultiSelect.d.ts +48 -0
- package/dist/ui/src/components/Paper.d.ts +6 -0
- package/dist/ui/src/components/Popover.d.ts +24 -0
- package/dist/ui/src/components/RadioGroup.d.ts +28 -0
- package/dist/ui/src/components/ResizablePanels.d.ts +18 -0
- package/dist/ui/src/components/SearchBar.d.ts +22 -0
- package/dist/ui/src/components/Select.d.ts +43 -0
- package/dist/ui/src/components/Separator.d.ts +5 -0
- package/dist/ui/src/components/Sheet.d.ts +22 -0
- package/dist/ui/src/components/Skeleton.d.ts +6 -0
- package/dist/ui/src/components/Slider.d.ts +21 -0
- package/dist/ui/src/components/Table.d.ts +34 -0
- package/dist/ui/src/components/Tabs.d.ts +19 -0
- package/dist/ui/src/components/TextField.d.ts +58 -0
- package/dist/ui/src/components/TextareaAutosize.d.ts +43 -0
- package/dist/ui/src/components/ToggleButtonGroup.d.ts +30 -0
- package/dist/ui/src/components/Tooltip.d.ts +19 -0
- package/dist/ui/src/components/Typography.d.ts +36 -0
- package/dist/ui/src/components/VirtualTable/VirtualTable.d.ts +11 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableCell.d.ts +21 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableHeader.d.ts +29 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableHeaderRow.d.ts +2 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +243 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableRow.d.ts +3 -0
- package/dist/ui/src/components/VirtualTable/index.d.ts +3 -0
- package/dist/ui/src/components/VirtualTable/types.d.ts +38 -0
- package/dist/ui/src/components/common/SelectInputLabel.d.ts +5 -0
- package/dist/ui/src/components/index.d.ts +53 -0
- package/dist/ui/src/hooks/PortalContainerContext.d.ts +31 -0
- package/dist/ui/src/hooks/index.d.ts +6 -0
- package/dist/ui/src/hooks/useDebounceCallback.d.ts +1 -0
- package/dist/ui/src/hooks/useDebounceValue.d.ts +1 -0
- package/dist/ui/src/hooks/useDebouncedCallback.d.ts +1 -0
- package/dist/ui/src/hooks/useInjectStyles.d.ts +7 -0
- package/dist/ui/src/hooks/useOutsideAlerter.d.ts +5 -0
- package/dist/ui/src/icons/GitHubIcon.d.ts +2 -0
- package/dist/ui/src/icons/HandleIcon.d.ts +1 -0
- package/dist/ui/src/icons/Icon.d.ts +20 -0
- package/dist/ui/src/icons/cool_icon_keys.d.ts +1 -0
- package/dist/ui/src/icons/icon_keys.d.ts +1 -0
- package/dist/ui/src/icons/index.d.ts +6 -0
- package/dist/ui/src/index.d.ts +5 -0
- package/dist/ui/src/styles.d.ts +12 -0
- package/dist/ui/src/util/chip_colors.d.ts +4 -0
- package/dist/ui/src/util/cls.d.ts +2 -0
- package/dist/ui/src/util/debounce.d.ts +10 -0
- package/dist/ui/src/util/hash.d.ts +1 -0
- package/dist/ui/src/util/index.d.ts +4 -0
- package/dist/ui/src/util/key_to_icon_component.d.ts +1 -0
- package/package.json +84 -0
- package/src/components/ApiExplorer/ApiExplorer.tsx +290 -0
- package/src/components/ApiExplorer/EndpointDetail.tsx +271 -0
- package/src/components/ApiExplorer/TryItPanel.tsx +510 -0
- package/src/components/ApiExplorer/parseSpec.ts +104 -0
- package/src/components/ApiExplorer/types.ts +84 -0
- package/src/components/AuthSimulationSelector.tsx +77 -0
- package/src/components/Branches/BranchesView.tsx +370 -0
- package/src/components/CronJobs/CronJobsView.tsx +346 -0
- package/src/components/JSEditor/JSEditor.tsx +1033 -0
- package/src/components/JSEditor/JSEditorSidebar.tsx +340 -0
- package/src/components/JSEditor/JSMonacoEditor.tsx +390 -0
- package/src/components/RLSEditor/PolicyEditor.tsx +444 -0
- package/src/components/RLSEditor/RLSEditor.tsx +692 -0
- package/src/components/RLSEditor/index.ts +1 -0
- package/src/components/RebaseStudio.tsx +121 -0
- package/src/components/SQLEditor/ExplainVisualizer.tsx +128 -0
- package/src/components/SQLEditor/MonacoEditor.tsx +203 -0
- package/src/components/SQLEditor/SQLEditor.tsx +1419 -0
- package/src/components/SQLEditor/SQLEditorSidebar.tsx +174 -0
- package/src/components/SQLEditor/SchemaBrowser.tsx +158 -0
- package/src/components/SchemaVisualizer/RelationEdge.tsx +102 -0
- package/src/components/SchemaVisualizer/SchemaVisualizer.tsx +665 -0
- package/src/components/SchemaVisualizer/TableNode.tsx +257 -0
- package/src/components/SchemaVisualizer/index.ts +5 -0
- package/src/components/SchemaVisualizer/schema-visualizer.utils.ts +140 -0
- package/src/components/SchemaVisualizer/useSchemaGraph.ts +397 -0
- package/src/components/StorageView/StorageView.tsx +1035 -0
- package/src/components/StudioHomePage.tsx +357 -0
- package/src/index.ts +31 -0
- package/src/utils/entities.ts +2 -0
- package/src/utils/pgColumnToProperty.test.ts +401 -0
- package/src/utils/pgColumnToProperty.ts +275 -0
- package/src/utils/sql_utils.test.ts +265 -0
- package/src/utils/sql_utils.ts +291 -0
- package/src/vite-env.d.ts +1 -0
|
@@ -0,0 +1,1308 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { c } from "react-compiler-runtime";
|
|
3
|
+
import { useRef, useState, useMemo, useEffect, useCallback } from "react";
|
|
4
|
+
import { themes, Highlight } from "prism-react-renderer";
|
|
5
|
+
import { toSnakeCase } from "@rebasepro/utils";
|
|
6
|
+
import { cls, Tabs, Tab, Tooltip, Typography, defaultBorderMixin, iconSize, IconButton, ResizablePanels, Button, CircularProgress, Chip, VirtualTable, Menu, MenuItem, Dialog, DialogTitle, DialogContent, TextField, DialogActions } from "@rebasepro/ui";
|
|
7
|
+
import { PlusIcon, Trash2Icon, TerminalIcon, XIcon, SaveIcon, DownloadIcon, PlayIcon, PencilIcon, MoreVerticalIcon } from "lucide-react";
|
|
8
|
+
import { useModeController, useRebaseContext, useRebaseClient, useApiConfig, useSnackbarController, useStudioCollectionRegistry, useStudioSideEntityController, useTranslation, ErrorView, IconForView } from "@rebasepro/core";
|
|
9
|
+
import { createRebaseClient } from "@rebasepro/client";
|
|
10
|
+
import Editor from "@monaco-editor/react";
|
|
11
|
+
import { A as AuthSimulationSelector } from "./AuthSimulationSelector-BF4rkRGp.js";
|
|
12
|
+
const REBASE_CLIENT_TYPES = `
|
|
13
|
+
// ─── Rebase Client SDK Type Definitions ─────────────────────────────
|
|
14
|
+
|
|
15
|
+
interface Entity<M extends Record<string, any> = any> {
|
|
16
|
+
id: string | number;
|
|
17
|
+
path: string;
|
|
18
|
+
values: M;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface FindParams {
|
|
22
|
+
limit?: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
page?: number;
|
|
25
|
+
where?: Record<string, string>;
|
|
26
|
+
orderBy?: string;
|
|
27
|
+
include?: string[];
|
|
28
|
+
searchString?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface FindResponse<M extends Record<string, any> = any> {
|
|
32
|
+
data: Entity<M>[];
|
|
33
|
+
meta: {
|
|
34
|
+
total: number;
|
|
35
|
+
limit: number;
|
|
36
|
+
offset: number;
|
|
37
|
+
hasMore: boolean;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type FilterOperator = "=" | "!=" | ">" | ">=" | "<" | "<=" | "in" | "not-in" | "array-contains" | "array-contains-any" | "is" | "is_not" | "like" | "ilike";
|
|
42
|
+
|
|
43
|
+
interface QueryBuilder<M extends Record<string, any> = any> {
|
|
44
|
+
where(column: keyof M & string, operator: FilterOperator, value: any): QueryBuilder<M>;
|
|
45
|
+
orderBy(column: keyof M & string, direction?: "asc" | "desc"): QueryBuilder<M>;
|
|
46
|
+
limit(count: number): QueryBuilder<M>;
|
|
47
|
+
offset(count: number): QueryBuilder<M>;
|
|
48
|
+
search(searchString: string): QueryBuilder<M>;
|
|
49
|
+
find(): Promise<FindResponse<M>>;
|
|
50
|
+
findOne(): Promise<Entity<M> | undefined>;
|
|
51
|
+
count(): Promise<number>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface CollectionClient<M extends Record<string, any> = any> {
|
|
55
|
+
find(params?: FindParams): Promise<FindResponse<M>>;
|
|
56
|
+
findById(id: string | number): Promise<Entity<M> | undefined>;
|
|
57
|
+
create(data: Partial<M>, id?: string | number): Promise<Entity<M>>;
|
|
58
|
+
update(id: string | number, data: Partial<M>): Promise<Entity<M>>;
|
|
59
|
+
delete(id: string | number): Promise<void>;
|
|
60
|
+
where(column: keyof M & string, operator: FilterOperator, value: any): QueryBuilder<M>;
|
|
61
|
+
orderBy(column: keyof M & string, direction?: "asc" | "desc"): QueryBuilder<M>;
|
|
62
|
+
limit(count: number): QueryBuilder<M>;
|
|
63
|
+
offset(count: number): QueryBuilder<M>;
|
|
64
|
+
search(searchString: string): QueryBuilder<M>;
|
|
65
|
+
listen?(params: FindParams | undefined, onUpdate: (response: FindResponse<M>) => void, onError?: (error: Error) => void): () => void;
|
|
66
|
+
listenById?(id: string | number, onUpdate: (entity: Entity<M> | undefined) => void, onError?: (error: Error) => void): () => void;
|
|
67
|
+
count?(params?: FindParams): Promise<number>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface RebaseUser {
|
|
71
|
+
uid: string;
|
|
72
|
+
email: string | null;
|
|
73
|
+
displayName: string | null;
|
|
74
|
+
photoURL: string | null;
|
|
75
|
+
emailVerified?: boolean;
|
|
76
|
+
roles?: string[];
|
|
77
|
+
providerId: string;
|
|
78
|
+
isAnonymous: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface RebaseSession {
|
|
82
|
+
accessToken: string;
|
|
83
|
+
refreshToken: string;
|
|
84
|
+
expiresAt: number;
|
|
85
|
+
user: RebaseUser;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type AuthChangeEvent = 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED';
|
|
89
|
+
|
|
90
|
+
interface RebaseAuth {
|
|
91
|
+
signInWithEmail(email: string, password: string): Promise<{ user: RebaseUser; accessToken: string; refreshToken: string }>;
|
|
92
|
+
signUp(email: string, password: string, displayName?: string): Promise<{ user: RebaseUser; accessToken: string; refreshToken: string }>;
|
|
93
|
+
signInWithGoogle(idToken: string): Promise<{ user: RebaseUser; accessToken: string; refreshToken: string }>;
|
|
94
|
+
signOut(): Promise<void>;
|
|
95
|
+
refreshSession(): Promise<RebaseSession>;
|
|
96
|
+
getUser(): Promise<RebaseUser>;
|
|
97
|
+
updateUser(updates: { displayName?: string; photoURL?: string }): Promise<RebaseUser>;
|
|
98
|
+
resetPasswordForEmail(email: string): Promise<{ success: boolean; message: string }>;
|
|
99
|
+
resetPassword(token: string, password: string): Promise<{ success: boolean; message: string }>;
|
|
100
|
+
changePassword(oldPassword: string, newPassword: string): Promise<{ success: boolean; message: string }>;
|
|
101
|
+
sendVerificationEmail(): Promise<{ success: boolean; message: string }>;
|
|
102
|
+
verifyEmail(token: string): Promise<{ success: boolean; message: string }>;
|
|
103
|
+
getSessions(): Promise<any[]>;
|
|
104
|
+
revokeSession(sessionId: string): Promise<{ success: boolean }>;
|
|
105
|
+
revokeAllSessions(): Promise<{ success: boolean }>;
|
|
106
|
+
getSession(): RebaseSession | null;
|
|
107
|
+
onAuthStateChange(callback: (event: AuthChangeEvent, session: RebaseSession | null) => void): () => void;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface AdminUser {
|
|
111
|
+
uid: string;
|
|
112
|
+
email: string;
|
|
113
|
+
displayName: string | null;
|
|
114
|
+
photoURL: string | null;
|
|
115
|
+
provider: string;
|
|
116
|
+
roles: string[];
|
|
117
|
+
createdAt: string;
|
|
118
|
+
updatedAt: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
interface RebaseRole {
|
|
122
|
+
id: string;
|
|
123
|
+
name: string;
|
|
124
|
+
isAdmin: boolean;
|
|
125
|
+
defaultPermissions: Record<string, any> | null;
|
|
126
|
+
config: Record<string, any> | null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
interface RebaseAdmin {
|
|
130
|
+
listUsers(): Promise<{ users: AdminUser[] }>;
|
|
131
|
+
getUser(userId: string): Promise<{ user: AdminUser }>;
|
|
132
|
+
createUser(data: { email: string; displayName?: string; password?: string; roles?: string[] }): Promise<{ user: AdminUser }>;
|
|
133
|
+
updateUser(userId: string, data: { email?: string; displayName?: string; password?: string; roles?: string[] }): Promise<{ user: AdminUser }>;
|
|
134
|
+
deleteUser(userId: string): Promise<{ success: boolean }>;
|
|
135
|
+
listRoles(): Promise<{ roles: RebaseRole[] }>;
|
|
136
|
+
getRole(roleId: string): Promise<{ role: RebaseRole }>;
|
|
137
|
+
createRole(data: { id: string; name: string; isAdmin?: boolean; defaultPermissions?: any; config?: any }): Promise<{ role: RebaseRole }>;
|
|
138
|
+
updateRole(roleId: string, data: { name?: string; isAdmin?: boolean; defaultPermissions?: any; config?: any }): Promise<{ role: RebaseRole }>;
|
|
139
|
+
deleteRole(roleId: string): Promise<{ success: boolean }>;
|
|
140
|
+
bootstrap(): Promise<{ success: boolean; message: string; user: { uid: string; roles: string[] } }>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
interface UploadFileProps {
|
|
144
|
+
file: FileIcon;
|
|
145
|
+
fileName?: string;
|
|
146
|
+
path?: string;
|
|
147
|
+
metadata?: Record<string, any>;
|
|
148
|
+
bucket?: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
interface UploadFileResult {
|
|
152
|
+
path: string;
|
|
153
|
+
bucket?: string;
|
|
154
|
+
downloadUrl?: string;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
interface DownloadConfig {
|
|
158
|
+
url: string | null;
|
|
159
|
+
fileNotFound?: boolean;
|
|
160
|
+
metadata?: any;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
interface StorageSource {
|
|
164
|
+
putObject(props: UploadFileProps): Promise<UploadFileResult>;
|
|
165
|
+
getSignedUrl(pathOrUrl: string, bucket?: string): Promise<DownloadConfig>;
|
|
166
|
+
getObject(path: string, bucket?: string): Promise<FileIcon | null>;
|
|
167
|
+
deleteObject(path: string, bucket?: string): Promise<void>;
|
|
168
|
+
listObjects(path: string, options?: { bucket?: string; maxResults?: number; pageToken?: string }): Promise<any>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
type RebaseData = {
|
|
172
|
+
/** Look up a collection by slug. */
|
|
173
|
+
collection(slug: string): CollectionClient;
|
|
174
|
+
} & {
|
|
175
|
+
/** Dynamic collection access — e.g. client.data.authors */
|
|
176
|
+
[collectionSlug: string]: CollectionClient;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* The Rebase client instance. Use \`client.data\`, \`client.auth\`, \`client.admin\`,
|
|
181
|
+
* \`client.storage\`, and \`client.call()\` to interact with your Rebase backend.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* // Query a collection
|
|
185
|
+
* const result = await client.data.products.find({ limit: 10 });
|
|
186
|
+
*
|
|
187
|
+
* // Create a record
|
|
188
|
+
* await client.data.products.create({ name: "Camera", price: 299 });
|
|
189
|
+
*
|
|
190
|
+
* // Fluent query
|
|
191
|
+
* const expensive = await client.data.products.where("price", ">", 100).orderBy("price", "desc").limit(5).find();
|
|
192
|
+
*
|
|
193
|
+
* // Auth
|
|
194
|
+
* const session = client.auth.getSession();
|
|
195
|
+
*
|
|
196
|
+
* // Admin
|
|
197
|
+
* const { users } = await client.admin.listUsers();
|
|
198
|
+
*
|
|
199
|
+
* // Custom endpoint
|
|
200
|
+
* const result = await client.call("/my-endpoint", { myData: 123 });
|
|
201
|
+
*/
|
|
202
|
+
interface RebaseClient {
|
|
203
|
+
/** Data access — dynamic collection accessors */
|
|
204
|
+
data: RebaseData;
|
|
205
|
+
/** Authentication methods */
|
|
206
|
+
auth: RebaseAuth;
|
|
207
|
+
/** User/role admin methods */
|
|
208
|
+
admin: RebaseAdmin;
|
|
209
|
+
/** Storage operations */
|
|
210
|
+
storage?: StorageSource;
|
|
211
|
+
/** Call a custom server-side endpoint */
|
|
212
|
+
call<T = any>(endpoint: string, payload?: any): Promise<T>;
|
|
213
|
+
/** Direct collection access (shorthand) */
|
|
214
|
+
[collectionSlug: string]: any;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** The pre-configured client instance. Already authenticated with the current user session. */
|
|
218
|
+
declare const client: RebaseClient;
|
|
219
|
+
|
|
220
|
+
/** Execution context with user and collection information. */
|
|
221
|
+
interface JSEditorContext {
|
|
222
|
+
/** The user the script is running as. */
|
|
223
|
+
user: {
|
|
224
|
+
uid: string;
|
|
225
|
+
displayName: string | null;
|
|
226
|
+
email: string | null;
|
|
227
|
+
roles?: string[];
|
|
228
|
+
} | null;
|
|
229
|
+
/** Registered collections with their property names. */
|
|
230
|
+
collections: Array<{
|
|
231
|
+
slug: string;
|
|
232
|
+
name: string;
|
|
233
|
+
properties: string[];
|
|
234
|
+
}>;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Execution context — contains info about the selected user and registered collections. */
|
|
238
|
+
declare const context: JSEditorContext;
|
|
239
|
+
`;
|
|
240
|
+
const JSMonacoEditor = ({
|
|
241
|
+
value,
|
|
242
|
+
onChange,
|
|
243
|
+
onRun,
|
|
244
|
+
className,
|
|
245
|
+
readOnly = false,
|
|
246
|
+
autoFocus = true,
|
|
247
|
+
collectionSlugs = [],
|
|
248
|
+
collections = []
|
|
249
|
+
}) => {
|
|
250
|
+
const {
|
|
251
|
+
mode
|
|
252
|
+
} = useModeController();
|
|
253
|
+
const editorRef = useRef(null);
|
|
254
|
+
const monacoRef = useRef(null);
|
|
255
|
+
const onRunRef = useRef(onRun);
|
|
256
|
+
onRunRef.current = onRun;
|
|
257
|
+
const typesRegisteredRef = useRef(false);
|
|
258
|
+
const handleEditorOnMount = (editorInstance, monaco) => {
|
|
259
|
+
editorRef.current = editorInstance;
|
|
260
|
+
monacoRef.current = monaco;
|
|
261
|
+
editorInstance.addAction({
|
|
262
|
+
id: "run-script",
|
|
263
|
+
label: "Run Script",
|
|
264
|
+
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter],
|
|
265
|
+
contextMenuGroupId: "operation",
|
|
266
|
+
contextMenuOrder: 0,
|
|
267
|
+
run: () => {
|
|
268
|
+
if (onRunRef.current) {
|
|
269
|
+
const selection = editorInstance.getSelection();
|
|
270
|
+
let selectedText;
|
|
271
|
+
if (selection && !selection.isEmpty()) {
|
|
272
|
+
selectedText = editorInstance.getModel()?.getValueInRange(selection)?.trim();
|
|
273
|
+
}
|
|
274
|
+
onRunRef.current(selectedText || void 0);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
if (!typesRegisteredRef.current) {
|
|
279
|
+
typesRegisteredRef.current = true;
|
|
280
|
+
const ts = monaco.languages.typescript;
|
|
281
|
+
ts.typescriptDefaults.setCompilerOptions({
|
|
282
|
+
target: ts.ScriptTarget.ESNext,
|
|
283
|
+
module: ts.ModuleKind.ESNext,
|
|
284
|
+
allowJs: true,
|
|
285
|
+
checkJs: false,
|
|
286
|
+
strict: false,
|
|
287
|
+
noEmit: true,
|
|
288
|
+
allowNonTsExtensions: true
|
|
289
|
+
});
|
|
290
|
+
ts.typescriptDefaults.setDiagnosticsOptions({
|
|
291
|
+
diagnosticCodesToIgnore: [1375, 1108]
|
|
292
|
+
});
|
|
293
|
+
ts.typescriptDefaults.addExtraLib(REBASE_CLIENT_TYPES, "ts:rebase-client.d.ts");
|
|
294
|
+
if (collections.length > 0) {
|
|
295
|
+
const lines = [];
|
|
296
|
+
for (const col of collections) {
|
|
297
|
+
const ifaceName = col.slug.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
298
|
+
const propsType = col.properties.length > 0 ? `{ ${col.properties.map((p) => `${p}: any`).join("; ")} }` : "Record<string, any>";
|
|
299
|
+
lines.push(`/** Collection: ${col.name} (${col.slug}) */`);
|
|
300
|
+
lines.push(`interface ${ifaceName}_Row ${propsType}`);
|
|
301
|
+
lines.push(`declare namespace client.data { const ${col.slug}: CollectionClient<${ifaceName}_Row>; }`);
|
|
302
|
+
}
|
|
303
|
+
ts.typescriptDefaults.addExtraLib(lines.join("\n"), "ts:rebase-collections.d.ts");
|
|
304
|
+
} else if (collectionSlugs.length > 0) {
|
|
305
|
+
const collectionHints = collectionSlugs.map((slug) => `/** Collection: ${slug} */
|
|
306
|
+
declare namespace client.data { const ${slug}: CollectionClient; }`).join("\n");
|
|
307
|
+
ts.typescriptDefaults.addExtraLib(collectionHints, "ts:rebase-collections.d.ts");
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (autoFocus) {
|
|
311
|
+
editorInstance.focus();
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
return /* @__PURE__ */ jsx("div", { className: cls("relative w-full h-full overflow-hidden", className), children: /* @__PURE__ */ jsx(Editor, { height: "100%", defaultLanguage: "typescript", path: "rebase-script.ts", value, onChange, onMount: handleEditorOnMount, theme: mode === "dark" ? "vs-dark" : "vs", options: {
|
|
315
|
+
minimap: {
|
|
316
|
+
enabled: false
|
|
317
|
+
},
|
|
318
|
+
fontSize: 14,
|
|
319
|
+
lineNumbers: "on",
|
|
320
|
+
scrollBeyondLastLine: false,
|
|
321
|
+
automaticLayout: true,
|
|
322
|
+
readOnly,
|
|
323
|
+
tabSize: 2,
|
|
324
|
+
wordWrap: "on",
|
|
325
|
+
suggestOnTriggerCharacters: true,
|
|
326
|
+
quickSuggestions: true,
|
|
327
|
+
parameterHints: {
|
|
328
|
+
enabled: true
|
|
329
|
+
}
|
|
330
|
+
} }) });
|
|
331
|
+
};
|
|
332
|
+
const QUICK_REFERENCE = [{
|
|
333
|
+
label: "Find all",
|
|
334
|
+
code: 'const result = await client.data.collection("COLLECTION").find({ limit: 20 });\nreturn result;',
|
|
335
|
+
description: "Fetch records with pagination"
|
|
336
|
+
}, {
|
|
337
|
+
label: "Find by ID",
|
|
338
|
+
code: 'const item = await client.data.collection("COLLECTION").findById("ID");\nreturn item;',
|
|
339
|
+
description: "Fetch a single record"
|
|
340
|
+
}, {
|
|
341
|
+
label: "Create",
|
|
342
|
+
code: 'const created = await client.data.collection("COLLECTION").create({\n // your fields here\n});\nreturn created;',
|
|
343
|
+
description: "Insert a new record"
|
|
344
|
+
}, {
|
|
345
|
+
label: "Update",
|
|
346
|
+
code: 'const updated = await client.data.collection("COLLECTION").update("ID", {\n // fields to update\n});\nreturn updated;',
|
|
347
|
+
description: "Update an existing record"
|
|
348
|
+
}, {
|
|
349
|
+
label: "Delete",
|
|
350
|
+
code: 'await client.data.collection("COLLECTION").delete("ID");\nreturn { success: true };',
|
|
351
|
+
description: "Delete a record"
|
|
352
|
+
}, {
|
|
353
|
+
label: "Fluent query",
|
|
354
|
+
code: 'const result = await client.data.collection("COLLECTION")\n .where("field", ">", value)\n .orderBy("field", "desc")\n .limit(10)\n .find();\nreturn result;',
|
|
355
|
+
description: "Chained query builder"
|
|
356
|
+
}, {
|
|
357
|
+
label: "Auth: Current session",
|
|
358
|
+
code: "const session = client.auth.getSession();\nreturn session;",
|
|
359
|
+
description: "Get current auth session"
|
|
360
|
+
}, {
|
|
361
|
+
label: "Admin: List users",
|
|
362
|
+
code: "const { users } = await client.admin.listUsers();\nreturn users;",
|
|
363
|
+
description: "List all registered users"
|
|
364
|
+
}, {
|
|
365
|
+
label: "Custom endpoint",
|
|
366
|
+
code: 'const result = await client.call("/my-endpoint", { key: "value" });\nreturn result;',
|
|
367
|
+
description: "Call a custom API endpoint"
|
|
368
|
+
}];
|
|
369
|
+
const JSEditorSidebar = ({
|
|
370
|
+
collections,
|
|
371
|
+
snippets,
|
|
372
|
+
history,
|
|
373
|
+
onSelectSnippet,
|
|
374
|
+
onDeleteSnippet,
|
|
375
|
+
onInsertCode
|
|
376
|
+
}) => {
|
|
377
|
+
const [activeTab, setActiveTab] = useState("collections");
|
|
378
|
+
return /* @__PURE__ */ jsxs("div", { className: cls("flex flex-col h-full w-full bg-white dark:bg-surface-950 border-r", defaultBorderMixin), children: [
|
|
379
|
+
/* @__PURE__ */ jsxs(Tabs, { value: activeTab, onValueChange: (v) => setActiveTab(v), variant: "boxy", className: "border-b border-surface-200 dark:border-surface-950", children: [
|
|
380
|
+
/* @__PURE__ */ jsx(Tab, { value: "collections", children: /* @__PURE__ */ jsx(Tooltip, { title: "Browse collections", children: /* @__PURE__ */ jsx("span", { className: "text-xs", children: "Collections" }) }) }),
|
|
381
|
+
/* @__PURE__ */ jsx(Tab, { value: "reference", children: /* @__PURE__ */ jsx(Tooltip, { title: "SDK quick reference", children: /* @__PURE__ */ jsx("span", { className: "text-xs", children: "Reference" }) }) }),
|
|
382
|
+
/* @__PURE__ */ jsx(Tab, { value: "snippets", children: /* @__PURE__ */ jsx("span", { className: "text-xs", children: "Snippets" }) }),
|
|
383
|
+
/* @__PURE__ */ jsx(Tab, { value: "history", children: /* @__PURE__ */ jsx("span", { className: "text-xs", children: "History" }) })
|
|
384
|
+
] }),
|
|
385
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-grow overflow-hidden relative", children: [
|
|
386
|
+
activeTab === "collections" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
387
|
+
/* @__PURE__ */ jsx("div", { className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin), children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", children: "Collections" }) }),
|
|
388
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow overflow-y-auto p-1 space-y-1 no-scrollbar", children: collections.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark", children: "No collections found" }) }) : collections.map((col) => /* @__PURE__ */ jsx(CollectionItem, { collection: col, onInsertCode }, col.slug)) })
|
|
389
|
+
] }),
|
|
390
|
+
activeTab === "reference" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
391
|
+
/* @__PURE__ */ jsx("div", { className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin), children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", children: "SDK Reference" }) }),
|
|
392
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow overflow-y-auto p-2 space-y-2 no-scrollbar", children: QUICK_REFERENCE.map((ref, i) => /* @__PURE__ */ jsxs("div", { className: cls("group p-2.5 rounded-lg border hover:border-primary/40 dark:hover:border-primary/40", "bg-white dark:bg-surface-900 transition-all cursor-pointer", defaultBorderMixin), onClick: () => onInsertCode(ref.code), children: [
|
|
393
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-1", children: [
|
|
394
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-text-primary dark:text-text-primary-dark font-semibold text-[13px]", children: ref.label }),
|
|
395
|
+
/* @__PURE__ */ jsx("svg", { className: "w-3.5 h-3.5 text-text-disabled group-hover:text-primary transition-colors", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
396
|
+
] }),
|
|
397
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark text-[10px] leading-tight", children: ref.description })
|
|
398
|
+
] }, i)) })
|
|
399
|
+
] }),
|
|
400
|
+
activeTab === "snippets" && (() => {
|
|
401
|
+
const favorites = snippets.filter((s) => s.isFavorite);
|
|
402
|
+
const others = snippets.filter((s_0) => !s_0.isFavorite);
|
|
403
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
404
|
+
/* @__PURE__ */ jsx("div", { className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin), children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", children: "Snippets" }) }),
|
|
405
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow overflow-y-auto p-2 space-y-2 no-scrollbar", children: snippets.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark", children: "No saved snippets yet. Use the save button to store reusable code." }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
406
|
+
favorites.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
407
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", className: "text-[10px] font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark mb-2 px-1 flex items-center", children: [
|
|
408
|
+
/* @__PURE__ */ jsx("svg", { className: "w-3 h-3 mr-1 text-amber-500", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" }) }),
|
|
409
|
+
"Favorites"
|
|
410
|
+
] }),
|
|
411
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: favorites.map((snippet) => /* @__PURE__ */ jsx(SnippetItem, { snippet, onSelect: onSelectSnippet, onDelete: onDeleteSnippet }, snippet.id)) })
|
|
412
|
+
] }),
|
|
413
|
+
others.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
414
|
+
favorites.length > 0 && /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-[10px] font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark mb-2 px-1", children: "Others" }),
|
|
415
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: others.map((snippet_0) => /* @__PURE__ */ jsx(SnippetItem, { snippet: snippet_0, onSelect: onSelectSnippet, onDelete: onDeleteSnippet }, snippet_0.id)) })
|
|
416
|
+
] })
|
|
417
|
+
] }) })
|
|
418
|
+
] });
|
|
419
|
+
})(),
|
|
420
|
+
activeTab === "history" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
421
|
+
/* @__PURE__ */ jsx("div", { className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin), children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-bold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark", children: "History" }) }),
|
|
422
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow overflow-y-auto p-1 space-y-1 no-scrollbar", children: history.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled dark:text-text-disabled-dark", children: "No execution history yet" }) }) : [...history].reverse().map((code, i_0) => /* @__PURE__ */ jsxs("div", { className: "p-2 py-1.5 rounded hover:bg-surface-100 dark:hover:bg-surface-950 cursor-pointer group transition-colors flex items-start", onClick: () => onSelectSnippet(code), children: [
|
|
423
|
+
/* @__PURE__ */ jsx("svg", { className: "w-3 h-3 mt-1 mr-2 text-text-disabled dark:text-text-disabled-dark group-hover:text-primary transition-colors flex-shrink-0", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
424
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-secondary dark:text-text-secondary-dark group-hover:text-text-primary dark:group-hover:text-text-primary-dark text-[11px] line-clamp-2 leading-tight flex-grow font-mono", children: code.length > 120 ? code.substring(0, 120) + "…" : code })
|
|
425
|
+
] }, i_0)) })
|
|
426
|
+
] })
|
|
427
|
+
] })
|
|
428
|
+
] });
|
|
429
|
+
};
|
|
430
|
+
function CollectionItem(t0) {
|
|
431
|
+
const $ = c(28);
|
|
432
|
+
const {
|
|
433
|
+
collection,
|
|
434
|
+
onInsertCode
|
|
435
|
+
} = t0;
|
|
436
|
+
const [expanded, setExpanded] = useState(false);
|
|
437
|
+
let t1;
|
|
438
|
+
if ($[0] !== expanded) {
|
|
439
|
+
t1 = () => setExpanded(!expanded);
|
|
440
|
+
$[0] = expanded;
|
|
441
|
+
$[1] = t1;
|
|
442
|
+
} else {
|
|
443
|
+
t1 = $[1];
|
|
444
|
+
}
|
|
445
|
+
const t2 = expanded && "rotate-90";
|
|
446
|
+
let t3;
|
|
447
|
+
if ($[2] !== t2) {
|
|
448
|
+
t3 = cls("w-3 h-3 mr-1 transition-transform", t2);
|
|
449
|
+
$[2] = t2;
|
|
450
|
+
$[3] = t3;
|
|
451
|
+
} else {
|
|
452
|
+
t3 = $[3];
|
|
453
|
+
}
|
|
454
|
+
let t4;
|
|
455
|
+
if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
456
|
+
t4 = /* @__PURE__ */ jsx("path", { d: "M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" });
|
|
457
|
+
$[4] = t4;
|
|
458
|
+
} else {
|
|
459
|
+
t4 = $[4];
|
|
460
|
+
}
|
|
461
|
+
let t5;
|
|
462
|
+
if ($[5] !== t3) {
|
|
463
|
+
t5 = /* @__PURE__ */ jsx("svg", { className: t3, fill: "currentColor", viewBox: "0 0 20 20", children: t4 });
|
|
464
|
+
$[5] = t3;
|
|
465
|
+
$[6] = t5;
|
|
466
|
+
} else {
|
|
467
|
+
t5 = $[6];
|
|
468
|
+
}
|
|
469
|
+
let t6;
|
|
470
|
+
if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
471
|
+
t6 = /* @__PURE__ */ jsx("svg", { className: "w-3.5 h-3.5 mr-1 shrink-0 text-text-disabled dark:text-text-disabled-dark", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4" }) });
|
|
472
|
+
$[7] = t6;
|
|
473
|
+
} else {
|
|
474
|
+
t6 = $[7];
|
|
475
|
+
}
|
|
476
|
+
let t7;
|
|
477
|
+
if ($[8] !== collection.slug) {
|
|
478
|
+
t7 = /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-text-secondary dark:text-text-secondary-dark text-xs truncate flex-1 min-w-0", children: collection.slug });
|
|
479
|
+
$[8] = collection.slug;
|
|
480
|
+
$[9] = t7;
|
|
481
|
+
} else {
|
|
482
|
+
t7 = $[9];
|
|
483
|
+
}
|
|
484
|
+
let t8;
|
|
485
|
+
if ($[10] !== collection.slug || $[11] !== onInsertCode) {
|
|
486
|
+
t8 = (e) => {
|
|
487
|
+
e.stopPropagation();
|
|
488
|
+
onInsertCode(`const result = await client.data.${collection.slug}.find({ limit: 20 });
|
|
489
|
+
return result;`);
|
|
490
|
+
};
|
|
491
|
+
$[10] = collection.slug;
|
|
492
|
+
$[11] = onInsertCode;
|
|
493
|
+
$[12] = t8;
|
|
494
|
+
} else {
|
|
495
|
+
t8 = $[12];
|
|
496
|
+
}
|
|
497
|
+
let t9;
|
|
498
|
+
if ($[13] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
499
|
+
t9 = /* @__PURE__ */ jsx(PlusIcon, { size: iconSize.smallest });
|
|
500
|
+
$[13] = t9;
|
|
501
|
+
} else {
|
|
502
|
+
t9 = $[13];
|
|
503
|
+
}
|
|
504
|
+
let t10;
|
|
505
|
+
if ($[14] !== t8) {
|
|
506
|
+
t10 = /* @__PURE__ */ jsx(Tooltip, { title: "Insert find() snippet", children: /* @__PURE__ */ jsx(IconButton, { size: "smallest", className: "opacity-0 group-hover:opacity-100 text-text-disabled hover:text-primary transition-all", onClick: t8, children: t9 }) });
|
|
507
|
+
$[14] = t8;
|
|
508
|
+
$[15] = t10;
|
|
509
|
+
} else {
|
|
510
|
+
t10 = $[15];
|
|
511
|
+
}
|
|
512
|
+
let t11;
|
|
513
|
+
if ($[16] !== t1 || $[17] !== t10 || $[18] !== t5 || $[19] !== t7) {
|
|
514
|
+
t11 = /* @__PURE__ */ jsxs("div", { className: "flex items-center p-1 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-950 rounded transition-colors group relative", onClick: t1, children: [
|
|
515
|
+
t5,
|
|
516
|
+
t6,
|
|
517
|
+
t7,
|
|
518
|
+
t10
|
|
519
|
+
] });
|
|
520
|
+
$[16] = t1;
|
|
521
|
+
$[17] = t10;
|
|
522
|
+
$[18] = t5;
|
|
523
|
+
$[19] = t7;
|
|
524
|
+
$[20] = t11;
|
|
525
|
+
} else {
|
|
526
|
+
t11 = $[20];
|
|
527
|
+
}
|
|
528
|
+
let t12;
|
|
529
|
+
if ($[21] !== collection.properties || $[22] !== expanded || $[23] !== onInsertCode) {
|
|
530
|
+
t12 = expanded && collection.properties.length > 0 && /* @__PURE__ */ jsx("div", { className: cls("ml-5 mt-1 space-y-0.5 border-l", defaultBorderMixin), children: collection.properties.map((prop) => /* @__PURE__ */ jsxs("div", { className: "flex items-center p-1 pl-2 hover:bg-surface-50 dark:hover:bg-surface-950 rounded-r cursor-pointer transition-colors group/prop relative min-h-[28px]", onClick: () => onInsertCode(`"${prop}"`), children: [
|
|
531
|
+
/* @__PURE__ */ jsx("svg", { className: "w-3 h-3 mr-1.5 text-text-disabled dark:text-text-disabled-dark shrink-0", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M9 4.5v15m6-15v15m-10.5-1.5h15c.621 0 1.125-.504 1.125-1.125V5.625c0-.621-.504-1.125-1.125-1.125h-15c-.621 0-1.125.504-1.125 1.125v12.75c0 .621.504 1.125 1.125 1.125Z" }) }),
|
|
532
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-primary dark:text-text-primary-dark text-[11px] truncate flex-grow font-mono", children: prop })
|
|
533
|
+
] }, prop)) });
|
|
534
|
+
$[21] = collection.properties;
|
|
535
|
+
$[22] = expanded;
|
|
536
|
+
$[23] = onInsertCode;
|
|
537
|
+
$[24] = t12;
|
|
538
|
+
} else {
|
|
539
|
+
t12 = $[24];
|
|
540
|
+
}
|
|
541
|
+
let t13;
|
|
542
|
+
if ($[25] !== t11 || $[26] !== t12) {
|
|
543
|
+
t13 = /* @__PURE__ */ jsxs("div", { children: [
|
|
544
|
+
t11,
|
|
545
|
+
t12
|
|
546
|
+
] });
|
|
547
|
+
$[25] = t11;
|
|
548
|
+
$[26] = t12;
|
|
549
|
+
$[27] = t13;
|
|
550
|
+
} else {
|
|
551
|
+
t13 = $[27];
|
|
552
|
+
}
|
|
553
|
+
return t13;
|
|
554
|
+
}
|
|
555
|
+
function SnippetItem(t0) {
|
|
556
|
+
const $ = c(19);
|
|
557
|
+
const {
|
|
558
|
+
snippet,
|
|
559
|
+
onSelect,
|
|
560
|
+
onDelete
|
|
561
|
+
} = t0;
|
|
562
|
+
let t1;
|
|
563
|
+
if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
564
|
+
t1 = cls("group p-2 rounded border hover:border-surface-400 dark:hover:border-surface-600 bg-white dark:bg-surface-900 transition-all cursor-pointer relative", defaultBorderMixin);
|
|
565
|
+
$[0] = t1;
|
|
566
|
+
} else {
|
|
567
|
+
t1 = $[0];
|
|
568
|
+
}
|
|
569
|
+
let t2;
|
|
570
|
+
if ($[1] !== onSelect || $[2] !== snippet.code) {
|
|
571
|
+
t2 = () => onSelect(snippet.code);
|
|
572
|
+
$[1] = onSelect;
|
|
573
|
+
$[2] = snippet.code;
|
|
574
|
+
$[3] = t2;
|
|
575
|
+
} else {
|
|
576
|
+
t2 = $[3];
|
|
577
|
+
}
|
|
578
|
+
let t3;
|
|
579
|
+
if ($[4] !== snippet.name) {
|
|
580
|
+
t3 = /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-text-primary dark:text-text-primary-dark font-medium text-[13px] truncate pr-6", children: snippet.name });
|
|
581
|
+
$[4] = snippet.name;
|
|
582
|
+
$[5] = t3;
|
|
583
|
+
} else {
|
|
584
|
+
t3 = $[5];
|
|
585
|
+
}
|
|
586
|
+
let t4;
|
|
587
|
+
if ($[6] !== snippet.code) {
|
|
588
|
+
t4 = /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-secondary dark:text-text-secondary-dark text-[10px] block mt-1 truncate font-mono", children: snippet.code });
|
|
589
|
+
$[6] = snippet.code;
|
|
590
|
+
$[7] = t4;
|
|
591
|
+
} else {
|
|
592
|
+
t4 = $[7];
|
|
593
|
+
}
|
|
594
|
+
let t5;
|
|
595
|
+
if ($[8] !== onDelete || $[9] !== snippet.id) {
|
|
596
|
+
t5 = (e) => {
|
|
597
|
+
e.stopPropagation();
|
|
598
|
+
onDelete(snippet.id);
|
|
599
|
+
};
|
|
600
|
+
$[8] = onDelete;
|
|
601
|
+
$[9] = snippet.id;
|
|
602
|
+
$[10] = t5;
|
|
603
|
+
} else {
|
|
604
|
+
t5 = $[10];
|
|
605
|
+
}
|
|
606
|
+
let t6;
|
|
607
|
+
if ($[11] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
608
|
+
t6 = /* @__PURE__ */ jsx(Trash2Icon, { size: iconSize.smallest });
|
|
609
|
+
$[11] = t6;
|
|
610
|
+
} else {
|
|
611
|
+
t6 = $[11];
|
|
612
|
+
}
|
|
613
|
+
let t7;
|
|
614
|
+
if ($[12] !== t5) {
|
|
615
|
+
t7 = /* @__PURE__ */ jsx(IconButton, { size: "smallest", className: "absolute right-1 top-1 opacity-0 group-hover:opacity-100 text-text-disabled hover:text-red-500 transition-opacity", onClick: t5, children: t6 });
|
|
616
|
+
$[12] = t5;
|
|
617
|
+
$[13] = t7;
|
|
618
|
+
} else {
|
|
619
|
+
t7 = $[13];
|
|
620
|
+
}
|
|
621
|
+
let t8;
|
|
622
|
+
if ($[14] !== t2 || $[15] !== t3 || $[16] !== t4 || $[17] !== t7) {
|
|
623
|
+
t8 = /* @__PURE__ */ jsxs("div", { className: t1, onClick: t2, children: [
|
|
624
|
+
t3,
|
|
625
|
+
t4,
|
|
626
|
+
t7
|
|
627
|
+
] });
|
|
628
|
+
$[14] = t2;
|
|
629
|
+
$[15] = t3;
|
|
630
|
+
$[16] = t4;
|
|
631
|
+
$[17] = t7;
|
|
632
|
+
$[18] = t8;
|
|
633
|
+
} else {
|
|
634
|
+
t8 = $[18];
|
|
635
|
+
}
|
|
636
|
+
return t8;
|
|
637
|
+
}
|
|
638
|
+
const STORAGE_PREFIX = "rebase_js_";
|
|
639
|
+
const DEFAULT_CODE = `// Available: client (RebaseClient)
|
|
640
|
+
// Press Cmd+Enter (Ctrl+Enter) to run
|
|
641
|
+
//
|
|
642
|
+
// Examples:
|
|
643
|
+
// const result = await client.data.collection("your_collection").find({ limit: 10 });
|
|
644
|
+
// const users = await client.admin.listUsers();
|
|
645
|
+
// const session = client.auth.getSession();
|
|
646
|
+
|
|
647
|
+
const result = await client.data.collection("your_collection").find({ limit: 10 });
|
|
648
|
+
return result;
|
|
649
|
+
`;
|
|
650
|
+
function loadFromStorage(key, fallback) {
|
|
651
|
+
try {
|
|
652
|
+
const raw = localStorage.getItem(STORAGE_PREFIX + key);
|
|
653
|
+
return raw ? JSON.parse(raw) : fallback;
|
|
654
|
+
} catch {
|
|
655
|
+
return fallback;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
function saveToStorage(key, value) {
|
|
659
|
+
try {
|
|
660
|
+
localStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value));
|
|
661
|
+
} catch {
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
function formatJSON(value) {
|
|
665
|
+
try {
|
|
666
|
+
return JSON.stringify(value, null, 2);
|
|
667
|
+
} catch {
|
|
668
|
+
return String(value);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
function detectCollectionsInResult(code, resultValue, collections) {
|
|
672
|
+
if (!resultValue || !collections?.length) return [];
|
|
673
|
+
const mentionedSlugs = /* @__PURE__ */ new Set();
|
|
674
|
+
const collectionCallRegex = /\.collection\(["']([^"']+)["']\)/g;
|
|
675
|
+
let m;
|
|
676
|
+
while ((m = collectionCallRegex.exec(code)) !== null) {
|
|
677
|
+
mentionedSlugs.add(m[1]);
|
|
678
|
+
}
|
|
679
|
+
const dotAccessRegex = /client\.data\.([a-zA-Z_][a-zA-Z0-9_]*)\./g;
|
|
680
|
+
while ((m = dotAccessRegex.exec(code)) !== null) {
|
|
681
|
+
if (!["collection", "find", "findById", "create", "update", "delete"].includes(m[1])) {
|
|
682
|
+
mentionedSlugs.add(m[1]);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (mentionedSlugs.size === 0) return [];
|
|
686
|
+
let rows = [];
|
|
687
|
+
if (resultValue?.data && Array.isArray(resultValue.data)) {
|
|
688
|
+
rows = resultValue.data;
|
|
689
|
+
} else if (Array.isArray(resultValue)) {
|
|
690
|
+
rows = resultValue;
|
|
691
|
+
}
|
|
692
|
+
const hasId = rows.length > 0 && rows.some((r) => r?.id != null);
|
|
693
|
+
if (!hasId) return [];
|
|
694
|
+
const matched = [];
|
|
695
|
+
for (const slug of mentionedSlugs) {
|
|
696
|
+
const normalised = toSnakeCase(slug);
|
|
697
|
+
const col = collections.find((c2) => {
|
|
698
|
+
const tableName = c2.table || toSnakeCase(c2.slug);
|
|
699
|
+
return c2.slug === slug || tableName === normalised || toSnakeCase(c2.slug) === normalised;
|
|
700
|
+
});
|
|
701
|
+
if (col) {
|
|
702
|
+
matched.push({
|
|
703
|
+
collectionSlug: col.slug,
|
|
704
|
+
collection: col,
|
|
705
|
+
pkColumn: "id"
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return matched;
|
|
710
|
+
}
|
|
711
|
+
function JSEditor() {
|
|
712
|
+
const rebaseContext = useRebaseContext();
|
|
713
|
+
const rebaseClient = useRebaseClient();
|
|
714
|
+
const apiConfig = useApiConfig();
|
|
715
|
+
const snackbar = useSnackbarController();
|
|
716
|
+
const collectionRegistry = useStudioCollectionRegistry();
|
|
717
|
+
const sideEntityController = useStudioSideEntityController();
|
|
718
|
+
const {
|
|
719
|
+
t
|
|
720
|
+
} = useTranslation();
|
|
721
|
+
const userManagement = rebaseContext.userManagement;
|
|
722
|
+
const currentUser = rebaseContext.authController?.user;
|
|
723
|
+
const [tabs, setTabs] = useState(() => loadFromStorage("tabs", [{
|
|
724
|
+
id: "1",
|
|
725
|
+
name: "Script 1",
|
|
726
|
+
code: DEFAULT_CODE
|
|
727
|
+
}]));
|
|
728
|
+
const [activeTabId, setActiveTabId] = useState(() => loadFromStorage("activeTab", "1"));
|
|
729
|
+
const [result, setResult] = useState(null);
|
|
730
|
+
const [isRunning, setIsRunning] = useState(false);
|
|
731
|
+
const [snippets, setSnippets] = useState(() => loadFromStorage("snippets", []));
|
|
732
|
+
const [history, setHistory] = useState(() => loadFromStorage("history", []));
|
|
733
|
+
const [showSaveDialog, setShowSaveDialog] = useState(false);
|
|
734
|
+
const [snippetName, setSnippetName] = useState("");
|
|
735
|
+
const [resultView, setResultView] = useState("json");
|
|
736
|
+
const [selectedUser, setSelectedUser] = useState(null);
|
|
737
|
+
const [authMode, setAuthMode] = useState("jwt");
|
|
738
|
+
const [sidebarSize, setSidebarSize] = useState(() => {
|
|
739
|
+
try {
|
|
740
|
+
const stored = localStorage.getItem(STORAGE_PREFIX + "sidebar_size");
|
|
741
|
+
return stored ? Number(stored) : 18;
|
|
742
|
+
} catch {
|
|
743
|
+
return 18;
|
|
744
|
+
}
|
|
745
|
+
});
|
|
746
|
+
const [editorHeight, setEditorHeight] = useState(() => {
|
|
747
|
+
try {
|
|
748
|
+
const stored_0 = localStorage.getItem(STORAGE_PREFIX + "editor_height");
|
|
749
|
+
return stored_0 ? Number(stored_0) : 55;
|
|
750
|
+
} catch {
|
|
751
|
+
return 55;
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
const activeTab = tabs.find((t_0) => t_0.id === activeTabId) ?? tabs[0];
|
|
755
|
+
const collectionInfos = useMemo(() => {
|
|
756
|
+
const collections = collectionRegistry?.collections ?? [];
|
|
757
|
+
return collections.map((col) => ({
|
|
758
|
+
slug: col.slug,
|
|
759
|
+
name: col.name,
|
|
760
|
+
properties: Object.keys(col.properties ?? {})
|
|
761
|
+
}));
|
|
762
|
+
}, [collectionRegistry?.collections]);
|
|
763
|
+
const collectionSlugs = useMemo(() => collectionInfos.map((c2) => c2.slug), [collectionInfos]);
|
|
764
|
+
const users = useMemo(() => {
|
|
765
|
+
const managed = (userManagement?.users ?? []).map((u) => ({
|
|
766
|
+
uid: u.uid,
|
|
767
|
+
displayName: u.displayName,
|
|
768
|
+
email: u.email,
|
|
769
|
+
photoURL: u.photoURL,
|
|
770
|
+
roles: u.roles
|
|
771
|
+
}));
|
|
772
|
+
if (currentUser && !managed.some((u_0) => u_0.uid === currentUser.uid)) {
|
|
773
|
+
managed.unshift({
|
|
774
|
+
uid: currentUser.uid,
|
|
775
|
+
displayName: currentUser.displayName,
|
|
776
|
+
email: currentUser.email,
|
|
777
|
+
photoURL: currentUser.photoURL,
|
|
778
|
+
roles: currentUser.roles
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
return managed;
|
|
782
|
+
}, [userManagement?.users, currentUser]);
|
|
783
|
+
const currentSelectableUser = useMemo(() => {
|
|
784
|
+
if (!currentUser) return null;
|
|
785
|
+
return {
|
|
786
|
+
uid: currentUser.uid,
|
|
787
|
+
displayName: currentUser.displayName,
|
|
788
|
+
email: currentUser.email,
|
|
789
|
+
photoURL: currentUser.photoURL,
|
|
790
|
+
roles: currentUser.roles
|
|
791
|
+
};
|
|
792
|
+
}, [currentUser]);
|
|
793
|
+
useEffect(() => {
|
|
794
|
+
saveToStorage("tabs", tabs);
|
|
795
|
+
}, [tabs]);
|
|
796
|
+
useEffect(() => {
|
|
797
|
+
saveToStorage("activeTab", activeTabId);
|
|
798
|
+
}, [activeTabId]);
|
|
799
|
+
useEffect(() => {
|
|
800
|
+
saveToStorage("snippets", snippets);
|
|
801
|
+
}, [snippets]);
|
|
802
|
+
useEffect(() => {
|
|
803
|
+
saveToStorage("history", history);
|
|
804
|
+
}, [history]);
|
|
805
|
+
useEffect(() => {
|
|
806
|
+
try {
|
|
807
|
+
localStorage.setItem(STORAGE_PREFIX + "sidebar_size", sidebarSize.toString());
|
|
808
|
+
} catch {
|
|
809
|
+
}
|
|
810
|
+
}, [sidebarSize]);
|
|
811
|
+
useEffect(() => {
|
|
812
|
+
try {
|
|
813
|
+
localStorage.setItem(STORAGE_PREFIX + "editor_height", editorHeight.toString());
|
|
814
|
+
} catch {
|
|
815
|
+
}
|
|
816
|
+
}, [editorHeight]);
|
|
817
|
+
const updateActiveCode = useCallback((code) => {
|
|
818
|
+
setTabs((prev) => prev.map((t_1) => t_1.id === activeTabId ? {
|
|
819
|
+
...t_1,
|
|
820
|
+
code: code ?? ""
|
|
821
|
+
} : t_1));
|
|
822
|
+
}, [activeTabId]);
|
|
823
|
+
const addTab = useCallback(() => {
|
|
824
|
+
const id = String(Date.now());
|
|
825
|
+
const newTab = {
|
|
826
|
+
id,
|
|
827
|
+
name: `Script ${tabs.length + 1}`,
|
|
828
|
+
code: DEFAULT_CODE
|
|
829
|
+
};
|
|
830
|
+
setTabs((prev_0) => [...prev_0, newTab]);
|
|
831
|
+
setActiveTabId(id);
|
|
832
|
+
}, [tabs.length]);
|
|
833
|
+
const closeTab = useCallback((tabId) => {
|
|
834
|
+
setTabs((prev_1) => {
|
|
835
|
+
const filtered = prev_1.filter((t_2) => t_2.id !== tabId);
|
|
836
|
+
if (filtered.length === 0) {
|
|
837
|
+
const fresh = {
|
|
838
|
+
id: String(Date.now()),
|
|
839
|
+
name: "Script 1",
|
|
840
|
+
code: DEFAULT_CODE
|
|
841
|
+
};
|
|
842
|
+
setActiveTabId(fresh.id);
|
|
843
|
+
return [fresh];
|
|
844
|
+
}
|
|
845
|
+
if (activeTabId === tabId) {
|
|
846
|
+
setActiveTabId(filtered[filtered.length - 1].id);
|
|
847
|
+
}
|
|
848
|
+
return filtered;
|
|
849
|
+
});
|
|
850
|
+
}, [activeTabId]);
|
|
851
|
+
const buildClient = useCallback(async () => {
|
|
852
|
+
const apiUrl = apiConfig?.apiUrl;
|
|
853
|
+
const getAuthToken = apiConfig?.getAuthToken;
|
|
854
|
+
if (!apiUrl) {
|
|
855
|
+
throw new Error("API URL not configured. Make sure apiUrl is set.");
|
|
856
|
+
}
|
|
857
|
+
if (authMode === "none") {
|
|
858
|
+
const client = createRebaseClient({
|
|
859
|
+
baseUrl: apiUrl,
|
|
860
|
+
token: void 0
|
|
861
|
+
});
|
|
862
|
+
return {
|
|
863
|
+
client,
|
|
864
|
+
isScoped: true
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
if (!selectedUser || currentUser && selectedUser.uid === currentUser.uid) {
|
|
868
|
+
if (!rebaseClient) {
|
|
869
|
+
throw new Error("Application client is not initialized.");
|
|
870
|
+
}
|
|
871
|
+
return {
|
|
872
|
+
client: rebaseClient,
|
|
873
|
+
isScoped: false
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
let token;
|
|
877
|
+
if (getAuthToken) {
|
|
878
|
+
token = await getAuthToken() ?? void 0;
|
|
879
|
+
}
|
|
880
|
+
if (!token) {
|
|
881
|
+
throw new Error("No auth token available. Please sign in first.");
|
|
882
|
+
}
|
|
883
|
+
const client_0 = createRebaseClient({
|
|
884
|
+
baseUrl: apiUrl,
|
|
885
|
+
token
|
|
886
|
+
});
|
|
887
|
+
return {
|
|
888
|
+
client: client_0,
|
|
889
|
+
isScoped: true
|
|
890
|
+
};
|
|
891
|
+
}, [apiConfig, rebaseClient, selectedUser, currentUser, authMode]);
|
|
892
|
+
const executeCode = useCallback(async (codeOverride) => {
|
|
893
|
+
const code_0 = codeOverride ?? activeTab?.code ?? "";
|
|
894
|
+
if (!code_0.trim()) return;
|
|
895
|
+
setIsRunning(true);
|
|
896
|
+
setResult(null);
|
|
897
|
+
setHistory((prev_2) => {
|
|
898
|
+
const deduped = prev_2.filter((h) => h !== code_0);
|
|
899
|
+
return [...deduped, code_0].slice(-50);
|
|
900
|
+
});
|
|
901
|
+
const consoleEntries = [];
|
|
902
|
+
const startTime = performance.now();
|
|
903
|
+
let scopedClientToCleanUp = null;
|
|
904
|
+
const originalConsole = {
|
|
905
|
+
log: console.log,
|
|
906
|
+
warn: console.warn,
|
|
907
|
+
error: console.error,
|
|
908
|
+
info: console.info
|
|
909
|
+
};
|
|
910
|
+
const captureConsole = (type) => (...args) => {
|
|
911
|
+
consoleEntries.push({
|
|
912
|
+
type,
|
|
913
|
+
args,
|
|
914
|
+
timestamp: Date.now()
|
|
915
|
+
});
|
|
916
|
+
originalConsole[type](...args);
|
|
917
|
+
};
|
|
918
|
+
try {
|
|
919
|
+
console.log = captureConsole("log");
|
|
920
|
+
console.warn = captureConsole("warn");
|
|
921
|
+
console.error = captureConsole("error");
|
|
922
|
+
console.info = captureConsole("info");
|
|
923
|
+
const {
|
|
924
|
+
client: client_1,
|
|
925
|
+
isScoped
|
|
926
|
+
} = await buildClient();
|
|
927
|
+
if (isScoped) {
|
|
928
|
+
scopedClientToCleanUp = client_1;
|
|
929
|
+
}
|
|
930
|
+
const context = {
|
|
931
|
+
user: selectedUser ?? (currentUser ? {
|
|
932
|
+
uid: currentUser.uid,
|
|
933
|
+
displayName: currentUser.displayName,
|
|
934
|
+
email: currentUser.email,
|
|
935
|
+
roles: currentUser.roles
|
|
936
|
+
} : null),
|
|
937
|
+
collections: collectionInfos
|
|
938
|
+
};
|
|
939
|
+
const AsyncFunction = Object.getPrototypeOf(async function() {
|
|
940
|
+
}).constructor;
|
|
941
|
+
const fn = new AsyncFunction("client", "context", code_0);
|
|
942
|
+
const value = await fn(client_1, context);
|
|
943
|
+
const duration_0 = performance.now() - startTime;
|
|
944
|
+
setResult({
|
|
945
|
+
value,
|
|
946
|
+
console: consoleEntries,
|
|
947
|
+
duration: duration_0,
|
|
948
|
+
timestamp: Date.now()
|
|
949
|
+
});
|
|
950
|
+
if (value?.data && Array.isArray(value.data)) {
|
|
951
|
+
setResultView("table");
|
|
952
|
+
} else if (consoleEntries.length > 0 && value === void 0) {
|
|
953
|
+
setResultView("console");
|
|
954
|
+
} else {
|
|
955
|
+
setResultView("json");
|
|
956
|
+
}
|
|
957
|
+
} catch (err) {
|
|
958
|
+
const duration = performance.now() - startTime;
|
|
959
|
+
setResult({
|
|
960
|
+
value: void 0,
|
|
961
|
+
console: consoleEntries,
|
|
962
|
+
duration,
|
|
963
|
+
error: err?.message || String(err),
|
|
964
|
+
timestamp: Date.now()
|
|
965
|
+
});
|
|
966
|
+
setResultView("json");
|
|
967
|
+
} finally {
|
|
968
|
+
console.log = originalConsole.log;
|
|
969
|
+
console.warn = originalConsole.warn;
|
|
970
|
+
console.error = originalConsole.error;
|
|
971
|
+
console.info = originalConsole.info;
|
|
972
|
+
setIsRunning(false);
|
|
973
|
+
if (scopedClientToCleanUp) {
|
|
974
|
+
scopedClientToCleanUp.ws?.disconnect();
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}, [activeTab?.code, buildClient, selectedUser, currentUser, collectionInfos]);
|
|
978
|
+
const saveSnippet = useCallback(() => {
|
|
979
|
+
if (!snippetName.trim() || !activeTab?.code.trim()) return;
|
|
980
|
+
const snippet = {
|
|
981
|
+
id: String(Date.now()),
|
|
982
|
+
name: snippetName.trim(),
|
|
983
|
+
code: activeTab.code,
|
|
984
|
+
createdAt: Date.now()
|
|
985
|
+
};
|
|
986
|
+
setSnippets((prev_3) => [snippet, ...prev_3]);
|
|
987
|
+
setShowSaveDialog(false);
|
|
988
|
+
setSnippetName("");
|
|
989
|
+
snackbar.open({
|
|
990
|
+
type: "success",
|
|
991
|
+
message: "Snippet saved"
|
|
992
|
+
});
|
|
993
|
+
}, [snippetName, activeTab?.code, snackbar]);
|
|
994
|
+
const deleteSnippet = useCallback((id_0) => {
|
|
995
|
+
setSnippets((prev_4) => prev_4.filter((s) => s.id !== id_0));
|
|
996
|
+
}, []);
|
|
997
|
+
const exportResult = useCallback(() => {
|
|
998
|
+
if (!result?.value) return;
|
|
999
|
+
const blob = new Blob([formatJSON(result.value)], {
|
|
1000
|
+
type: "application/json"
|
|
1001
|
+
});
|
|
1002
|
+
const url = URL.createObjectURL(blob);
|
|
1003
|
+
const a = document.createElement("a");
|
|
1004
|
+
a.href = url;
|
|
1005
|
+
a.download = `rebase-result-${Date.now()}.json`;
|
|
1006
|
+
a.click();
|
|
1007
|
+
URL.revokeObjectURL(url);
|
|
1008
|
+
}, [result]);
|
|
1009
|
+
const tableData = useMemo(() => {
|
|
1010
|
+
if (!result?.value) return {
|
|
1011
|
+
columns: [],
|
|
1012
|
+
data: []
|
|
1013
|
+
};
|
|
1014
|
+
let rows = [];
|
|
1015
|
+
if (result.value?.data && Array.isArray(result.value.data)) {
|
|
1016
|
+
rows = result.value.data.map((entity) => ({
|
|
1017
|
+
id: entity.id,
|
|
1018
|
+
...entity.values,
|
|
1019
|
+
...entity.values ? {} : entity
|
|
1020
|
+
}));
|
|
1021
|
+
} else if (Array.isArray(result.value)) {
|
|
1022
|
+
rows = result.value;
|
|
1023
|
+
}
|
|
1024
|
+
if (rows.length === 0) return {
|
|
1025
|
+
columns: [],
|
|
1026
|
+
data: []
|
|
1027
|
+
};
|
|
1028
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1029
|
+
rows.slice(0, 20).forEach((row) => {
|
|
1030
|
+
if (row && typeof row === "object") {
|
|
1031
|
+
Object.keys(row).forEach((k) => keys.add(k));
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
const columns = Array.from(keys).map((key) => ({
|
|
1035
|
+
key,
|
|
1036
|
+
title: key,
|
|
1037
|
+
width: key === "id" ? 100 : 200
|
|
1038
|
+
}));
|
|
1039
|
+
return {
|
|
1040
|
+
columns,
|
|
1041
|
+
data: rows
|
|
1042
|
+
};
|
|
1043
|
+
}, [result]);
|
|
1044
|
+
const matchedCollections = useMemo(() => {
|
|
1045
|
+
if (!result?.value || result.error) return [];
|
|
1046
|
+
return detectCollectionsInResult(activeTab?.code ?? "", result.value, collectionRegistry?.collections ?? []);
|
|
1047
|
+
}, [result, activeTab?.code, collectionRegistry?.collections]);
|
|
1048
|
+
const getRowEntityActions = useCallback((rowData) => {
|
|
1049
|
+
if (!rowData || matchedCollections.length === 0) return [];
|
|
1050
|
+
return matchedCollections.filter((mc) => rowData[mc.pkColumn] != null).map((mc_0) => ({
|
|
1051
|
+
collection: mc_0,
|
|
1052
|
+
entityId: rowData[mc_0.pkColumn]
|
|
1053
|
+
}));
|
|
1054
|
+
}, [matchedCollections]);
|
|
1055
|
+
const handleExportCSV = useCallback(() => {
|
|
1056
|
+
if (tableData.data.length === 0) return;
|
|
1057
|
+
const headers = tableData.columns.map((c_0) => c_0.key).join(",");
|
|
1058
|
+
const rows_0 = tableData.data.map((row_0) => tableData.columns.map((c_1) => {
|
|
1059
|
+
const val = row_0[c_1.key];
|
|
1060
|
+
const str = val === null || val === void 0 ? "" : String(val);
|
|
1061
|
+
return str.includes(",") ? `"${str}"` : str;
|
|
1062
|
+
}).join(","));
|
|
1063
|
+
const csv = [headers, ...rows_0].join("\n");
|
|
1064
|
+
const blob_0 = new Blob([csv], {
|
|
1065
|
+
type: "text/csv"
|
|
1066
|
+
});
|
|
1067
|
+
const url_0 = URL.createObjectURL(blob_0);
|
|
1068
|
+
const a_0 = document.createElement("a");
|
|
1069
|
+
a_0.href = url_0;
|
|
1070
|
+
a_0.download = `js_results_${(/* @__PURE__ */ new Date()).toISOString().slice(0, 19)}.csv`;
|
|
1071
|
+
a_0.click();
|
|
1072
|
+
URL.revokeObjectURL(url_0);
|
|
1073
|
+
}, [tableData]);
|
|
1074
|
+
const handleExportMarkdown = useCallback(() => {
|
|
1075
|
+
if (tableData.data.length === 0) return;
|
|
1076
|
+
const headers_0 = tableData.columns.map((c_2) => c_2.key);
|
|
1077
|
+
const headerRow = `| ${headers_0.join(" | ")} |`;
|
|
1078
|
+
const dividerRow = `| ${headers_0.map(() => "---").join(" | ")} |`;
|
|
1079
|
+
const dataRows = tableData.data.map((row_1) => `| ${headers_0.map((h_0) => {
|
|
1080
|
+
const val_0 = row_1[h_0];
|
|
1081
|
+
if (val_0 === null || val_0 === void 0) return "";
|
|
1082
|
+
return String(val_0).replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
1083
|
+
}).join(" | ")} |`);
|
|
1084
|
+
const markdown = [headerRow, dividerRow, ...dataRows].join("\n");
|
|
1085
|
+
navigator.clipboard.writeText(markdown).then(() => {
|
|
1086
|
+
snackbar.open({
|
|
1087
|
+
type: "success",
|
|
1088
|
+
message: t("studio_sql_markdown_copied")
|
|
1089
|
+
});
|
|
1090
|
+
}).catch(() => {
|
|
1091
|
+
snackbar.open({
|
|
1092
|
+
type: "error",
|
|
1093
|
+
message: t("studio_sql_markdown_copy_failed")
|
|
1094
|
+
});
|
|
1095
|
+
});
|
|
1096
|
+
}, [tableData, snackbar, t]);
|
|
1097
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full w-full", children: [
|
|
1098
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow overflow-hidden", children: /* @__PURE__ */ jsx(ResizablePanels, { orientation: "horizontal", panelSizePercent: sidebarSize, onPanelSizeChange: setSidebarSize, minPanelSizePx: 200, firstPanel: /* @__PURE__ */ jsx(JSEditorSidebar, { collections: collectionInfos, snippets, history, onSelectSnippet: (code_1) => updateActiveCode(code_1), onDeleteSnippet: deleteSnippet, onInsertCode: (code_2) => updateActiveCode(code_2) }), secondPanel: /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
1099
|
+
/* @__PURE__ */ jsxs("div", { className: cls("flex items-center justify-between pr-2 border-b bg-white dark:bg-surface-950", defaultBorderMixin), children: [
|
|
1100
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center flex-grow overflow-hidden mr-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center no-scrollbar overflow-x-auto min-w-0", children: [
|
|
1101
|
+
/* @__PURE__ */ jsx(Tabs, { value: activeTabId, onValueChange: setActiveTabId, variant: "boxy", className: "w-[unset] flex-shrink-0", innerClassName: "bg-white dark:bg-surface-950", children: tabs.map((tab) => /* @__PURE__ */ jsxs(Tab, { value: tab.id, className: "flex items-center justify-between group max-w-[200px]", children: [
|
|
1102
|
+
/* @__PURE__ */ jsx(TerminalIcon, { size: iconSize.smallest, className: "text-amber-500 mr-1.5 flex-shrink-0" }),
|
|
1103
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: tab.name }),
|
|
1104
|
+
tabs.length > 1 && /* @__PURE__ */ jsx(IconButton, { size: "smallest", onClick: (e) => {
|
|
1105
|
+
e.stopPropagation();
|
|
1106
|
+
closeTab(tab.id);
|
|
1107
|
+
}, className: "ml-1 !p-0.5 opacity-0 group-hover:opacity-100 hover:text-red-500 transition-opacity", children: /* @__PURE__ */ jsx(XIcon, { size: iconSize.smallest }) })
|
|
1108
|
+
] }, tab.id)) }),
|
|
1109
|
+
/* @__PURE__ */ jsx(IconButton, { size: "small", onClick: addTab, className: "ml-2 flex-shrink-0", children: /* @__PURE__ */ jsx(PlusIcon, { size: iconSize.smallest }) })
|
|
1110
|
+
] }) }),
|
|
1111
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-end gap-1.5", children: [
|
|
1112
|
+
/* @__PURE__ */ jsx(Tooltip, { title: "SaveIcon as snippet", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => {
|
|
1113
|
+
setSnippetName("");
|
|
1114
|
+
setShowSaveDialog(true);
|
|
1115
|
+
}, disabled: !activeTab?.code.trim(), children: /* @__PURE__ */ jsx(SaveIcon, { size: iconSize.smallest }) }) }),
|
|
1116
|
+
result?.value && /* @__PURE__ */ jsx(Tooltip, { title: "Export result as JSON", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: exportResult, children: /* @__PURE__ */ jsx(DownloadIcon, { size: iconSize.smallest }) }) }),
|
|
1117
|
+
/* @__PURE__ */ jsxs(Button, { size: "small", color: "primary", disabled: isRunning || !activeTab?.code.trim(), onClick: () => executeCode(), children: [
|
|
1118
|
+
isRunning ? /* @__PURE__ */ jsx(CircularProgress, { size: "smallest", className: "mr-2" }) : /* @__PURE__ */ jsx(PlayIcon, { size: iconSize.smallest, className: "mr-2" }),
|
|
1119
|
+
"Run"
|
|
1120
|
+
] })
|
|
1121
|
+
] })
|
|
1122
|
+
] }),
|
|
1123
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow overflow-hidden", children: /* @__PURE__ */ jsx(ResizablePanels, { orientation: "vertical", panelSizePercent: editorHeight, onPanelSizeChange: setEditorHeight, minPanelSizePx: 100, firstPanel: /* @__PURE__ */ jsxs("div", { className: "h-full w-full overflow-hidden flex flex-col", children: [
|
|
1124
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 px-3 border-b border-surface-200 dark:border-surface-950 bg-surface-50 dark:bg-surface-900 flex items-center shrink-0", children: /* @__PURE__ */ jsx(AuthSimulationSelector, { authMode, setAuthMode, selectedUser, setSelectedUser, users, loading: userManagement?.loading, currentUser: currentSelectableUser }) }),
|
|
1125
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsx(JSMonacoEditor, { value: activeTab?.code ?? "", onChange: updateActiveCode, onRun: (selectedText) => executeCode(selectedText), collectionSlugs, collections: collectionInfos, autoFocus: true }) })
|
|
1126
|
+
] }), secondPanel: /* @__PURE__ */ jsxs("div", { className: "h-full w-full flex flex-col bg-surface-50 dark:bg-surface-950 overflow-hidden min-h-0", children: [
|
|
1127
|
+
/* @__PURE__ */ jsxs("div", { className: cls("p-2 px-4 bg-surface-100 dark:bg-surface-900 border-b shrink-0 flex items-center", defaultBorderMixin), children: [
|
|
1128
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "font-bold text-text-disabled dark:text-text-disabled-dark uppercase tracking-widest text-[10px]", children: t("studio_sql_query_results") }),
|
|
1129
|
+
result && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1130
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow" }),
|
|
1131
|
+
/* @__PURE__ */ jsxs(Tabs, { value: resultView, onValueChange: (val_1) => setResultView(val_1), variant: "pill", className: "w-[unset] mr-2", children: [
|
|
1132
|
+
/* @__PURE__ */ jsx(Tab, { value: "json", children: "JSON" }),
|
|
1133
|
+
tableData.data.length > 0 && /* @__PURE__ */ jsx(Tab, { value: "table", children: "Table" }),
|
|
1134
|
+
result.console.length > 0 && /* @__PURE__ */ jsxs(Tab, { value: "console", children: [
|
|
1135
|
+
"Console (",
|
|
1136
|
+
result.console.length,
|
|
1137
|
+
")"
|
|
1138
|
+
] })
|
|
1139
|
+
] }),
|
|
1140
|
+
/* @__PURE__ */ jsx(Chip, { size: "smallest", colorScheme: result.error ? "redDarker" : "greenDarker", children: result.error ? "Error" : `${result.duration.toFixed(0)}ms` })
|
|
1141
|
+
] })
|
|
1142
|
+
] }),
|
|
1143
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-grow flex flex-col min-h-0 overflow-hidden", children: [
|
|
1144
|
+
isRunning && /* @__PURE__ */ jsx("div", { className: "flex-grow flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1145
|
+
/* @__PURE__ */ jsx(CircularProgress, { size: "medium" }),
|
|
1146
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", className: "mt-4 text-text-secondary dark:text-text-secondary-dark font-mono tracking-tight animate-pulse", children: "EXECUTING SCRIPT..." })
|
|
1147
|
+
] }) }),
|
|
1148
|
+
!isRunning && !result && /* @__PURE__ */ jsx("div", { className: "flex-grow flex items-center justify-center text-text-disabled dark:text-text-disabled-dark", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1149
|
+
/* @__PURE__ */ jsx("svg", { className: "w-12 h-12 mx-auto mb-4 opacity-50", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1, d: "M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
1150
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
|
|
1151
|
+
"Write JavaScript and press ",
|
|
1152
|
+
/* @__PURE__ */ jsx("kbd", { className: "px-1.5 py-0.5 rounded bg-surface-200 dark:bg-surface-700 text-[11px] font-mono", children: "⌘ Enter" }),
|
|
1153
|
+
" to run"
|
|
1154
|
+
] })
|
|
1155
|
+
] }) }),
|
|
1156
|
+
!isRunning && result?.error && /* @__PURE__ */ jsx("div", { className: "flex-grow flex items-center justify-center p-6 overflow-auto", children: /* @__PURE__ */ jsx(ErrorView, { title: "Execution Error", error: result.error }) }),
|
|
1157
|
+
!isRunning && result && !result.error && resultView === "json" && /* @__PURE__ */ jsx("pre", { className: "flex-grow overflow-auto p-4 text-[13px] font-mono leading-relaxed text-text-primary dark:text-text-primary-dark whitespace-pre-wrap break-words", children: result.value === void 0 ? /* @__PURE__ */ jsx("span", { className: "text-text-disabled italic", children: "undefined (no return value)" }) : /* @__PURE__ */ jsx(JSONHighlight, { value: result.value }) }),
|
|
1158
|
+
!isRunning && result && !result.error && resultView === "table" && tableData.data.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex-grow flex flex-col overflow-hidden min-h-0", children: [
|
|
1159
|
+
matchedCollections.length > 0 && /* @__PURE__ */ jsxs("div", { className: cls("px-4 py-1.5 border-b flex items-center gap-2 shrink-0 bg-surface-50 dark:bg-surface-900", defaultBorderMixin), children: [
|
|
1160
|
+
/* @__PURE__ */ jsx(Tooltip, { title: t("studio_sql_cms_collections_tooltip"), children: /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-[10px] font-bold uppercase tracking-widest text-text-disabled dark:text-text-disabled-dark mr-1 shrink-0 cursor-help", children: t("studio_sql_cms") }) }),
|
|
1161
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 overflow-x-auto no-scrollbar", children: matchedCollections.map((mc_1) => /* @__PURE__ */ jsx(Tooltip, { title: `${mc_1.collection.name} (${mc_1.collectionSlug})`, children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium bg-primary/10 dark:bg-primary-dark/15 text-primary dark:text-primary-dark whitespace-nowrap border border-primary/20 dark:border-primary-dark/20", children: [
|
|
1162
|
+
typeof mc_1.collection.icon === "string" && /* @__PURE__ */ jsx(IconForView, { collectionOrView: {
|
|
1163
|
+
icon: mc_1.collection.icon
|
|
1164
|
+
}, className: "text-[12px]" }),
|
|
1165
|
+
mc_1.collection.name
|
|
1166
|
+
] }) }, mc_1.collectionSlug)) })
|
|
1167
|
+
] }),
|
|
1168
|
+
/* @__PURE__ */ jsx("div", { className: "flex-grow relative h-full min-h-0 min-w-0", children: /* @__PURE__ */ jsx(VirtualTable, { data: tableData.data, columns: matchedCollections.length > 0 ? [{
|
|
1169
|
+
key: "__entity_action__",
|
|
1170
|
+
title: "",
|
|
1171
|
+
width: 36,
|
|
1172
|
+
sortable: false,
|
|
1173
|
+
resizable: false
|
|
1174
|
+
}, ...tableData.columns] : tableData.columns, rowHeight: 32, headerHeight: 32, cellRenderer: ({
|
|
1175
|
+
rowData: rowData_0,
|
|
1176
|
+
column,
|
|
1177
|
+
rowIndex
|
|
1178
|
+
}) => {
|
|
1179
|
+
if (column.key === "__entity_action__") {
|
|
1180
|
+
const rowActions = getRowEntityActions(rowData_0);
|
|
1181
|
+
if (rowActions.length === 0) return /* @__PURE__ */ jsx("div", { className: "h-full w-full" });
|
|
1182
|
+
if (rowActions.length === 1) {
|
|
1183
|
+
const ra = rowActions[0];
|
|
1184
|
+
return /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Tooltip, { title: t("studio_sql_edit_entity", {
|
|
1185
|
+
name: ra.collection.collection.name,
|
|
1186
|
+
id: String(ra.entityId)
|
|
1187
|
+
}), children: /* @__PURE__ */ jsx(IconButton, { size: "small", className: "text-surface-400 dark:text-surface-500 hover:text-surface-600 dark:hover:text-surface-300", onClick: (e_0) => {
|
|
1188
|
+
e_0.stopPropagation();
|
|
1189
|
+
sideEntityController.open({
|
|
1190
|
+
path: ra.collection.collectionSlug,
|
|
1191
|
+
entityId: ra.entityId,
|
|
1192
|
+
collection: ra.collection.collection,
|
|
1193
|
+
updateUrl: false
|
|
1194
|
+
});
|
|
1195
|
+
}, children: /* @__PURE__ */ jsx(PencilIcon, { size: iconSize.smallest }) }) }) });
|
|
1196
|
+
}
|
|
1197
|
+
return /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(Menu, { trigger: /* @__PURE__ */ jsx(IconButton, { size: "small", className: "text-surface-400 dark:text-surface-500 hover:text-surface-600 dark:hover:text-surface-300", onClick: (e_1) => e_1.stopPropagation(), children: /* @__PURE__ */ jsx(MoreVerticalIcon, { size: iconSize.smallest }) }), children: rowActions.map((ra_0) => /* @__PURE__ */ jsx(MenuItem, { dense: true, onClick: () => {
|
|
1198
|
+
sideEntityController.open({
|
|
1199
|
+
path: ra_0.collection.collectionSlug,
|
|
1200
|
+
entityId: ra_0.entityId,
|
|
1201
|
+
collection: ra_0.collection.collection,
|
|
1202
|
+
updateUrl: false
|
|
1203
|
+
});
|
|
1204
|
+
}, children: t("studio_sql_edit_entity", {
|
|
1205
|
+
name: ra_0.collection.collection.name,
|
|
1206
|
+
id: String(ra_0.entityId)
|
|
1207
|
+
}) }, ra_0.collection.collectionSlug)) }) });
|
|
1208
|
+
}
|
|
1209
|
+
if (!rowData_0) return null;
|
|
1210
|
+
const val_2 = rowData_0[column.key];
|
|
1211
|
+
const displayValue = typeof val_2 === "object" && val_2 !== null ? JSON.stringify(val_2) : String(val_2 ?? "");
|
|
1212
|
+
return /* @__PURE__ */ jsx("div", { className: "px-4 py-1.5 h-full flex items-center whitespace-nowrap text-[13px] text-text-primary dark:text-text-primary-dark font-mono", children: /* @__PURE__ */ jsx("div", { className: "truncate flex-grow", title: displayValue, children: displayValue === "" ? /* @__PURE__ */ jsx("span", { className: "text-text-disabled dark:text-text-disabled-dark italic text-[11px]", children: "NULL" }) : displayValue }) });
|
|
1213
|
+
} }) })
|
|
1214
|
+
] }),
|
|
1215
|
+
!isRunning && result && resultView === "console" && /* @__PURE__ */ jsxs("div", { className: "flex-grow overflow-auto p-2 space-y-1 font-mono text-[12px]", children: [
|
|
1216
|
+
result.console.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled p-2", children: "No console output" }) : result.console.map((entry, i) => /* @__PURE__ */ jsxs("div", { className: cls("px-2 py-1 rounded flex items-start gap-2", entry.type === "error" && "bg-red-50 dark:bg-red-950/30 text-red-700 dark:text-red-400", entry.type === "warn" && "bg-amber-50 dark:bg-amber-950/30 text-amber-700 dark:text-amber-400", entry.type === "log" && "text-text-primary dark:text-text-primary-dark", entry.type === "info" && "text-blue-700 dark:text-blue-400"), children: [
|
|
1217
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] opacity-50 flex-shrink-0 mt-0.5", children: entry.type === "error" ? "❌" : entry.type === "warn" ? "⚠️" : entry.type === "info" ? "ℹ️" : "›" }),
|
|
1218
|
+
/* @__PURE__ */ jsx("span", { className: "whitespace-pre-wrap break-words", children: entry.args.map((a_1) => typeof a_1 === "object" ? JSON.stringify(a_1, null, 2) : String(a_1)).join(" ") })
|
|
1219
|
+
] }, i)),
|
|
1220
|
+
result.value !== void 0 && /* @__PURE__ */ jsxs("div", { className: cls("px-2 py-1 mt-2 border-t pt-2", defaultBorderMixin), children: [
|
|
1221
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-text-disabled text-[10px] uppercase tracking-wider mb-1 block", children: "Return Value" }),
|
|
1222
|
+
/* @__PURE__ */ jsx("pre", { className: "text-text-primary dark:text-text-primary-dark whitespace-pre-wrap break-words text-[12px]", children: formatJSON(result.value) })
|
|
1223
|
+
] })
|
|
1224
|
+
] })
|
|
1225
|
+
] }),
|
|
1226
|
+
!isRunning && result && !result.error && resultView === "table" && tableData.data.length > 0 && /* @__PURE__ */ jsxs("div", { className: cls("p-2 px-4 border-t bg-surface-50 dark:bg-surface-900 flex justify-between items-center shrink-0", defaultBorderMixin), children: [
|
|
1227
|
+
/* @__PURE__ */ jsxs("div", { className: "flex space-x-4", children: [
|
|
1228
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center text-[11px]", children: [
|
|
1229
|
+
/* @__PURE__ */ jsx("span", { className: "font-bold text-text-disabled dark:text-text-disabled-dark mr-2 uppercase tracking-tighter", children: t("studio_sql_rows") }),
|
|
1230
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-text-secondary dark:text-text-secondary-dark", children: tableData.data.length })
|
|
1231
|
+
] }),
|
|
1232
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center text-[11px]", children: [
|
|
1233
|
+
/* @__PURE__ */ jsx("span", { className: "font-bold text-text-disabled dark:text-text-disabled-dark mr-2 uppercase tracking-tighter", children: t("studio_sql_time") }),
|
|
1234
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono text-text-secondary dark:text-text-secondary-dark", children: [
|
|
1235
|
+
result.duration.toFixed(0),
|
|
1236
|
+
"ms"
|
|
1237
|
+
] })
|
|
1238
|
+
] })
|
|
1239
|
+
] }),
|
|
1240
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 overflow-x-auto no-scrollbar items-center px-2", children: [
|
|
1241
|
+
/* @__PURE__ */ jsx(Button, { size: "small", variant: "text", className: "text-[10px] uppercase font-bold text-text-secondary dark:text-text-secondary-dark whitespace-nowrap", onClick: handleExportMarkdown, children: t("studio_sql_copy_markdown") }),
|
|
1242
|
+
/* @__PURE__ */ jsx(Button, { size: "small", variant: "text", className: "text-[10px] uppercase font-bold text-text-secondary dark:text-text-secondary-dark whitespace-nowrap", onClick: exportResult, children: t("studio_sql_export_json") }),
|
|
1243
|
+
/* @__PURE__ */ jsx(Button, { size: "small", variant: "text", className: "text-[10px] uppercase font-bold text-text-secondary dark:text-text-secondary-dark whitespace-nowrap", onClick: handleExportCSV, children: t("studio_sql_export_csv") })
|
|
1244
|
+
] })
|
|
1245
|
+
] })
|
|
1246
|
+
] }) }) })
|
|
1247
|
+
] }) }) }),
|
|
1248
|
+
/* @__PURE__ */ jsxs(Dialog, { open: showSaveDialog, onOpenChange: setShowSaveDialog, children: [
|
|
1249
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "SaveIcon Snippet" }),
|
|
1250
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx(TextField, { label: "Snippet name", value: snippetName, onChange: (e_2) => setSnippetName(e_2.target.value), placeholder: "e.g. List all products", autoFocus: true, onKeyDown: (e_3) => {
|
|
1251
|
+
if (e_3.key === "Enter") saveSnippet();
|
|
1252
|
+
} }) }),
|
|
1253
|
+
/* @__PURE__ */ jsxs(DialogActions, { children: [
|
|
1254
|
+
/* @__PURE__ */ jsx(Button, { variant: "text", onClick: () => setShowSaveDialog(false), children: "Cancel" }),
|
|
1255
|
+
/* @__PURE__ */ jsx(Button, { variant: "filled", color: "primary", onClick: saveSnippet, disabled: !snippetName.trim(), children: "Save" })
|
|
1256
|
+
] })
|
|
1257
|
+
] })
|
|
1258
|
+
] });
|
|
1259
|
+
}
|
|
1260
|
+
function JSONHighlight(t0) {
|
|
1261
|
+
const $ = c(5);
|
|
1262
|
+
const {
|
|
1263
|
+
value
|
|
1264
|
+
} = t0;
|
|
1265
|
+
let t1;
|
|
1266
|
+
if ($[0] !== value) {
|
|
1267
|
+
t1 = formatJSON(value);
|
|
1268
|
+
$[0] = value;
|
|
1269
|
+
$[1] = t1;
|
|
1270
|
+
} else {
|
|
1271
|
+
t1 = $[1];
|
|
1272
|
+
}
|
|
1273
|
+
const json = t1;
|
|
1274
|
+
const {
|
|
1275
|
+
mode
|
|
1276
|
+
} = useModeController();
|
|
1277
|
+
const t2 = mode === "dark" ? themes.vsDark : themes.github;
|
|
1278
|
+
let t3;
|
|
1279
|
+
if ($[2] !== json || $[3] !== t2) {
|
|
1280
|
+
t3 = /* @__PURE__ */ jsx(Highlight, { theme: t2, code: json, language: "json", children: _temp });
|
|
1281
|
+
$[2] = json;
|
|
1282
|
+
$[3] = t2;
|
|
1283
|
+
$[4] = t3;
|
|
1284
|
+
} else {
|
|
1285
|
+
t3 = $[4];
|
|
1286
|
+
}
|
|
1287
|
+
return t3;
|
|
1288
|
+
}
|
|
1289
|
+
function _temp(t0) {
|
|
1290
|
+
const {
|
|
1291
|
+
style,
|
|
1292
|
+
tokens,
|
|
1293
|
+
getLineProps,
|
|
1294
|
+
getTokenProps
|
|
1295
|
+
} = t0;
|
|
1296
|
+
return /* @__PURE__ */ jsx("span", { style: {
|
|
1297
|
+
...style,
|
|
1298
|
+
backgroundColor: "transparent"
|
|
1299
|
+
}, children: tokens.map((line, i) => /* @__PURE__ */ jsx("div", { ...getLineProps({
|
|
1300
|
+
line
|
|
1301
|
+
}), children: line.map((token, key) => /* @__PURE__ */ jsx("span", { ...getTokenProps({
|
|
1302
|
+
token
|
|
1303
|
+
}) }, key)) }, i)) });
|
|
1304
|
+
}
|
|
1305
|
+
export {
|
|
1306
|
+
JSEditor
|
|
1307
|
+
};
|
|
1308
|
+
//# sourceMappingURL=JSEditor-D8nVp3Lp.js.map
|