@datarecce/ui 0.1.30 → 0.1.31
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/dist/api.d.mts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/components.d.mts +1 -1
- package/dist/components.d.ts +1 -1
- package/dist/hooks.d.mts +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/{index-BNUP2V_N.d.ts → index-B9lSPJTi.d.ts} +184 -2
- package/dist/index-B9lSPJTi.d.ts.map +1 -0
- package/dist/{index-DOPZuhD8.d.mts → index-IIXVIoOL.d.mts} +253 -71
- package/dist/index-IIXVIoOL.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +4 -0
- package/dist/theme.d.mts +2 -185
- package/dist/theme.d.ts +2 -185
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +4 -2
- package/recce-source/.editorconfig +26 -0
- package/recce-source/.flake8 +37 -0
- package/recce-source/.github/ISSUE_TEMPLATE/bug_report.yml +67 -0
- package/recce-source/.github/ISSUE_TEMPLATE/custom.md +10 -0
- package/recce-source/.github/ISSUE_TEMPLATE/feature_request.yml +42 -0
- package/recce-source/.github/PULL_REQUEST_TEMPLATE.md +21 -0
- package/recce-source/.github/copilot-instructions.md +331 -0
- package/recce-source/.github/instructions/backend-instructions.md +541 -0
- package/recce-source/.github/instructions/frontend-instructions.md +317 -0
- package/recce-source/.github/workflows/build-statics.yaml +72 -0
- package/recce-source/.github/workflows/bump.yaml +48 -0
- package/recce-source/.github/workflows/integration-tests-cloud.yaml +92 -0
- package/recce-source/.github/workflows/integration-tests-sqlmesh.yaml +33 -0
- package/recce-source/.github/workflows/integration-tests.yaml +52 -0
- package/recce-source/.github/workflows/nightly.yaml +246 -0
- package/recce-source/.github/workflows/release.yaml +196 -0
- package/recce-source/.github/workflows/tests-js.yaml +58 -0
- package/recce-source/.github/workflows/tests-python.yaml +128 -0
- package/recce-source/.pre-commit-config.yaml +26 -0
- package/recce-source/CLAUDE.md +483 -0
- package/recce-source/CODE_OF_CONDUCT.md +128 -0
- package/recce-source/CONTRIBUTING.md +107 -0
- package/recce-source/LICENSE +201 -0
- package/recce-source/Makefile +126 -0
- package/recce-source/README.md +182 -0
- package/recce-source/RECCE_CLOUD.md +81 -0
- package/recce-source/SECURITY.md +25 -0
- package/recce-source/docs/PACKAGING.md +340 -0
- package/recce-source/docs/README.md +1 -0
- package/recce-source/integration_tests/dbt/dbt_project.yml +26 -0
- package/recce-source/integration_tests/dbt/models/customers.sql +69 -0
- package/recce-source/integration_tests/dbt/models/docs.md +14 -0
- package/recce-source/integration_tests/dbt/models/orders.sql +56 -0
- package/recce-source/integration_tests/dbt/models/schema.yml +82 -0
- package/recce-source/integration_tests/dbt/models/staging/schema.yml +31 -0
- package/recce-source/integration_tests/dbt/models/staging/stg_customers.sql +22 -0
- package/recce-source/integration_tests/dbt/models/staging/stg_orders.sql +23 -0
- package/recce-source/integration_tests/dbt/models/staging/stg_payments.sql +25 -0
- package/recce-source/integration_tests/dbt/packages.yml +7 -0
- package/recce-source/integration_tests/dbt/profiles.yml +8 -0
- package/recce-source/integration_tests/dbt/seeds/raw_customers.csv +101 -0
- package/recce-source/integration_tests/dbt/seeds/raw_orders.csv +100 -0
- package/recce-source/integration_tests/dbt/seeds/raw_payments.csv +114 -0
- package/recce-source/integration_tests/dbt/seeds/raw_statuses.csv +5 -0
- package/recce-source/integration_tests/dbt/smoke_test.sh +72 -0
- package/recce-source/integration_tests/dbt/smoke_test_cloud.sh +71 -0
- package/recce-source/integration_tests/sqlmesh/__init__.py +0 -0
- package/recce-source/integration_tests/sqlmesh/audits/assert_item_price_above_zero.sql +9 -0
- package/recce-source/integration_tests/sqlmesh/audits/items.sql +7 -0
- package/recce-source/integration_tests/sqlmesh/audits/order_items.sql +7 -0
- package/recce-source/integration_tests/sqlmesh/config.py +171 -0
- package/recce-source/integration_tests/sqlmesh/helper.py +20 -0
- package/recce-source/integration_tests/sqlmesh/hooks/__init__.py +0 -0
- package/recce-source/integration_tests/sqlmesh/macros/__init__.py +0 -0
- package/recce-source/integration_tests/sqlmesh/macros/macros.py +8 -0
- package/recce-source/integration_tests/sqlmesh/macros/macros.sql +8 -0
- package/recce-source/integration_tests/sqlmesh/macros/utils.py +11 -0
- package/recce-source/integration_tests/sqlmesh/metrics/metrics.sql +25 -0
- package/recce-source/integration_tests/sqlmesh/models/customer_revenue_by_day.sql +41 -0
- package/recce-source/integration_tests/sqlmesh/models/customer_revenue_lifetime.sql +60 -0
- package/recce-source/integration_tests/sqlmesh/models/customers.sql +32 -0
- package/recce-source/integration_tests/sqlmesh/models/items.py +95 -0
- package/recce-source/integration_tests/sqlmesh/models/marketing.sql +15 -0
- package/recce-source/integration_tests/sqlmesh/models/order_items.py +95 -0
- package/recce-source/integration_tests/sqlmesh/models/orders.py +70 -0
- package/recce-source/integration_tests/sqlmesh/models/raw_marketing.py +62 -0
- package/recce-source/integration_tests/sqlmesh/models/top_waiters.sql +23 -0
- package/recce-source/integration_tests/sqlmesh/models/waiter_as_customer_by_day.sql +29 -0
- package/recce-source/integration_tests/sqlmesh/models/waiter_names.sql +10 -0
- package/recce-source/integration_tests/sqlmesh/models/waiter_revenue_by_day.sql +29 -0
- package/recce-source/integration_tests/sqlmesh/models/waiters.py +62 -0
- package/recce-source/integration_tests/sqlmesh/prep_env.sh +16 -0
- package/recce-source/integration_tests/sqlmesh/schema.yaml +5 -0
- package/recce-source/integration_tests/sqlmesh/seeds/waiter_names.csv +11 -0
- package/recce-source/integration_tests/sqlmesh/test_server.sh +29 -0
- package/recce-source/integration_tests/sqlmesh/tests/test_customer_revenue_by_day.yaml +63 -0
- package/recce-source/integration_tests/sqlmesh/tests/test_order_items.yaml +72 -0
- package/recce-source/js/.editorconfig +27 -0
- package/recce-source/js/.env.development +5 -0
- package/recce-source/js/.husky/pre-commit +29 -0
- package/recce-source/js/.nvmrc +1 -0
- package/recce-source/js/README.md +39 -0
- package/recce-source/js/app/(mainComponents)/DisplayModeToggle.tsx +65 -0
- package/recce-source/js/app/(mainComponents)/NavBar.tsx +228 -0
- package/recce-source/js/app/(mainComponents)/RecceVersionBadge.tsx +107 -0
- package/recce-source/js/app/(mainComponents)/TopBar.tsx +252 -0
- package/recce-source/js/app/@lineage/default.tsx +20 -0
- package/recce-source/js/app/@lineage/page.tsx +14 -0
- package/recce-source/js/app/MainLayout.tsx +170 -0
- package/recce-source/js/app/Providers.tsx +49 -0
- package/recce-source/js/app/checks/page.tsx +296 -0
- package/recce-source/js/app/error.tsx +93 -0
- package/recce-source/js/app/favicon.ico +0 -0
- package/recce-source/js/app/global-error.tsx +115 -0
- package/recce-source/js/app/global.css +82 -0
- package/recce-source/js/app/layout.tsx +48 -0
- package/recce-source/js/app/lineage/page.tsx +15 -0
- package/recce-source/js/app/page.tsx +12 -0
- package/recce-source/js/app/query/page.tsx +8 -0
- package/recce-source/js/biome.json +313 -0
- package/recce-source/js/jest.config.js +34 -0
- package/recce-source/js/jest.globals.d.ts +32 -0
- package/recce-source/js/jest.setup.js +91 -0
- package/recce-source/js/next.config.js +16 -0
- package/recce-source/js/package-lock.json +13843 -0
- package/recce-source/js/package.json +123 -0
- package/recce-source/js/pnpm-lock.yaml +9235 -0
- package/recce-source/js/pnpm-workspace.yaml +6 -0
- package/recce-source/js/postcss.config.js +5 -0
- package/recce-source/js/public/auth_callback.html +68 -0
- package/recce-source/js/public/imgs/feedback/thumbs-down.png +0 -0
- package/recce-source/js/public/imgs/feedback/thumbs-up.png +0 -0
- package/recce-source/js/public/imgs/reload-image.svg +4 -0
- package/recce-source/js/public/logo/recce-logo-white.png +0 -0
- package/recce-source/js/src/components/AuthModal/AuthModal.tsx +202 -0
- package/recce-source/js/src/components/app/AvatarDropdown.tsx +159 -0
- package/recce-source/js/src/components/app/EnvInfo.tsx +357 -0
- package/recce-source/js/src/components/app/Filename.tsx +388 -0
- package/recce-source/js/src/components/app/SetupConnectionPopover.tsx +91 -0
- package/recce-source/js/src/components/app/StateExporter.tsx +57 -0
- package/recce-source/js/src/components/app/StateImporter.tsx +198 -0
- package/recce-source/js/src/components/app/StateSharing.tsx +145 -0
- package/recce-source/js/src/components/app/StateSynchronizer.tsx +205 -0
- package/recce-source/js/src/components/charts/HistogramChart.tsx +291 -0
- package/recce-source/js/src/components/charts/SquareIcon.tsx +51 -0
- package/recce-source/js/src/components/charts/TopKSummaryList.tsx +457 -0
- package/recce-source/js/src/components/charts/chartTheme.ts +74 -0
- package/recce-source/js/src/components/check/CheckBreadcrumb.tsx +97 -0
- package/recce-source/js/src/components/check/CheckDescription.tsx +134 -0
- package/recce-source/js/src/components/check/CheckDetail.tsx +797 -0
- package/recce-source/js/src/components/check/CheckEmptyState.tsx +84 -0
- package/recce-source/js/src/components/check/CheckList.tsx +320 -0
- package/recce-source/js/src/components/check/LineageDiffView.tsx +32 -0
- package/recce-source/js/src/components/check/PresetCheckTemplateView.tsx +48 -0
- package/recce-source/js/src/components/check/SchemaDiffView.tsx +290 -0
- package/recce-source/js/src/components/check/check.ts +25 -0
- package/recce-source/js/src/components/check/timeline/CheckTimeline.tsx +163 -0
- package/recce-source/js/src/components/check/timeline/CommentInput.tsx +84 -0
- package/recce-source/js/src/components/check/timeline/TimelineEvent.tsx +468 -0
- package/recce-source/js/src/components/check/timeline/index.ts +12 -0
- package/recce-source/js/src/components/check/utils.ts +12 -0
- package/recce-source/js/src/components/data-grid/ScreenshotDataGrid.tsx +333 -0
- package/recce-source/js/src/components/data-grid/agGridStyles.css +55 -0
- package/recce-source/js/src/components/data-grid/agGridTheme.ts +43 -0
- package/recce-source/js/src/components/editor/CodeEditor.tsx +107 -0
- package/recce-source/js/src/components/editor/DiffEditor.tsx +162 -0
- package/recce-source/js/src/components/editor/index.ts +12 -0
- package/recce-source/js/src/components/errorboundary/ErrorBoundary.tsx +87 -0
- package/recce-source/js/src/components/histogram/HistogramDiffForm.tsx +147 -0
- package/recce-source/js/src/components/histogram/HistogramDiffResultView.tsx +63 -0
- package/recce-source/js/src/components/icons/index.tsx +142 -0
- package/recce-source/js/src/components/lineage/ActionControl.tsx +63 -0
- package/recce-source/js/src/components/lineage/ActionTag.tsx +141 -0
- package/recce-source/js/src/components/lineage/ChangeStatusLegend.tsx +46 -0
- package/recce-source/js/src/components/lineage/ColumnLevelLineageControl.tsx +327 -0
- package/recce-source/js/src/components/lineage/ColumnLevelLineageLegend.tsx +57 -0
- package/recce-source/js/src/components/lineage/GraphColumnNode.tsx +199 -0
- package/recce-source/js/src/components/lineage/GraphEdge.tsx +59 -0
- package/recce-source/js/src/components/lineage/GraphNode.tsx +555 -0
- package/recce-source/js/src/components/lineage/LineagePage.tsx +10 -0
- package/recce-source/js/src/components/lineage/LineageView.tsx +1384 -0
- package/recce-source/js/src/components/lineage/LineageViewContext.tsx +86 -0
- package/recce-source/js/src/components/lineage/LineageViewContextMenu.tsx +637 -0
- package/recce-source/js/src/components/lineage/LineageViewNotification.tsx +64 -0
- package/recce-source/js/src/components/lineage/LineageViewTopBar.tsx +596 -0
- package/recce-source/js/src/components/lineage/NodeSqlView.tsx +136 -0
- package/recce-source/js/src/components/lineage/NodeTag.tsx +278 -0
- package/recce-source/js/src/components/lineage/NodeView.tsx +642 -0
- package/recce-source/js/src/components/lineage/SandboxView.tsx +436 -0
- package/recce-source/js/src/components/lineage/ServerDisconnectedModalContent.tsx +105 -0
- package/recce-source/js/src/components/lineage/SetupConnectionBanner.tsx +52 -0
- package/recce-source/js/src/components/lineage/SingleEnvironmentQueryView.tsx +152 -0
- package/recce-source/js/src/components/lineage/graph.test.ts +31 -0
- package/recce-source/js/src/components/lineage/graph.ts +58 -0
- package/recce-source/js/src/components/lineage/lineage.test.ts +169 -0
- package/recce-source/js/src/components/lineage/lineage.ts +521 -0
- package/recce-source/js/src/components/lineage/styles.css +42 -0
- package/recce-source/js/src/components/lineage/styles.tsx +165 -0
- package/recce-source/js/src/components/lineage/useMultiNodesAction.ts +352 -0
- package/recce-source/js/src/components/lineage/useValueDiffAlertDialog.tsx +108 -0
- package/recce-source/js/src/components/onboarding-guide/Notification.tsx +62 -0
- package/recce-source/js/src/components/profile/ProfileDiffForm.tsx +134 -0
- package/recce-source/js/src/components/profile/ProfileDiffResultView.tsx +245 -0
- package/recce-source/js/src/components/query/ChangedOnlyCheckbox.tsx +29 -0
- package/recce-source/js/src/components/query/DiffText.tsx +120 -0
- package/recce-source/js/src/components/query/QueryDiffResultView.tsx +470 -0
- package/recce-source/js/src/components/query/QueryForm.tsx +80 -0
- package/recce-source/js/src/components/query/QueryPage.tsx +282 -0
- package/recce-source/js/src/components/query/QueryResultView.tsx +180 -0
- package/recce-source/js/src/components/query/SetupConnectionGuide.tsx +57 -0
- package/recce-source/js/src/components/query/SqlEditor.tsx +245 -0
- package/recce-source/js/src/components/query/ToggleSwitch.tsx +84 -0
- package/recce-source/js/src/components/query/styles.css +21 -0
- package/recce-source/js/src/components/routing/DirectUrlAccess.test.tsx +428 -0
- package/recce-source/js/src/components/routing/LineageStatePreservation.test.tsx +311 -0
- package/recce-source/js/src/components/routing/Navigation.test.tsx +256 -0
- package/recce-source/js/src/components/rowcount/RowCountDiffResultView.tsx +109 -0
- package/recce-source/js/src/components/rowcount/delta.ts +11 -0
- package/recce-source/js/src/components/run/RunList.tsx +303 -0
- package/recce-source/js/src/components/run/RunModal.tsx +191 -0
- package/recce-source/js/src/components/run/RunPage.tsx +26 -0
- package/recce-source/js/src/components/run/RunResultPane.tsx +454 -0
- package/recce-source/js/src/components/run/RunStatusAndDate.tsx +106 -0
- package/recce-source/js/src/components/run/RunToolbar.tsx +70 -0
- package/recce-source/js/src/components/run/RunView.tsx +196 -0
- package/recce-source/js/src/components/run/registry.ts +214 -0
- package/recce-source/js/src/components/run/types.ts +14 -0
- package/recce-source/js/src/components/schema/ColumnNameCell.test.tsx +169 -0
- package/recce-source/js/src/components/schema/ColumnNameCell.tsx +198 -0
- package/recce-source/js/src/components/schema/SchemaView.tsx +337 -0
- package/recce-source/js/src/components/schema/schemaDiff.ts +32 -0
- package/recce-source/js/src/components/schema/style.css +134 -0
- package/recce-source/js/src/components/screenshot/ScreenshotBox.tsx +39 -0
- package/recce-source/js/src/components/shared/HistoryToggle.tsx +35 -0
- package/recce-source/js/src/components/split/Split.tsx +40 -0
- package/recce-source/js/src/components/split/styles.css +24 -0
- package/recce-source/js/src/components/summary/ChangeSummary.tsx +264 -0
- package/recce-source/js/src/components/summary/SchemaSummary.tsx +123 -0
- package/recce-source/js/src/components/summary/SummaryView.tsx +29 -0
- package/recce-source/js/src/components/timeout/IdleTimeoutBadge.tsx +48 -0
- package/recce-source/js/src/components/top-k/TopKDiffForm.tsx +58 -0
- package/recce-source/js/src/components/top-k/TopKDiffResultView.tsx +73 -0
- package/recce-source/js/src/components/ui/dataGrid/DataFrameColumnGroupHeader.tsx +228 -0
- package/recce-source/js/src/components/ui/dataGrid/DataFrameColumnHeader.tsx +113 -0
- package/recce-source/js/src/components/ui/dataGrid/defaultRenderCell.tsx +72 -0
- package/recce-source/js/src/components/ui/dataGrid/index.ts +23 -0
- package/recce-source/js/src/components/ui/dataGrid/inlineRenderCell.test.tsx +607 -0
- package/recce-source/js/src/components/ui/dataGrid/inlineRenderCell.tsx +211 -0
- package/recce-source/js/src/components/ui/dataGrid/schemaCells.test.tsx +452 -0
- package/recce-source/js/src/components/ui/dataGrid/schemaCells.tsx +142 -0
- package/recce-source/js/src/components/ui/dataGrid/valueDiffCells.test.tsx +178 -0
- package/recce-source/js/src/components/ui/dataGrid/valueDiffCells.tsx +275 -0
- package/recce-source/js/src/components/ui/markdown/ExternalLinkConfirmDialog.tsx +134 -0
- package/recce-source/js/src/components/ui/markdown/MarkdownContent.tsx +364 -0
- package/recce-source/js/src/components/ui/mui/index.ts +13 -0
- package/recce-source/js/src/components/ui/mui-provider.tsx +67 -0
- package/recce-source/js/src/components/ui/mui-theme.ts +1039 -0
- package/recce-source/js/src/components/ui/mui-utils.ts +113 -0
- package/recce-source/js/src/components/ui/toaster.tsx +288 -0
- package/recce-source/js/src/components/valuediff/ValueDiffDetailResultView.tsx +217 -0
- package/recce-source/js/src/components/valuediff/ValueDiffForm.tsx +246 -0
- package/recce-source/js/src/components/valuediff/ValueDiffResultView.tsx +82 -0
- package/recce-source/js/src/components/valuediff/shared.ts +33 -0
- package/recce-source/js/src/constants/tooltipMessage.ts +3 -0
- package/recce-source/js/src/constants/urls.ts +1 -0
- package/recce-source/js/src/lib/UrlHash.ts +12 -0
- package/recce-source/js/src/lib/api/adhocQuery.ts +70 -0
- package/recce-source/js/src/lib/api/axiosClient.ts +9 -0
- package/recce-source/js/src/lib/api/cacheKeys.ts +13 -0
- package/recce-source/js/src/lib/api/checkEvents.ts +252 -0
- package/recce-source/js/src/lib/api/checks.ts +129 -0
- package/recce-source/js/src/lib/api/cll.ts +53 -0
- package/recce-source/js/src/lib/api/connectToCloud.ts +13 -0
- package/recce-source/js/src/lib/api/flag.ts +37 -0
- package/recce-source/js/src/lib/api/info.ts +198 -0
- package/recce-source/js/src/lib/api/instanceInfo.ts +25 -0
- package/recce-source/js/src/lib/api/keepAlive.ts +108 -0
- package/recce-source/js/src/lib/api/lineagecheck.ts +35 -0
- package/recce-source/js/src/lib/api/localStorageKeys.ts +7 -0
- package/recce-source/js/src/lib/api/models.ts +59 -0
- package/recce-source/js/src/lib/api/profile.ts +65 -0
- package/recce-source/js/src/lib/api/rowcount.ts +19 -0
- package/recce-source/js/src/lib/api/runs.ts +174 -0
- package/recce-source/js/src/lib/api/schemacheck.ts +31 -0
- package/recce-source/js/src/lib/api/select.ts +25 -0
- package/recce-source/js/src/lib/api/sessionStorageKeys.ts +8 -0
- package/recce-source/js/src/lib/api/state.ts +117 -0
- package/recce-source/js/src/lib/api/track.ts +281 -0
- package/recce-source/js/src/lib/api/types.ts +284 -0
- package/recce-source/js/src/lib/api/user.ts +42 -0
- package/recce-source/js/src/lib/api/valuediff.ts +46 -0
- package/recce-source/js/src/lib/api/version.ts +40 -0
- package/recce-source/js/src/lib/const.ts +9 -0
- package/recce-source/js/src/lib/dataGrid/crossFunctionConsistency.test.ts +626 -0
- package/recce-source/js/src/lib/dataGrid/dataGridFactory.test.ts +2140 -0
- package/recce-source/js/src/lib/dataGrid/dataGridFactory.ts +397 -0
- package/recce-source/js/src/lib/dataGrid/generators/rowCountUtils.test.ts +132 -0
- package/recce-source/js/src/lib/dataGrid/generators/rowCountUtils.ts +126 -0
- package/recce-source/js/src/lib/dataGrid/generators/toDataDiffGrid.test.ts +1627 -0
- package/recce-source/js/src/lib/dataGrid/generators/toDataDiffGrid.ts +140 -0
- package/recce-source/js/src/lib/dataGrid/generators/toDataGrid.ts +67 -0
- package/recce-source/js/src/lib/dataGrid/generators/toRowCountDataGrid.test.ts +142 -0
- package/recce-source/js/src/lib/dataGrid/generators/toRowCountDataGrid.ts +71 -0
- package/recce-source/js/src/lib/dataGrid/generators/toRowCountDiffDataGrid.test.ts +258 -0
- package/recce-source/js/src/lib/dataGrid/generators/toRowCountDiffDataGrid.ts +153 -0
- package/recce-source/js/src/lib/dataGrid/generators/toSchemaDataGrid.test.ts +951 -0
- package/recce-source/js/src/lib/dataGrid/generators/toSchemaDataGrid.ts +221 -0
- package/recce-source/js/src/lib/dataGrid/generators/toValueDataGrid.test.ts +395 -0
- package/recce-source/js/src/lib/dataGrid/generators/toValueDataGrid.ts +184 -0
- package/recce-source/js/src/lib/dataGrid/generators/toValueDiffGrid.test.ts +884 -0
- package/recce-source/js/src/lib/dataGrid/generators/toValueDiffGrid.ts +113 -0
- package/recce-source/js/src/lib/dataGrid/index.ts +51 -0
- package/recce-source/js/src/lib/dataGrid/propertyBased.test.ts +858 -0
- package/recce-source/js/src/lib/dataGrid/shared/columnBuilders.test.ts +482 -0
- package/recce-source/js/src/lib/dataGrid/shared/columnBuilders.ts +345 -0
- package/recce-source/js/src/lib/dataGrid/shared/dataTypeEdgeCases.test.ts +698 -0
- package/recce-source/js/src/lib/dataGrid/shared/diffColumnBuilder.test.tsx +820 -0
- package/recce-source/js/src/lib/dataGrid/shared/diffColumnBuilder.tsx +277 -0
- package/recce-source/js/src/lib/dataGrid/shared/gridUtils.test.ts +785 -0
- package/recce-source/js/src/lib/dataGrid/shared/gridUtils.ts +370 -0
- package/recce-source/js/src/lib/dataGrid/shared/index.ts +81 -0
- package/recce-source/js/src/lib/dataGrid/shared/rowBuilders.test.ts +909 -0
- package/recce-source/js/src/lib/dataGrid/shared/rowBuilders.ts +325 -0
- package/recce-source/js/src/lib/dataGrid/shared/simpleColumnBuilder.tsx +240 -0
- package/recce-source/js/src/lib/dataGrid/shared/toDiffColumn.test.tsx +719 -0
- package/recce-source/js/src/lib/dataGrid/shared/toDiffColumn.tsx +231 -0
- package/recce-source/js/src/lib/dataGrid/shared/validation.test.ts +559 -0
- package/recce-source/js/src/lib/dataGrid/shared/validation.ts +367 -0
- package/recce-source/js/src/lib/dataGrid/warehouseNamingConventions.test.ts +1117 -0
- package/recce-source/js/src/lib/formatSelect.ts +50 -0
- package/recce-source/js/src/lib/hooks/ApiConfigContext.tsx +181 -0
- package/recce-source/js/src/lib/hooks/IdleTimeoutContext.tsx +177 -0
- package/recce-source/js/src/lib/hooks/LineageGraphContext.tsx +512 -0
- package/recce-source/js/src/lib/hooks/RecceActionContext.tsx +269 -0
- package/recce-source/js/src/lib/hooks/RecceCheckContext.tsx +33 -0
- package/recce-source/js/src/lib/hooks/RecceContextProvider.tsx +54 -0
- package/recce-source/js/src/lib/hooks/RecceInstanceContext.tsx +129 -0
- package/recce-source/js/src/lib/hooks/RecceQueryContext.tsx +98 -0
- package/recce-source/js/src/lib/hooks/RecceShareStateContext.tsx +59 -0
- package/recce-source/js/src/lib/hooks/ScreenShot.tsx +399 -0
- package/recce-source/js/src/lib/hooks/useAppRouter.test.ts +211 -0
- package/recce-source/js/src/lib/hooks/useAppRouter.ts +200 -0
- package/recce-source/js/src/lib/hooks/useCheckEvents.ts +99 -0
- package/recce-source/js/src/lib/hooks/useCheckToast.tsx +14 -0
- package/recce-source/js/src/lib/hooks/useClipBoardToast.tsx +27 -0
- package/recce-source/js/src/lib/hooks/useCountdownToast.tsx +102 -0
- package/recce-source/js/src/lib/hooks/useFeedbackCollectionToast.tsx +130 -0
- package/recce-source/js/src/lib/hooks/useGuideToast.tsx +45 -0
- package/recce-source/js/src/lib/hooks/useIdleDetection.tsx +185 -0
- package/recce-source/js/src/lib/hooks/useModelColumns.tsx +113 -0
- package/recce-source/js/src/lib/hooks/useRecceInstanceInfo.tsx +13 -0
- package/recce-source/js/src/lib/hooks/useRecceServerFlag.tsx +13 -0
- package/recce-source/js/src/lib/hooks/useRun.tsx +89 -0
- package/recce-source/js/src/lib/hooks/useThemeColors.ts +115 -0
- package/recce-source/js/src/lib/mergeKeys.test.ts +89 -0
- package/recce-source/js/src/lib/mergeKeys.ts +86 -0
- package/recce-source/js/src/lib/result/ResultErrorFallback.tsx +9 -0
- package/recce-source/js/src/lib/utils/formatTime.ts +84 -0
- package/recce-source/js/src/lib/utils/urls.ts +16 -0
- package/recce-source/js/src/utils/DropdownValuesInput.tsx +297 -0
- package/recce-source/js/src/utils/formatters.tsx +237 -0
- package/recce-source/js/src/utils/transforms.ts +81 -0
- package/recce-source/js/tsconfig.json +47 -0
- package/recce-source/macros/README.md +8 -0
- package/recce-source/macros/recce_athena.sql +73 -0
- package/recce-source/pyproject.toml +109 -0
- package/recce-source/recce/VERSION +1 -0
- package/recce-source/recce/__init__.py +84 -0
- package/recce-source/recce/adapter/__init__.py +0 -0
- package/recce-source/recce/adapter/base.py +109 -0
- package/recce-source/recce/adapter/dbt_adapter/__init__.py +1699 -0
- package/recce-source/recce/adapter/dbt_adapter/dbt_version.py +42 -0
- package/recce-source/recce/adapter/sqlmesh_adapter.py +141 -0
- package/recce-source/recce/apis/__init__.py +0 -0
- package/recce-source/recce/apis/check_api.py +203 -0
- package/recce-source/recce/apis/check_events_api.py +353 -0
- package/recce-source/recce/apis/check_func.py +130 -0
- package/recce-source/recce/apis/run_api.py +130 -0
- package/recce-source/recce/apis/run_func.py +258 -0
- package/recce-source/recce/artifact.py +266 -0
- package/recce-source/recce/cli.py +1846 -0
- package/recce-source/recce/config.py +127 -0
- package/recce-source/recce/connect_to_cloud.py +138 -0
- package/recce-source/recce/core.py +334 -0
- package/recce-source/recce/diff.py +26 -0
- package/recce-source/recce/event/CONFIG +1 -0
- package/recce-source/recce/event/SENTRY_DNS +1 -0
- package/recce-source/recce/event/__init__.py +304 -0
- package/recce-source/recce/event/collector.py +184 -0
- package/recce-source/recce/event/track.py +158 -0
- package/recce-source/recce/exceptions.py +21 -0
- package/recce-source/recce/git.py +77 -0
- package/recce-source/recce/github.py +222 -0
- package/recce-source/recce/mcp_server.py +861 -0
- package/recce-source/recce/models/__init__.py +6 -0
- package/recce-source/recce/models/check.py +473 -0
- package/recce-source/recce/models/run.py +46 -0
- package/recce-source/recce/models/types.py +218 -0
- package/recce-source/recce/pull_request.py +124 -0
- package/recce-source/recce/run.py +390 -0
- package/recce-source/recce/server.py +877 -0
- package/recce-source/recce/state/__init__.py +31 -0
- package/recce-source/recce/state/cloud.py +644 -0
- package/recce-source/recce/state/const.py +26 -0
- package/recce-source/recce/state/local.py +56 -0
- package/recce-source/recce/state/state.py +119 -0
- package/recce-source/recce/state/state_loader.py +174 -0
- package/recce-source/recce/summary.py +575 -0
- package/recce-source/recce/tasks/__init__.py +23 -0
- package/recce-source/recce/tasks/core.py +134 -0
- package/recce-source/recce/tasks/dataframe.py +170 -0
- package/recce-source/recce/tasks/histogram.py +433 -0
- package/recce-source/recce/tasks/lineage.py +19 -0
- package/recce-source/recce/tasks/profile.py +298 -0
- package/recce-source/recce/tasks/query.py +450 -0
- package/recce-source/recce/tasks/rowcount.py +277 -0
- package/recce-source/recce/tasks/schema.py +65 -0
- package/recce-source/recce/tasks/top_k.py +172 -0
- package/recce-source/recce/tasks/utils.py +147 -0
- package/recce-source/recce/tasks/valuediff.py +497 -0
- package/recce-source/recce/util/__init__.py +4 -0
- package/recce-source/recce/util/api_token.py +80 -0
- package/recce-source/recce/util/breaking.py +330 -0
- package/recce-source/recce/util/cache.py +25 -0
- package/recce-source/recce/util/cll.py +355 -0
- package/recce-source/recce/util/cloud/__init__.py +15 -0
- package/recce-source/recce/util/cloud/base.py +115 -0
- package/recce-source/recce/util/cloud/check_events.py +190 -0
- package/recce-source/recce/util/cloud/checks.py +242 -0
- package/recce-source/recce/util/io.py +120 -0
- package/recce-source/recce/util/lineage.py +83 -0
- package/recce-source/recce/util/logger.py +25 -0
- package/recce-source/recce/util/onboarding_state.py +45 -0
- package/recce-source/recce/util/perf_tracking.py +85 -0
- package/recce-source/recce/util/pydantic_model.py +22 -0
- package/recce-source/recce/util/recce_cloud.py +454 -0
- package/recce-source/recce/util/singleton.py +18 -0
- package/recce-source/recce/util/startup_perf.py +121 -0
- package/recce-source/recce/yaml/__init__.py +58 -0
- package/recce-source/recce_cloud/README.md +780 -0
- package/recce-source/recce_cloud/VERSION +1 -0
- package/recce-source/recce_cloud/__init__.py +24 -0
- package/recce-source/recce_cloud/api/__init__.py +17 -0
- package/recce-source/recce_cloud/api/base.py +132 -0
- package/recce-source/recce_cloud/api/client.py +186 -0
- package/recce-source/recce_cloud/api/exceptions.py +26 -0
- package/recce-source/recce_cloud/api/factory.py +63 -0
- package/recce-source/recce_cloud/api/github.py +106 -0
- package/recce-source/recce_cloud/api/gitlab.py +111 -0
- package/recce-source/recce_cloud/artifact.py +57 -0
- package/recce-source/recce_cloud/ci_providers/__init__.py +9 -0
- package/recce-source/recce_cloud/ci_providers/base.py +82 -0
- package/recce-source/recce_cloud/ci_providers/detector.py +147 -0
- package/recce-source/recce_cloud/ci_providers/github_actions.py +136 -0
- package/recce-source/recce_cloud/ci_providers/gitlab_ci.py +130 -0
- package/recce-source/recce_cloud/cli.py +434 -0
- package/recce-source/recce_cloud/download.py +230 -0
- package/recce-source/recce_cloud/hatch_build.py +20 -0
- package/recce-source/recce_cloud/pyproject.toml +49 -0
- package/recce-source/recce_cloud/upload.py +214 -0
- package/recce-source/test.py +0 -0
- package/recce-source/tests/__init__.py +0 -0
- package/recce-source/tests/adapter/__init__.py +0 -0
- package/recce-source/tests/adapter/dbt_adapter/__init__.py +0 -0
- package/recce-source/tests/adapter/dbt_adapter/conftest.py +17 -0
- package/recce-source/tests/adapter/dbt_adapter/dbt_test_helper.py +298 -0
- package/recce-source/tests/adapter/dbt_adapter/test_dbt_adapter.py +25 -0
- package/recce-source/tests/adapter/dbt_adapter/test_dbt_cll.py +717 -0
- package/recce-source/tests/adapter/dbt_adapter/test_proj/dbt_project.yml +4 -0
- package/recce-source/tests/adapter/dbt_adapter/test_proj/manifest.json +1 -0
- package/recce-source/tests/adapter/dbt_adapter/test_proj/package-lock.yml +8 -0
- package/recce-source/tests/adapter/dbt_adapter/test_proj/packages.yml +7 -0
- package/recce-source/tests/adapter/dbt_adapter/test_proj/profiles.yml +6 -0
- package/recce-source/tests/adapter/dbt_adapter/test_selector.py +205 -0
- package/recce-source/tests/apis/__init__.py +0 -0
- package/recce-source/tests/apis/row_count_diff.json +59 -0
- package/recce-source/tests/apis/test_check_events_api.py +615 -0
- package/recce-source/tests/apis/test_run_func.py +433 -0
- package/recce-source/tests/catalog.json +527 -0
- package/recce-source/tests/data/manifest/base/catalog.json +1 -0
- package/recce-source/tests/data/manifest/base/manifest.json +1 -0
- package/recce-source/tests/data/manifest/pr2/catalog.json +1 -0
- package/recce-source/tests/data/manifest/pr2/manifest.json +1 -0
- package/recce-source/tests/manifest.json +10655 -0
- package/recce-source/tests/models/__init__.py +0 -0
- package/recce-source/tests/models/test_check.py +731 -0
- package/recce-source/tests/models/test_run_models.py +295 -0
- package/recce-source/tests/recce_cloud/__init__.py +0 -0
- package/recce-source/tests/recce_cloud/test_ci_providers.py +351 -0
- package/recce-source/tests/recce_cloud/test_cli.py +735 -0
- package/recce-source/tests/recce_cloud/test_client.py +379 -0
- package/recce-source/tests/recce_cloud/test_platform_clients.py +483 -0
- package/recce-source/tests/recce_state.json +1 -0
- package/recce-source/tests/state/test_cloud.py +719 -0
- package/recce-source/tests/state/test_local.py +164 -0
- package/recce-source/tests/state/test_state_loader.py +211 -0
- package/recce-source/tests/tasks/__init__.py +0 -0
- package/recce-source/tests/tasks/conftest.py +4 -0
- package/recce-source/tests/tasks/test_histogram.py +129 -0
- package/recce-source/tests/tasks/test_lineage.py +55 -0
- package/recce-source/tests/tasks/test_preset_checks.py +64 -0
- package/recce-source/tests/tasks/test_profile.py +397 -0
- package/recce-source/tests/tasks/test_query.py +528 -0
- package/recce-source/tests/tasks/test_row_count.py +133 -0
- package/recce-source/tests/tasks/test_schema.py +122 -0
- package/recce-source/tests/tasks/test_top_k.py +77 -0
- package/recce-source/tests/tasks/test_utils.py +439 -0
- package/recce-source/tests/tasks/test_valuediff.py +361 -0
- package/recce-source/tests/test_cli.py +236 -0
- package/recce-source/tests/test_cli_mcp_optional.py +45 -0
- package/recce-source/tests/test_cloud_listing_cli.py +324 -0
- package/recce-source/tests/test_config.py +43 -0
- package/recce-source/tests/test_connect_to_cloud.py +82 -0
- package/recce-source/tests/test_core.py +174 -0
- package/recce-source/tests/test_dbt.py +36 -0
- package/recce-source/tests/test_mcp_server.py +505 -0
- package/recce-source/tests/test_pull_request.py +130 -0
- package/recce-source/tests/test_server.py +202 -0
- package/recce-source/tests/test_server_lifespan.py +138 -0
- package/recce-source/tests/test_summary.py +73 -0
- package/recce-source/tests/util/__init__.py +0 -0
- package/recce-source/tests/util/cloud/__init__.py +0 -0
- package/recce-source/tests/util/cloud/test_check_events.py +255 -0
- package/recce-source/tests/util/cloud/test_checks.py +204 -0
- package/recce-source/tests/util/test_api_token.py +119 -0
- package/recce-source/tests/util/test_breaking.py +1427 -0
- package/recce-source/tests/util/test_cll.py +706 -0
- package/recce-source/tests/util/test_lineage.py +122 -0
- package/recce-source/tests/util/test_onboarding_state.py +84 -0
- package/recce-source/tests/util/test_recce_cloud.py +231 -0
- package/recce-source/tox.ini +40 -0
- package/recce-source/uv.lock +3928 -0
- package/src/api/index.ts +32 -0
- package/src/components/index.ts +154 -0
- package/src/global.d.ts +14 -0
- package/src/hooks/index.ts +56 -0
- package/src/index.ts +17 -0
- package/src/lib/hooks/RouteConfigContext.ts +139 -0
- package/src/lib/hooks/useAppRouter.ts +240 -0
- package/src/mui-augmentation.d.ts +139 -0
- package/src/theme/index.ts +13 -0
- package/src/theme.ts +23 -0
- package/src/types/index.ts +23 -0
- package/dist/index-BNUP2V_N.d.ts.map +0 -1
- package/dist/index-DOPZuhD8.d.mts.map +0 -1
- package/dist/theme.d.mts.map +0 -1
- package/dist/theme.d.ts.map +0 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { mergeKeys } from "./mergeKeys";
|
|
2
|
+
|
|
3
|
+
export function formatSelectColumns(
|
|
4
|
+
baseColumns: string[],
|
|
5
|
+
currentColumns: string[],
|
|
6
|
+
): string[] {
|
|
7
|
+
const mergedColumns = mergeKeys(baseColumns, currentColumns);
|
|
8
|
+
|
|
9
|
+
// both side have no schema
|
|
10
|
+
if (mergedColumns.length === 0) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// if either side has schema (added and removed model, no catalog.json)
|
|
15
|
+
if (baseColumns.length === 0 || currentColumns.length === 0) {
|
|
16
|
+
return mergedColumns.map((col, idx) => {
|
|
17
|
+
const last = idx === mergedColumns.length - 1;
|
|
18
|
+
if (last) {
|
|
19
|
+
return col;
|
|
20
|
+
}
|
|
21
|
+
return col + ",";
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let lastActualColumn = "";
|
|
26
|
+
mergedColumns.forEach((col) => {
|
|
27
|
+
if (baseColumns.includes(col) && currentColumns.includes(col)) {
|
|
28
|
+
lastActualColumn = col;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const selectColumns = mergedColumns.map((col, idx) => {
|
|
33
|
+
let formatCol;
|
|
34
|
+
|
|
35
|
+
if (!baseColumns.includes(col)) {
|
|
36
|
+
formatCol = `--- ${col} (Added)`;
|
|
37
|
+
} else if (!currentColumns.includes(col)) {
|
|
38
|
+
formatCol = `--- ${col} (Removed)`;
|
|
39
|
+
} else {
|
|
40
|
+
formatCol = col;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (col === lastActualColumn || idx === mergedColumns.length - 1) {
|
|
44
|
+
return formatCol;
|
|
45
|
+
}
|
|
46
|
+
return formatCol + ",";
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return selectColumns;
|
|
50
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import axios, { AxiosInstance } from "axios";
|
|
2
|
+
import React, { createContext, useContext, useMemo } from "react";
|
|
3
|
+
import { PUBLIC_API_URL } from "@/lib/const";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* API Configuration Context
|
|
7
|
+
*
|
|
8
|
+
* Provides configurable API endpoint prefix and authentication token
|
|
9
|
+
* for use with recce-cloud or other custom API backends.
|
|
10
|
+
*
|
|
11
|
+
* Default behavior (OSS):
|
|
12
|
+
* - apiPrefix: "" (uses /api/* paths directly)
|
|
13
|
+
* - authToken: undefined (no auth header)
|
|
14
|
+
*
|
|
15
|
+
* Cloud usage example:
|
|
16
|
+
* - apiPrefix: "/api/v2/sessions/abc123" (replaces /api with this prefix)
|
|
17
|
+
* - authToken: "eyJ..." (adds Authorization: Bearer header)
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export interface ApiConfig {
|
|
21
|
+
/**
|
|
22
|
+
* API endpoint prefix to replace `/api` in all requests.
|
|
23
|
+
* For OSS: "" (empty string, uses default /api/* paths)
|
|
24
|
+
* For Cloud: "/api/v2/sessions/<session_id>" (replaces /api with this)
|
|
25
|
+
*/
|
|
26
|
+
apiPrefix: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Optional authentication token for API requests.
|
|
30
|
+
* When provided, adds "Authorization: Bearer <token>" header.
|
|
31
|
+
*/
|
|
32
|
+
authToken?: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Optional base URL override.
|
|
36
|
+
* When provided, overrides the PUBLIC_API_URL for this context.
|
|
37
|
+
*/
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface ApiConfigContextType extends ApiConfig {
|
|
42
|
+
/**
|
|
43
|
+
* Pre-configured axios instance with interceptors for
|
|
44
|
+
* API prefix replacement and auth token injection.
|
|
45
|
+
*/
|
|
46
|
+
apiClient: AxiosInstance;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const defaultConfig: ApiConfig = {
|
|
50
|
+
apiPrefix: "",
|
|
51
|
+
authToken: undefined,
|
|
52
|
+
baseUrl: undefined,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const ApiConfigContext = createContext<ApiConfigContextType | null>(null);
|
|
56
|
+
|
|
57
|
+
interface ApiConfigProviderProps extends Partial<ApiConfig> {
|
|
58
|
+
children: React.ReactNode;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates an axios instance configured with the given API config.
|
|
63
|
+
*
|
|
64
|
+
* The instance has interceptors that:
|
|
65
|
+
* 1. Replace /api prefix with the configured apiPrefix (if provided)
|
|
66
|
+
* 2. Add Authorization header with Bearer token (if authToken provided)
|
|
67
|
+
*/
|
|
68
|
+
function createApiClient(config: ApiConfig): AxiosInstance {
|
|
69
|
+
const { apiPrefix, authToken, baseUrl } = config;
|
|
70
|
+
|
|
71
|
+
const client = axios.create({
|
|
72
|
+
baseURL: baseUrl ?? PUBLIC_API_URL,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Request interceptor to modify URL and add auth header
|
|
76
|
+
client.interceptors.request.use(
|
|
77
|
+
(requestConfig) => {
|
|
78
|
+
try {
|
|
79
|
+
// Replace /api prefix with configured apiPrefix (only if apiPrefix is non-empty)
|
|
80
|
+
if (apiPrefix && requestConfig.url) {
|
|
81
|
+
// Handle exact "/api" and "/api/*" URLs explicitly
|
|
82
|
+
if (requestConfig.url === "/api") {
|
|
83
|
+
requestConfig.url = apiPrefix;
|
|
84
|
+
} else if (requestConfig.url.startsWith("/api/")) {
|
|
85
|
+
// "/api".length === 4; keep everything after that
|
|
86
|
+
requestConfig.url = apiPrefix + requestConfig.url.slice(4);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Add auth header if token is provided
|
|
91
|
+
if (authToken) {
|
|
92
|
+
requestConfig.headers.Authorization = `Bearer ${authToken}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return requestConfig;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
// If anything goes wrong in the interceptor, fall back to the original config
|
|
98
|
+
// to avoid breaking all API requests.
|
|
99
|
+
console.warn(
|
|
100
|
+
"API request interceptor error, proceeding with unmodified request:",
|
|
101
|
+
error,
|
|
102
|
+
);
|
|
103
|
+
return requestConfig;
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
(error) => {
|
|
107
|
+
// Preserve default axios behavior for request errors
|
|
108
|
+
return Promise.reject(error);
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
return client;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function ApiConfigProvider({
|
|
116
|
+
children,
|
|
117
|
+
apiPrefix = defaultConfig.apiPrefix,
|
|
118
|
+
authToken = defaultConfig.authToken,
|
|
119
|
+
baseUrl = defaultConfig.baseUrl,
|
|
120
|
+
}: ApiConfigProviderProps) {
|
|
121
|
+
const config: ApiConfig = useMemo(
|
|
122
|
+
() => ({ apiPrefix, authToken, baseUrl }),
|
|
123
|
+
[apiPrefix, authToken, baseUrl],
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const apiClient = useMemo(() => createApiClient(config), [config]);
|
|
127
|
+
|
|
128
|
+
const contextValue: ApiConfigContextType = useMemo(
|
|
129
|
+
() => ({
|
|
130
|
+
...config,
|
|
131
|
+
apiClient,
|
|
132
|
+
}),
|
|
133
|
+
[config, apiClient],
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<ApiConfigContext.Provider value={contextValue}>
|
|
138
|
+
{children}
|
|
139
|
+
</ApiConfigContext.Provider>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Default config used when ApiConfigProvider is not present (OSS mode)
|
|
144
|
+
const defaultApiConfigContext: ApiConfigContextType = {
|
|
145
|
+
apiPrefix: "",
|
|
146
|
+
authToken: undefined,
|
|
147
|
+
baseUrl: undefined,
|
|
148
|
+
apiClient: axios.create({ baseURL: PUBLIC_API_URL }),
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Hook to access the API configuration and configured axios client.
|
|
153
|
+
*
|
|
154
|
+
* When used outside ApiConfigProvider, returns default config with
|
|
155
|
+
* standard axiosClient (for OSS backward compatibility).
|
|
156
|
+
*
|
|
157
|
+
* @returns ApiConfigContextType with apiPrefix, authToken, and apiClient
|
|
158
|
+
*/
|
|
159
|
+
export function useApiConfig(): ApiConfigContextType {
|
|
160
|
+
const context = useContext(ApiConfigContext);
|
|
161
|
+
// Return default config if outside provider (OSS mode)
|
|
162
|
+
return context ?? defaultApiConfigContext;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Hook to get the configured axios client.
|
|
167
|
+
* Convenience wrapper around useApiConfig().apiClient
|
|
168
|
+
*
|
|
169
|
+
* @returns AxiosInstance configured with API prefix and auth token
|
|
170
|
+
*/
|
|
171
|
+
export function useApiClient(): AxiosInstance {
|
|
172
|
+
return useApiConfig().apiClient;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Safe version of useApiConfig that returns null if outside provider.
|
|
177
|
+
* Useful for components that need to detect if ApiConfigProvider is present.
|
|
178
|
+
*/
|
|
179
|
+
export function useApiConfigSafe(): ApiConfigContextType | null {
|
|
180
|
+
return useContext(ApiConfigContext);
|
|
181
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
useCallback,
|
|
7
|
+
useContext,
|
|
8
|
+
useEffect,
|
|
9
|
+
useRef,
|
|
10
|
+
useState,
|
|
11
|
+
} from "react";
|
|
12
|
+
import {
|
|
13
|
+
getLastKeepAliveTime,
|
|
14
|
+
setKeepAliveCallback,
|
|
15
|
+
} from "@/lib/api/keepAlive";
|
|
16
|
+
import { useIdleDetection } from "./useIdleDetection";
|
|
17
|
+
import { useRecceInstanceInfo } from "./useRecceInstanceInfo";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Context for sharing idle timeout state across components
|
|
21
|
+
*
|
|
22
|
+
* IMPORTANT: The countdown is based on the last SUCCESSFUL keep-alive API call,
|
|
23
|
+
* NOT on user activity. This ensures the countdown accurately reflects the
|
|
24
|
+
* server's idle timeout state.
|
|
25
|
+
*/
|
|
26
|
+
interface IdleTimeoutContextType {
|
|
27
|
+
/** Remaining seconds until timeout (null if idle timeout not enabled) */
|
|
28
|
+
remainingSeconds: number | null;
|
|
29
|
+
/** Idle timeout value from server in seconds (null if not configured) */
|
|
30
|
+
idleTimeout: number | null;
|
|
31
|
+
/** Whether idle timeout is enabled */
|
|
32
|
+
isEnabled: boolean;
|
|
33
|
+
/** Mark as disconnected - stops countdown and keep-alive */
|
|
34
|
+
setDisconnected: () => void;
|
|
35
|
+
/** Reset connection state - restarts countdown and keep-alive after successful reconnect */
|
|
36
|
+
resetConnection: () => void;
|
|
37
|
+
/** Whether the connection is disconnected */
|
|
38
|
+
isDisconnected: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const IdleTimeoutContext = createContext<IdleTimeoutContextType | undefined>(
|
|
42
|
+
undefined,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Provider for idle timeout state
|
|
47
|
+
*
|
|
48
|
+
* The countdown is based on lastServerSyncTime (when keep-alive API was last
|
|
49
|
+
* successfully sent), not on user activity. This provides accurate server state.
|
|
50
|
+
*/
|
|
51
|
+
export function IdleTimeoutProvider({ children }: { children: ReactNode }) {
|
|
52
|
+
const { data: instanceInfo } = useRecceInstanceInfo();
|
|
53
|
+
// Track the last time we successfully synced with server (keep-alive sent)
|
|
54
|
+
const lastServerSyncRef = useRef<number>(Date.now());
|
|
55
|
+
const [remainingSeconds, setRemainingSeconds] = useState<number | null>(null);
|
|
56
|
+
const [isDisconnected, setIsDisconnected] = useState(false);
|
|
57
|
+
|
|
58
|
+
const idleTimeout = instanceInfo?.idle_timeout ?? null;
|
|
59
|
+
const isEnabled = idleTimeout !== null && idleTimeout > 0;
|
|
60
|
+
|
|
61
|
+
// Register callback to receive keep-alive success notifications
|
|
62
|
+
// Use ref to track enabled state to avoid race condition in callback
|
|
63
|
+
const isEnabledRef = useRef(isEnabled);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
isEnabledRef.current = isEnabled;
|
|
66
|
+
}, [isEnabled]);
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!isEnabled) {
|
|
70
|
+
setKeepAliveCallback(null);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
setKeepAliveCallback((timestamp: number) => {
|
|
75
|
+
// Check current enabled state to avoid updating after disabled
|
|
76
|
+
if (isEnabledRef.current) {
|
|
77
|
+
lastServerSyncRef.current = timestamp;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Initialize with current keep-alive time if available
|
|
82
|
+
const currentTime = getLastKeepAliveTime();
|
|
83
|
+
if (currentTime > 0) {
|
|
84
|
+
lastServerSyncRef.current = currentTime;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return () => {
|
|
88
|
+
setKeepAliveCallback(null);
|
|
89
|
+
};
|
|
90
|
+
}, [isEnabled]);
|
|
91
|
+
|
|
92
|
+
const setDisconnected = useCallback(() => {
|
|
93
|
+
setIsDisconnected(true);
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
96
|
+
const resetConnection = useCallback(() => {
|
|
97
|
+
// Reset disconnected state
|
|
98
|
+
setIsDisconnected(false);
|
|
99
|
+
// Reset server sync time to now (server just restarted, timer reset)
|
|
100
|
+
lastServerSyncRef.current = Date.now();
|
|
101
|
+
}, []);
|
|
102
|
+
|
|
103
|
+
// Update remaining seconds every second based on server sync time
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
if (!isEnabled || idleTimeout === null) {
|
|
106
|
+
setRemainingSeconds(null);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Stop updating countdown if disconnected
|
|
111
|
+
if (isDisconnected) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const updateCountdown = () => {
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
const elapsedSeconds = (now - lastServerSyncRef.current) / 1000;
|
|
118
|
+
const remaining = Math.max(0, idleTimeout - elapsedSeconds);
|
|
119
|
+
setRemainingSeconds(remaining);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// Initial update
|
|
123
|
+
updateCountdown();
|
|
124
|
+
|
|
125
|
+
// Set up interval for updates
|
|
126
|
+
const intervalId = setInterval(updateCountdown, 1000);
|
|
127
|
+
|
|
128
|
+
return () => {
|
|
129
|
+
clearInterval(intervalId);
|
|
130
|
+
};
|
|
131
|
+
}, [isEnabled, idleTimeout, isDisconnected]);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<IdleTimeoutContext.Provider
|
|
135
|
+
value={{
|
|
136
|
+
remainingSeconds,
|
|
137
|
+
idleTimeout,
|
|
138
|
+
isEnabled,
|
|
139
|
+
setDisconnected,
|
|
140
|
+
resetConnection,
|
|
141
|
+
isDisconnected,
|
|
142
|
+
}}
|
|
143
|
+
>
|
|
144
|
+
<IdleDetector />
|
|
145
|
+
{children}
|
|
146
|
+
</IdleTimeoutContext.Provider>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Internal component that activates idle detection
|
|
152
|
+
* Placed inside provider so it has access to context
|
|
153
|
+
*/
|
|
154
|
+
function IdleDetector() {
|
|
155
|
+
useIdleDetection();
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Hook to access idle timeout context
|
|
161
|
+
* @throws Error if used outside IdleTimeoutProvider
|
|
162
|
+
*/
|
|
163
|
+
export function useIdleTimeout() {
|
|
164
|
+
const context = useContext(IdleTimeoutContext);
|
|
165
|
+
if (!context) {
|
|
166
|
+
throw new Error("useIdleTimeout must be used within IdleTimeoutProvider");
|
|
167
|
+
}
|
|
168
|
+
return context;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Hook to access idle timeout context, returns null if outside provider
|
|
173
|
+
* Used internally by useIdleDetection to avoid circular dependency
|
|
174
|
+
*/
|
|
175
|
+
export function useIdleTimeoutSafe(): IdleTimeoutContextType | null {
|
|
176
|
+
return useContext(IdleTimeoutContext) ?? null;
|
|
177
|
+
}
|