gloomberb 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
package/src/cli/report-tables.ts
CHANGED
|
@@ -57,6 +57,12 @@ export interface CliReportColumn<Row = Record<string, unknown>> {
|
|
|
57
57
|
format?: (value: unknown, row: Row) => string;
|
|
58
58
|
/** The row field naming the unit of a number in this column; the number then exports as it is, with that unit. */
|
|
59
59
|
unitKey?: string;
|
|
60
|
+
/**
|
|
61
|
+
* With `unitKey`: the unit always goes to a `<header> unit` column beside
|
|
62
|
+
* the figures, never into the header, so the header is the same whichever
|
|
63
|
+
* rows loaded (a market cap in one currency for some peers, in another for others).
|
|
64
|
+
*/
|
|
65
|
+
unitColumn?: boolean;
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
/** A label/value line of a report. `unit` names the unit of a numeric `value` when `formatted` cannot say it. */
|
|
@@ -69,7 +75,8 @@ export interface CliReportEntry {
|
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
type Cell =
|
|
72
|
-
|
|
78
|
+
/** `unit`: what the column draws a number of this row in, so a missing figure still names its unit. */
|
|
79
|
+
| { kind: "blank"; unit?: string }
|
|
73
80
|
| { kind: "text"; text: string; time?: boolean }
|
|
74
81
|
| { kind: "number"; value: number; unit: string }
|
|
75
82
|
/** Text that may read as a number, once the whole column is known. */
|
|
@@ -80,6 +87,10 @@ type ResolvedCell = Exclude<Cell, { kind: "textual" }>;
|
|
|
80
87
|
interface ResolvedColumn {
|
|
81
88
|
header: string;
|
|
82
89
|
cells: ResolvedCell[];
|
|
90
|
+
/** The unit the column draws its numbers in, for a table with no rows to say it. */
|
|
91
|
+
unit?: string;
|
|
92
|
+
/** The unit always has a column of its own (`unitColumn`). */
|
|
93
|
+
unitColumn?: boolean;
|
|
83
94
|
}
|
|
84
95
|
|
|
85
96
|
const BLANK = { kind: "blank" } as const;
|
|
@@ -265,8 +276,9 @@ function resolveColumn(header: string, cells: Cell[], parseText: boolean): Resol
|
|
|
265
276
|
};
|
|
266
277
|
}
|
|
267
278
|
|
|
279
|
+
/** The units a column's numbers are in, a missing figure's own among them, so the header does not change with which figures are missing. */
|
|
268
280
|
function numberUnits(cells: readonly ResolvedCell[]): Set<string> {
|
|
269
|
-
return new Set(cells.flatMap((cell) => cell.kind === "number" ? [cell.unit] : []));
|
|
281
|
+
return new Set(cells.flatMap((cell) => cell.kind === "number" ? [cell.unit] : cell.kind === "blank" && cell.unit != null ? [cell.unit] : []));
|
|
270
282
|
}
|
|
271
283
|
|
|
272
284
|
function cellValue(cell: ResolvedCell): CliReportValue {
|
|
@@ -312,9 +324,9 @@ function rowUnits(columns: readonly ResolvedColumn[], mixed: readonly boolean[],
|
|
|
312
324
|
* metrics whose rows each have one, and otherwise a `<header> unit` column
|
|
313
325
|
* beside a column that mixes them (a rate in % and a spread in bp).
|
|
314
326
|
*/
|
|
315
|
-
function assembleTable(title: string, columns: readonly ResolvedColumn[], rowCount: number): CliReportTable {
|
|
316
|
-
const units = columns.map((column) => numberUnits(column.cells));
|
|
317
|
-
const mixed = units.map((columnUnits) => columnUnits.size > 1);
|
|
327
|
+
function assembleTable(title: string, columns: readonly ResolvedColumn[], rowCount: number, status?: StatusColumn): CliReportTable {
|
|
328
|
+
const units = columns.map((column) => rowCount === 0 && column.unit != null ? new Set([column.unit]) : numberUnits(column.cells));
|
|
329
|
+
const mixed = units.map((columnUnits, index) => columnUnits.size > 1 || columns[index]!.unitColumn === true);
|
|
318
330
|
const byRow = mixed.some(Boolean) ? rowUnits(columns, mixed, rowCount) : null;
|
|
319
331
|
const layout = columns.flatMap((column, index) => {
|
|
320
332
|
const columnUnits = units[index]!;
|
|
@@ -338,6 +350,7 @@ function assembleTable(title: string, columns: readonly ResolvedColumn[], rowCou
|
|
|
338
350
|
},
|
|
339
351
|
];
|
|
340
352
|
});
|
|
353
|
+
if (status) layout.push({ header: status.header, value: (row: number) => status.values[row] ?? "" });
|
|
341
354
|
return {
|
|
342
355
|
title,
|
|
343
356
|
columns: layout.map((column) => column.header),
|
|
@@ -345,28 +358,151 @@ function assembleTable(title: string, columns: readonly ResolvedColumn[], rowCou
|
|
|
345
358
|
};
|
|
346
359
|
}
|
|
347
360
|
|
|
361
|
+
/** The `status` column a table of rows ends its own columns with: why a figure is missing, by row. */
|
|
362
|
+
interface StatusColumn {
|
|
363
|
+
header: string;
|
|
364
|
+
values: string[];
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* A number a probe draws through a column's format, to read the unit the
|
|
369
|
+
* column draws numbers in. A figure format rounds it; a format that prints
|
|
370
|
+
* it whole passes values through as text and draws no figures of its own.
|
|
371
|
+
*/
|
|
372
|
+
const UNIT_PROBE = 0.1234567891;
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* A row with nothing in it that a format can still read through: every
|
|
376
|
+
* field, call and conversion of it is empty. For a format that reads fields of
|
|
377
|
+
* the row beyond its value and would throw on an empty one.
|
|
378
|
+
*/
|
|
379
|
+
const EMPTY_ROW: unknown = (() => {
|
|
380
|
+
const empty: unknown = new Proxy(function empty() {}, {
|
|
381
|
+
get: (_target, key) => key === Symbol.toPrimitive ? (hint: string) => (hint === "number" ? Number.NaN : "") : empty,
|
|
382
|
+
apply: () => empty,
|
|
383
|
+
});
|
|
384
|
+
return empty;
|
|
385
|
+
})();
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* The unit a column draws a number of this row in (`%` for an IV, `""` for a
|
|
389
|
+
* plain figure), read from what its format draws for one; null when it draws
|
|
390
|
+
* no figure for one, passes the value through as it is, or throws.
|
|
391
|
+
*/
|
|
392
|
+
function drawnUnit<Row>(column: CliReportColumn<Row>, row: Row, rowUnitKey?: string): string | null {
|
|
393
|
+
// A figure in the row's own unit is bare: the row's `currency_or_unit` names it.
|
|
394
|
+
if (rowUnitKey && column.unitKey === rowUnitKey) return "";
|
|
395
|
+
const unit = column.unitKey ? (row as Record<string, unknown> | undefined)?.[column.unitKey] : undefined;
|
|
396
|
+
if (typeof unit === "string" && unit) return unit;
|
|
397
|
+
if (!column.format) return null;
|
|
398
|
+
try {
|
|
399
|
+
const drawn = column.format(UNIT_PROBE, row);
|
|
400
|
+
if (typeof drawn !== "string" || drawn.trim() === String(UNIT_PROBE)) return null;
|
|
401
|
+
const read = readDisplay(drawn);
|
|
402
|
+
return read && read !== BLANK_DISPLAY ? read.unit : null;
|
|
403
|
+
} catch {
|
|
404
|
+
// Intentional ignore: a format that cannot draw a number for this row draws no unit for it.
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* The unit a column draws its figures in whatever the rows, read without one:
|
|
411
|
+
* on an empty row, or through a row of nothing when the format throws on an
|
|
412
|
+
* empty one. The same with rows and without, so a header and the table's
|
|
413
|
+
* status column do not depend on what was loaded. Null for a column of text.
|
|
414
|
+
*/
|
|
415
|
+
function columnUnit<Row>(column: CliReportColumn<Row>): string | null {
|
|
416
|
+
if (column.unitKey) return "";
|
|
417
|
+
if (!column.format) return null;
|
|
418
|
+
try {
|
|
419
|
+
column.format(UNIT_PROBE, {} as Row);
|
|
420
|
+
return drawnUnit(column, {} as Row);
|
|
421
|
+
} catch {
|
|
422
|
+
// Intentional ignore: the format reads a field an empty row lacks; read it through a row of nothing.
|
|
423
|
+
return drawnUnit(column, EMPTY_ROW as Row);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/** What a status cell says: each reason once, after the columns it is the reason for. */
|
|
428
|
+
function statusText(reasons: ReadonlyArray<{ header: string; text: string }>): string {
|
|
429
|
+
const byText = new Map<string, string[]>();
|
|
430
|
+
for (const { header, text } of reasons) byText.set(text, [...byText.get(text) ?? [], header]);
|
|
431
|
+
return [...byText].map(([text, headers]) => `${headers.join(", ")}: ${text}`).join("; ");
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const isMissing = (value: unknown) => value == null || (typeof value === "number" && !Number.isFinite(value));
|
|
435
|
+
|
|
348
436
|
// Codes a spreadsheet must not turn into numbers, even when they are digits.
|
|
349
437
|
const IDENTIFIER_KEY = /^(?:id|cik|code|cusip|figi|isin|symbol|ticker)$|(?:Id|Cik|Code|Cusip|Figi|Isin|Symbol|Ticker)$/;
|
|
350
438
|
|
|
351
|
-
/**
|
|
439
|
+
/**
|
|
440
|
+
* A table of rows under the columns the text view draws. A figure that is
|
|
441
|
+
* missing still names the unit its column draws it in, so a header is the same
|
|
442
|
+
* whichever figures a symbol has. With `status`, a reason the text draws in
|
|
443
|
+
* place of a missing figure (`not quoted`, `under 7d`) leaves the cell empty
|
|
444
|
+
* and goes to the `status` column the table ends its own columns with, so a
|
|
445
|
+
* column of figures holds only numbers. Only a row whose own value is missing,
|
|
446
|
+
* in a column that draws that row's figures, has a reason: text a format draws
|
|
447
|
+
* from the rest of the row (a range, N/M, ATM) stays. A table has the column
|
|
448
|
+
* when one of its columns draws figures through a format, read from the
|
|
449
|
+
* columns alone so it is there with or without rows, and a table of text has
|
|
450
|
+
* none; beside a column of its own named Status it is `value_status`.
|
|
451
|
+
* `rowUnitKey` is the row field its `currency_or_unit` cell is read from: a
|
|
452
|
+
* column whose `unitKey` is that field exports its figures bare under its own
|
|
453
|
+
* header (`Last`, never `Last ($)` beside a franc), each row's unit named there.
|
|
454
|
+
*/
|
|
352
455
|
export function exportRowsTable<Row extends Record<string, unknown>>(
|
|
353
456
|
title: string,
|
|
354
457
|
columns: readonly CliReportColumn<Row>[],
|
|
355
458
|
rows: readonly Row[],
|
|
459
|
+
{ status = false, rowUnitKey }: { status?: boolean; rowUnitKey?: string } = {},
|
|
356
460
|
): CliReportTable {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
461
|
+
const reasons = rows.map((): Array<{ header: string; text: string }> => []);
|
|
462
|
+
const units = columns.map(columnUnit);
|
|
463
|
+
// Decided by the columns alone, so a table has the column, or not, whatever rows it has.
|
|
464
|
+
const withStatus = status && units.some((unit) => unit != null);
|
|
465
|
+
const resolved = columns.map((column, columnIndex): ResolvedColumn => {
|
|
466
|
+
const rowUnits = rows.map((row) => drawnUnit(column, row, rowUnitKey));
|
|
467
|
+
const values = rows.map((row) => (row as Record<string, unknown> | undefined)?.[column.key]);
|
|
468
|
+
const inRowUnit = !!rowUnitKey && column.unitKey === rowUnitKey;
|
|
469
|
+
const { header, cells } = resolveColumn(
|
|
470
|
+
column.header,
|
|
471
|
+
rows.map((row, index): Cell => {
|
|
472
|
+
const value = values[index];
|
|
473
|
+
const unit = column.unitKey ? (row as Record<string, unknown> | undefined)?.[column.unitKey] : undefined;
|
|
474
|
+
const drawn = column.format ? column.format(value, row) : null;
|
|
475
|
+
// A figure the text leaves out of this row (another session's print) is not one of its figures.
|
|
476
|
+
const left = drawn != null && readDisplay(drawn) === BLANK_DISPLAY;
|
|
477
|
+
if (!left && typeof value === "number" && Number.isFinite(value) && (inRowUnit || (typeof unit === "string" && unit))) {
|
|
478
|
+
return { kind: "number", value: exportNumber(value), unit: inRowUnit ? "" : unit as string };
|
|
479
|
+
}
|
|
480
|
+
return exportCell(value, drawn, column.key);
|
|
481
|
+
}),
|
|
482
|
+
!IDENTIFIER_KEY.test(column.key),
|
|
483
|
+
);
|
|
484
|
+
const table: ResolvedColumn = {
|
|
485
|
+
header,
|
|
486
|
+
cells: cells.map((cell, index): ResolvedCell => {
|
|
487
|
+
const unit = rowUnits[index];
|
|
488
|
+
const blank: ResolvedCell = unit != null ? { kind: "blank", unit } : BLANK;
|
|
489
|
+
if (cell.kind === "blank") return cell.unit == null ? blank : cell;
|
|
490
|
+
// Text drawn in place of a figure this row does not have, where the column draws this row's figures: a reason.
|
|
491
|
+
// Text drawn from the rest of the row (a range, N/M, ATM) is no figure's absence and stays.
|
|
492
|
+
if (!withStatus || cell.kind !== "text" || cell.time || unit == null || !isMissing(values[index])) return cell;
|
|
493
|
+
reasons[index]!.push({ header: column.header, text: cell.text });
|
|
494
|
+
return blank;
|
|
495
|
+
}),
|
|
496
|
+
};
|
|
497
|
+
const unit = units[columnIndex];
|
|
498
|
+
const withUnit = unit == null ? table : { ...table, unit };
|
|
499
|
+
return column.unitColumn && column.unitKey && !inRowUnit ? { ...withUnit, unitColumn: true } : withUnit;
|
|
500
|
+
});
|
|
501
|
+
const statusColumn = withStatus ? {
|
|
502
|
+
header: columns.some((column) => column.header.trim().toLowerCase() === "status") ? "value_status" : "status",
|
|
503
|
+
values: reasons.map(statusText),
|
|
504
|
+
} : undefined;
|
|
505
|
+
return assembleTable(title, resolved, rows.length, statusColumn);
|
|
370
506
|
}
|
|
371
507
|
|
|
372
508
|
/** Label/value lines as `Metric,Value`; a number's unit moves into its label. */
|
|
@@ -434,18 +570,33 @@ function sectionList(tables: readonly CliReportTable[]): string {
|
|
|
434
570
|
}
|
|
435
571
|
|
|
436
572
|
/**
|
|
437
|
-
* `--section
|
|
438
|
-
*
|
|
573
|
+
* The table `--section` names by title, in any case: the one titled so, else
|
|
574
|
+
* the one whose title starts with it, as a title that carries its date does
|
|
575
|
+
* (`Strikes` for `Strikes · Oct 30 '26`). A start several titles share picks
|
|
576
|
+
* none.
|
|
577
|
+
*/
|
|
578
|
+
function sectionByTitle(tables: readonly CliReportTable[], wanted: string): CliReportTable | undefined {
|
|
579
|
+
const name = wanted.toLowerCase();
|
|
580
|
+
const titles = tables.map((table) => table.title.trim().toLowerCase());
|
|
581
|
+
const exact = titles.indexOf(name);
|
|
582
|
+
if (exact >= 0) return tables[exact];
|
|
583
|
+
const starting = tables.filter((_, index) => titles[index]!.startsWith(name));
|
|
584
|
+
if (starting.length > 1) {
|
|
585
|
+
throw new Error(`"${wanted}" starts more than one section: ${starting.map((table) => table.title).join(", ")}. Give more of the title, or its number.`);
|
|
586
|
+
}
|
|
587
|
+
return starting[0];
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* `--section`: one table, by its title or the start of it (any case), or its
|
|
592
|
+
* 1-based position. Without a selector the report keeps every table.
|
|
439
593
|
*/
|
|
440
594
|
export function selectReportTables(report: CliReportTables, selector: string | true | undefined): CliReportTables {
|
|
441
595
|
if (selector === undefined) return report;
|
|
442
596
|
if (selector === true || !selector.trim()) throw new Error("--section needs a section title or number.");
|
|
443
597
|
const wanted = selector.trim();
|
|
444
598
|
if (report.tables.length === 0) throw new Error(`No section "${wanted}": this report has no tables.`);
|
|
445
|
-
const
|
|
446
|
-
? Number(wanted) - 1
|
|
447
|
-
: report.tables.findIndex((table) => table.title.trim().toLowerCase() === wanted.toLowerCase());
|
|
448
|
-
const table = report.tables[index];
|
|
599
|
+
const table = /^\d+$/.test(wanted) ? report.tables[Number(wanted) - 1] : sectionByTitle(report.tables, wanted);
|
|
449
600
|
if (!table) throw new Error(`No section "${wanted}". Sections: ${sectionList(report.tables)}.`);
|
|
450
601
|
return { ...report, tables: [table] };
|
|
451
602
|
}
|
|
@@ -464,7 +615,10 @@ function csvLine(row: readonly unknown[]): string {
|
|
|
464
615
|
|
|
465
616
|
/**
|
|
466
617
|
* A table with the fixed columns after its own, every row naming what it is
|
|
467
|
-
* and the source and as-of the footer cites. A
|
|
618
|
+
* and the source and as-of the footer cites. A fixed column the table already
|
|
619
|
+
* has under the same name is left out, so its own per-row values stay the
|
|
620
|
+
* only ones (CBR's `source` and `as_of`) and a reader keyed by name finds one
|
|
621
|
+
* column. A table without columns stays empty.
|
|
468
622
|
*/
|
|
469
623
|
function identifiedTable(table: CliReportTable, report: CliReportTables, freshness: ReportFreshness | undefined): CliReportTable {
|
|
470
624
|
if (!freshness || table.columns.length === 0) return table;
|
|
@@ -474,7 +628,16 @@ function identifiedTable(table: CliReportTable, report: CliReportTables, freshne
|
|
|
474
628
|
const own = table.rowIdentities?.[index];
|
|
475
629
|
return own ? exportIdentityCells(freshness, { ...identity, ...own }) : cells;
|
|
476
630
|
};
|
|
477
|
-
|
|
631
|
+
const added = EXPORT_IDENTITY_COLUMNS.flatMap((column, index) => table.columns.includes(column) ? [] : [index]);
|
|
632
|
+
if (added.length === 0) return table;
|
|
633
|
+
return {
|
|
634
|
+
...table,
|
|
635
|
+
columns: [...table.columns, ...added.map((index) => EXPORT_IDENTITY_COLUMNS[index]!)],
|
|
636
|
+
rows: table.rows.map((row, index) => {
|
|
637
|
+
const identityCells = rowCells(index);
|
|
638
|
+
return [...row, ...added.map((column) => identityCells[column]!)];
|
|
639
|
+
}),
|
|
640
|
+
};
|
|
478
641
|
}
|
|
479
642
|
|
|
480
643
|
/**
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { saveConfig } from "../data/config/store";
|
|
2
2
|
import { loadCliConfigIfAvailable } from "./context";
|
|
3
3
|
import { getPluginsDir } from "../plugins/loader";
|
|
4
|
-
import { seedExtractedPlugins } from "../plugins/extracted-plugins";
|
|
4
|
+
import { pluginSeedFailure, pluginSeedNotice, samePluginSeedFailure, seedExtractedPlugins } from "../plugins/extracted-plugins";
|
|
5
|
+
import { setPluginSeedNotice } from "../plugins/seed-notice";
|
|
5
6
|
import { debugLog } from "../utils/debug-log";
|
|
7
|
+
import type { AppConfig } from "../types/config";
|
|
6
8
|
|
|
7
9
|
const log = debugLog.createLogger("plugin-seed");
|
|
8
10
|
|
|
@@ -10,39 +12,52 @@ const log = debugLog.createLogger("plugin-seed");
|
|
|
10
12
|
* Reinstalls plugins that moved out of this repository into their own.
|
|
11
13
|
*
|
|
12
14
|
* Runs before the plugin catalog is read so a restored plugin is available in
|
|
13
|
-
* the same session, and
|
|
14
|
-
* normally and try again next time
|
|
15
|
+
* the same session, and never blocks or prints: an offline launch should
|
|
16
|
+
* start normally and try again next time. What it could not install becomes
|
|
17
|
+
* one notice the app shows once it is up (`setPluginSeedNotice`), saying why
|
|
18
|
+
* when git is missing, and `doctor` names the plugins.
|
|
15
19
|
*
|
|
16
|
-
* Returns the seeded ids so a caller that
|
|
17
|
-
* can adopt
|
|
18
|
-
* this it would keep an object
|
|
19
|
-
* overwrite the record on the next save.
|
|
20
|
+
* Returns what it recorded (the seeded ids, and what failed) so a caller that
|
|
21
|
+
* already holds the config in memory can adopt it. The desktop loads its
|
|
22
|
+
* config before restoring, and without this it would keep an object one
|
|
23
|
+
* launch stale and overwrite the record on the next save.
|
|
20
24
|
*/
|
|
21
|
-
export async function restoreExtractedPlugins(): Promise<
|
|
25
|
+
export async function restoreExtractedPlugins(): Promise<Pick<AppConfig, "seededPlugins" | "pluginSeedFailure"> | null> {
|
|
22
26
|
try {
|
|
23
27
|
const config = await loadCliConfigIfAvailable();
|
|
24
28
|
// No data directory yet means a first run: there is nothing to restore.
|
|
25
29
|
if (!config) return null;
|
|
26
|
-
// Through the registry like `
|
|
30
|
+
// Through the registry like `gloom install`: the reviewed commit, and
|
|
27
31
|
// nothing on a Gloomberb too old for it. That failure is retried at the
|
|
28
32
|
// next launch, by when this Gloomberb has usually updated itself. The
|
|
29
33
|
// registry is read once, and only when something is left to install.
|
|
30
|
-
|
|
34
|
+
// Quiet: the terminal app is about to own the screen, and git's or bun's
|
|
35
|
+
// output would be left behind in the scrollback.
|
|
36
|
+
const { gitInstalled, installListedPlugin, loadRegistryListings } = await import("../plugins/installer");
|
|
31
37
|
let listings: ReturnType<typeof loadRegistryListings> | undefined;
|
|
38
|
+
let gitMissing: boolean | undefined;
|
|
32
39
|
const result = await seedExtractedPlugins(config, async (repo) => {
|
|
40
|
+
// Without git every clone fails the same way: no registry read, no attempt.
|
|
41
|
+
gitMissing ??= !gitInstalled();
|
|
42
|
+
if (gitMissing) throw new Error("git is not installed");
|
|
33
43
|
listings ??= loadRegistryListings();
|
|
34
|
-
return installListedPlugin(repo, {}, await listings);
|
|
44
|
+
return installListedPlugin(repo, { quiet: true }, await listings);
|
|
35
45
|
});
|
|
46
|
+
// Recorded, so doctor knows a launch tried, and a failure the next launch
|
|
47
|
+
// retries is not announced again while it lasts.
|
|
48
|
+
const failure = pluginSeedFailure(result.failed, gitMissing === true);
|
|
49
|
+
setPluginSeedNotice(pluginSeedNotice(failure, config.pluginSeedFailure));
|
|
36
50
|
|
|
37
51
|
const seeded = [...new Set(result.seeded)].sort();
|
|
38
52
|
const existing = [...new Set(config.seededPlugins ?? [])].sort();
|
|
39
|
-
|
|
53
|
+
const record = { seededPlugins: seeded, pluginSeedFailure: failure };
|
|
54
|
+
if (seeded.join() === existing.join() && samePluginSeedFailure(failure, config.pluginSeedFailure)) return record;
|
|
40
55
|
|
|
41
|
-
await saveConfig({ ...config,
|
|
56
|
+
await saveConfig({ ...config, ...record });
|
|
42
57
|
if (result.installed.length > 0) {
|
|
43
58
|
log.info(`Restored ${result.installed.join(", ")} into ${getPluginsDir()}`);
|
|
44
59
|
}
|
|
45
|
-
return
|
|
60
|
+
return record;
|
|
46
61
|
} catch (error) {
|
|
47
62
|
log.error(`Plugin restore skipped: ${error}`);
|
|
48
63
|
return null;
|
package/src/cli/result.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CliGlobalOptions } from "./options";
|
|
2
2
|
import {
|
|
3
|
+
cliPlainEnabled,
|
|
3
4
|
cliStyles,
|
|
4
5
|
cliTerminalWidth,
|
|
5
6
|
renderStats,
|
|
@@ -13,7 +14,7 @@ import {
|
|
|
13
14
|
} from "../utils/cli-output";
|
|
14
15
|
import { serializeCsv } from "../utils/csv";
|
|
15
16
|
import { formatUtcTime, isEpochMilliseconds, isZonedIsoDateTime } from "../utils/utc-time";
|
|
16
|
-
import { formatFreshnessLine, type ReportFreshness } from "./pane-functions/freshness";
|
|
17
|
+
import { formatFreshnessLine, withSavedCopy, type ReportFreshness } from "./pane-functions/freshness";
|
|
17
18
|
import { withSearchHints, type FredSeriesCheck } from "./not-a-ticker";
|
|
18
19
|
import { renderReportCsv, renderReportNdjson, withCsvFooter, type CliReportTables } from "./report-tables";
|
|
19
20
|
import {
|
|
@@ -46,6 +47,12 @@ export interface CliResult<T = unknown> {
|
|
|
46
47
|
* `fear-greed` prints its row alone.
|
|
47
48
|
*/
|
|
48
49
|
exportFreshness?: ReportFreshness;
|
|
50
|
+
/**
|
|
51
|
+
* Why a result that still prints counts as a failure (a report with no
|
|
52
|
+
* data): the command exits 1, and JSON says `ok: false` with this as
|
|
53
|
+
* `error` beside the data, so the envelope and the exit status agree.
|
|
54
|
+
*/
|
|
55
|
+
failure?: CliErrorObject;
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
export interface CliErrorObject {
|
|
@@ -92,6 +99,11 @@ export interface CliResultRenderOptions<T = unknown, Row = Record<string, unknow
|
|
|
92
99
|
* `metadata.rows` in JSON.
|
|
93
100
|
*/
|
|
94
101
|
dateKey?: string;
|
|
102
|
+
/**
|
|
103
|
+
* The row key that splits the rows into series of their own, each windowed
|
|
104
|
+
* apart: with `symbol`, `--tail 5` keeps every symbol's newest five rows.
|
|
105
|
+
*/
|
|
106
|
+
seriesKey?: string;
|
|
95
107
|
/** How many rows to show when neither `--limit` nor `--tail` is given; every row when absent. */
|
|
96
108
|
defaultLimit?: number;
|
|
97
109
|
/**
|
|
@@ -108,10 +120,20 @@ export interface CliResultRenderOptions<T = unknown, Row = Record<string, unknow
|
|
|
108
120
|
exportIdentity?: ExportIdentity | ((row: Row) => ExportIdentity);
|
|
109
121
|
/** What CSV says after the source lines as `# note:` lines: what the rows do not show, such as where a series begins. */
|
|
110
122
|
exportNotes?: readonly string[];
|
|
123
|
+
/**
|
|
124
|
+
* Why a row's figures are empty (`Not a ticker: ZZZZQQ.`, `Chg%: no previous
|
|
125
|
+
* close`), for the `status` column CSV writes after the row's own columns and
|
|
126
|
+
* the `status` field of an NDJSON row; empty for a whole row. The column is
|
|
127
|
+
* there whenever this is, with rows or without, so the header never depends
|
|
128
|
+
* on what loaded. A figure that is no number (NaN) is written empty and,
|
|
129
|
+
* without a reason here, named as `<header>: not available`.
|
|
130
|
+
*/
|
|
131
|
+
exportStatus?: (row: Row) => string | null | undefined;
|
|
111
132
|
}
|
|
112
133
|
|
|
113
|
-
interface CliResultJsonEnvelope<T> extends Omit<CliResult<T>, "freshness" | "exportFreshness"> {
|
|
114
|
-
ok:
|
|
134
|
+
interface CliResultJsonEnvelope<T> extends Omit<CliResult<T>, "freshness" | "exportFreshness" | "failure"> {
|
|
135
|
+
ok: boolean;
|
|
136
|
+
error?: CliErrorObject;
|
|
115
137
|
/** Where the data comes from, as CSV's closing `#` lines say it. */
|
|
116
138
|
source?: ExportSource;
|
|
117
139
|
columns?: Array<Pick<CliResultColumn, "key" | "header" | "align" | "width">>;
|
|
@@ -142,11 +164,28 @@ function rowWindowOptions(options: CliGlobalOptions, renderOptions: Pick<CliResu
|
|
|
142
164
|
function windowed<Row>(
|
|
143
165
|
rows: readonly Row[],
|
|
144
166
|
options: CliGlobalOptions,
|
|
145
|
-
renderOptions: Pick<CliResultRenderOptions, "dateKey" | "defaultLimit">,
|
|
167
|
+
renderOptions: Pick<CliResultRenderOptions, "dateKey" | "defaultLimit" | "seriesKey">,
|
|
146
168
|
): RowWindow<Row> {
|
|
147
|
-
const { dateKey } = renderOptions;
|
|
169
|
+
const { dateKey, seriesKey } = renderOptions;
|
|
148
170
|
const dateOf = dateKey ? (row: Row) => (isPlainObject(row) ? row[dateKey] : undefined) : undefined;
|
|
149
|
-
|
|
171
|
+
const windowOptions = rowWindowOptions(options, renderOptions);
|
|
172
|
+
if (!seriesKey) return windowRows(rows, windowOptions, dateOf);
|
|
173
|
+
const series = new Map<unknown, Row[]>();
|
|
174
|
+
for (const row of rows) {
|
|
175
|
+
const key = isPlainObject(row) ? row[seriesKey] : undefined;
|
|
176
|
+
const group = series.get(key);
|
|
177
|
+
if (group) group.push(row);
|
|
178
|
+
else series.set(key, [row]);
|
|
179
|
+
}
|
|
180
|
+
const windows = [...series.values()].map((group) => windowRows(group, windowOptions, dateOf));
|
|
181
|
+
const count = windowOptions.tail ?? windowOptions.limit;
|
|
182
|
+
return {
|
|
183
|
+
rows: windows.flatMap((window) => window.rows),
|
|
184
|
+
total: rows.length,
|
|
185
|
+
kept: windows.find((window) => window.kept)?.kept ?? null,
|
|
186
|
+
note: windows.some((window) => window.note)
|
|
187
|
+
? `showing the oldest ${count} ${count === 1 ? "row" : "rows"} of each ${seriesKey}; --tail ${count} for the latest` : null,
|
|
188
|
+
};
|
|
150
189
|
}
|
|
151
190
|
|
|
152
191
|
function asRows<T, Row>(data: T, rows?: (data: T) => Row[]): Row[] {
|
|
@@ -199,7 +238,7 @@ function formatTextValue(
|
|
|
199
238
|
depth = 0,
|
|
200
239
|
width: number | null = null,
|
|
201
240
|
): string {
|
|
202
|
-
const missing = context === "record" ? cliStyles.muted("-") : "";
|
|
241
|
+
const missing = context === "record" ? cliPlainEnabled() ? "—" : cliStyles.muted("-") : "";
|
|
203
242
|
if (value == null || value === "") return missing;
|
|
204
243
|
// Times print in UTC with the zone named, never in the host's zone; JSON and CSV keep the raw value.
|
|
205
244
|
if (value instanceof Date) return formatUtcTime(value);
|
|
@@ -284,23 +323,69 @@ function serializeColumns<Row>(columns?: CliResultColumn<Row>[]) {
|
|
|
284
323
|
}));
|
|
285
324
|
}
|
|
286
325
|
|
|
326
|
+
/** A number a spreadsheet cannot read: NaN or an infinity, which exports write empty, never as the word. */
|
|
327
|
+
function isNonFiniteNumber(value: unknown): boolean {
|
|
328
|
+
return typeof value === "number" && !Number.isFinite(value);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* What a row's status cell says: the command's reason, else the figures
|
|
333
|
+
* written empty for being no number. Empty when nothing is missing.
|
|
334
|
+
*/
|
|
335
|
+
function exportStatusText(reason: string | null | undefined, blanked: readonly string[]): string {
|
|
336
|
+
const own = reason?.trim();
|
|
337
|
+
if (own) return own;
|
|
338
|
+
return blanked.length > 0 ? `${blanked.join(", ")}: not available` : "";
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** `status`, or `value_status` beside a column of the table's own named Status. */
|
|
342
|
+
function statusHeader(headers: readonly string[]): string {
|
|
343
|
+
return headers.some((header) => header.trim().toLowerCase() === "status") ? "value_status" : "status";
|
|
344
|
+
}
|
|
345
|
+
|
|
287
346
|
function renderCsv<Row extends Record<string, unknown>>(
|
|
288
347
|
rows: Row[],
|
|
289
348
|
columns?: CliResultColumn<Row>[],
|
|
290
349
|
identity?: (row: Row) => string[],
|
|
350
|
+
status?: (row: Row) => string | null | undefined,
|
|
291
351
|
): string {
|
|
292
352
|
const resolvedColumns = columns && columns.length > 0
|
|
293
353
|
? columns
|
|
294
354
|
: inferColumns(rows as Record<string, unknown>[]) as CliResultColumn<Row>[];
|
|
355
|
+
const headers = resolvedColumns.map((column) => column.header);
|
|
295
356
|
return serializeCsv([
|
|
296
|
-
[...
|
|
297
|
-
...rows.map((row) =>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
357
|
+
[...headers, ...status ? [statusHeader(headers)] : [], ...identity ? EXPORT_IDENTITY_COLUMNS : []],
|
|
358
|
+
...rows.map((row) => {
|
|
359
|
+
const values = resolvedColumns.map((column) => (column.value ? column.value(row) : row[column.key]));
|
|
360
|
+
const blanked = resolvedColumns.flatMap((column, index) => isNonFiniteNumber(values[index]) ? [column.header] : []);
|
|
361
|
+
return [
|
|
362
|
+
...values.map((value) => isNonFiniteNumber(value) ? "" : value),
|
|
363
|
+
...status ? [exportStatusText(status(row), blanked)] : [],
|
|
364
|
+
...identity?.(row) ?? [],
|
|
365
|
+
];
|
|
366
|
+
}),
|
|
301
367
|
]);
|
|
302
368
|
}
|
|
303
369
|
|
|
370
|
+
/**
|
|
371
|
+
* The key an NDJSON row says why its figures are empty under: `status`, or
|
|
372
|
+
* `value_status` beside a field of the row's own that the export writes under
|
|
373
|
+
* that name (an order's status), as CSV's header does.
|
|
374
|
+
*/
|
|
375
|
+
function ndjsonStatusKey(rows: readonly unknown[], columns?: readonly CliResultColumn<never>[]): string {
|
|
376
|
+
const own = columns && columns.length > 0
|
|
377
|
+
? columns.some((column) => column.key === "status")
|
|
378
|
+
: rows.some((row) => isPlainObject(row) && "status" in row);
|
|
379
|
+
return own ? "value_status" : "status";
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/** An NDJSON row: a figure that is no number is null, and the row says why its figures are empty when the command does. */
|
|
383
|
+
function ndjsonRow<Row extends Record<string, unknown>>(row: Row, status: ((row: Row) => string | null | undefined) | undefined, statusKey: string): Record<string, unknown> {
|
|
384
|
+
const blanked = Object.entries(row).flatMap(([key, value]) => isNonFiniteNumber(value) ? [key] : []);
|
|
385
|
+
const own = blanked.length > 0 ? { ...row, ...Object.fromEntries(blanked.map((key) => [key, null])) } : row;
|
|
386
|
+
return status ? { ...own, [statusKey]: exportStatusText(status(row), blanked) || null } : own;
|
|
387
|
+
}
|
|
388
|
+
|
|
304
389
|
function stringField(row: Record<string, unknown>, key: string): string | null {
|
|
305
390
|
const value = row?.[key];
|
|
306
391
|
return typeof value === "string" && value.trim() ? value : null;
|
|
@@ -341,10 +426,11 @@ function renderTextTable<Row extends Record<string, unknown>>(
|
|
|
341
426
|
): string {
|
|
342
427
|
const resolvedColumns = textColumns(rows, columns);
|
|
343
428
|
const cells = rows.map((row) => resolvedColumns.map((column) => formatTextCell(column, row, "table")));
|
|
344
|
-
// A column no row fills is noise in a table; exports keep it
|
|
429
|
+
// A column no row fills is noise in a table; exports keep it, and so does plain output, whose
|
|
430
|
+
// tables keep one shape from query to query with "—" in the empty cells.
|
|
345
431
|
const filled = resolvedColumns
|
|
346
432
|
.map((column, index) => ({ column, index }))
|
|
347
|
-
.filter(({ column, index }) => column.width != null || cells.some((row) => row[index] !== ""));
|
|
433
|
+
.filter(({ column, index }) => cliPlainEnabled() || column.width != null || cells.some((row) => row[index] !== ""));
|
|
348
434
|
const shown = filled.length > 0 ? filled : resolvedColumns.map((column, index) => ({ column, index }));
|
|
349
435
|
return renderTable(
|
|
350
436
|
shown.map(({ column }) => ({
|
|
@@ -388,9 +474,13 @@ function overflowsTerminal<Row extends Record<string, unknown>>(rows: Row[]): bo
|
|
|
388
474
|
return width > terminalWidth;
|
|
389
475
|
}
|
|
390
476
|
|
|
391
|
-
/**
|
|
392
|
-
|
|
393
|
-
|
|
477
|
+
/**
|
|
478
|
+
* The closing source, as-of and status line of a text result, for output
|
|
479
|
+
* printed without `printResult`; `shown` is the data the line is drawn from,
|
|
480
|
+
* which says whether it came from a saved copy.
|
|
481
|
+
*/
|
|
482
|
+
export function cliFreshnessFooter(freshness: ReportFreshness, shown?: unknown): string {
|
|
483
|
+
return cliStyles.muted(wrapToTerminal(formatFreshnessLine(withSavedCopy(freshness, shown))));
|
|
394
484
|
}
|
|
395
485
|
|
|
396
486
|
export function serializeCliResult<T, Row extends Record<string, unknown> = Record<string, unknown>>(
|
|
@@ -398,14 +488,17 @@ export function serializeCliResult<T, Row extends Record<string, unknown> = Reco
|
|
|
398
488
|
options: CliGlobalOptions,
|
|
399
489
|
renderOptions: CliResultRenderOptions<T, Row> = {},
|
|
400
490
|
): string {
|
|
401
|
-
const { freshness, exportFreshness, ...rest } = result;
|
|
402
|
-
|
|
491
|
+
const { freshness: reported, exportFreshness, failure, ...rest } = result;
|
|
492
|
+
// Rows shown from a saved copy, its refresh having failed, say so in place of live or delayed.
|
|
493
|
+
const freshness = reported && withSavedCopy(reported, result.data);
|
|
494
|
+
const cited = freshness ?? (exportFreshness && withSavedCopy(exportFreshness, result.data));
|
|
403
495
|
if (options.format === "json") {
|
|
404
496
|
const columns = serializeColumns(renderOptions.columns);
|
|
405
497
|
const window = Array.isArray(result.data) ? windowed(result.data as unknown[], options, renderOptions) : null;
|
|
406
498
|
const cut = window ? cutMetadata(window) : null;
|
|
407
499
|
const envelope: CliResultJsonEnvelope<T> = {
|
|
408
|
-
ok:
|
|
500
|
+
ok: !failure,
|
|
501
|
+
...(failure ? { error: failure } : {}),
|
|
409
502
|
...rest,
|
|
410
503
|
...(freshness || cut ? { metadata: { ...rest.metadata, ...(freshness ? { freshness } : {}), ...(cut ? { rows: cut } : {}) } } : {}),
|
|
411
504
|
data: window ? window.rows as T : result.data,
|
|
@@ -435,14 +528,18 @@ function serializeCliRows<T, Row extends Record<string, unknown>>(
|
|
|
435
528
|
}
|
|
436
529
|
const window = windowed(asRows(result.data, renderOptions.rows), options, renderOptions);
|
|
437
530
|
const rows = window.rows;
|
|
531
|
+
const status = renderOptions.exportStatus;
|
|
438
532
|
if (options.format === "ndjson") {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
533
|
+
const statusKey = ndjsonStatusKey(rows, renderOptions.columns as readonly CliResultColumn<never>[] | undefined);
|
|
534
|
+
return rows.map((row) => {
|
|
535
|
+
if (!isPlainObject(row)) return JSON.stringify(row);
|
|
536
|
+
const fields = ndjsonRow(row as Row, status, statusKey);
|
|
537
|
+
return JSON.stringify(cited ? { ...fields, ...exportIdentityFields(cited, rowIdentity(row as Row, renderOptions.exportIdentity)) } : fields);
|
|
538
|
+
}).join("\n");
|
|
442
539
|
}
|
|
443
540
|
if (options.format === "csv") {
|
|
444
|
-
if (!cited) return renderCsv(rows as Row[], renderOptions.columns);
|
|
445
|
-
const csv = renderCsv(rows as Row[], renderOptions.columns, (row) => exportIdentityCells(cited, rowIdentity(row, renderOptions.exportIdentity)));
|
|
541
|
+
if (!cited) return renderCsv(rows as Row[], renderOptions.columns, undefined, status);
|
|
542
|
+
const csv = renderCsv(rows as Row[], renderOptions.columns, (row) => exportIdentityCells(cited, rowIdentity(row, renderOptions.exportIdentity)), status);
|
|
446
543
|
return withCsvFooter(csv, [...exportSourceLines(cited), ...(renderOptions.exportNotes ?? []).map((note) => `note: ${note}`)]);
|
|
447
544
|
}
|
|
448
545
|
if (renderOptions.text) {
|