saropa_drift_advisor 0.3.0 copy "saropa_drift_advisor: ^0.3.0" to clipboard
saropa_drift_advisor: ^0.3.0 copied to clipboard

Debug-only HTTP server that exposes SQLite/Drift table data as JSON and a minimal web viewer. Use from any Drift (or raw SQLite) app via an injectable query callback.

Changelog #

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

pub.devsaropa_drift_advisor

0.3.0 Unreleased #

Package renamed from saropa_drift_viewer to saropa_drift_advisor. Update your pubspec.yaml dependency and replace package:saropa_drift_viewer/ imports with package:saropa_drift_advisor/. All APIs are unchanged.

This release also improves everyday usability with a visual query builder, smarter data formatting, per-table state persistence, and one-click cell copying.

Added #

  • VS Code extension: Isar-to-Drift schema generator — Convert Isar @collection classes to Drift table definitions. Scan the workspace to auto-discover all @collection / @embedded files, or manually pick Dart source files or Isar JSON schema exports. The parser extracts collections, embedded objects, links, indexes, and enum fields. Type mapper converts Isar types to Drift column types, generates foreign key columns for IsarLink, junction tables for IsarLinks, and supports configurable strategies for embedded objects (JSON serialization or column flattening) and enums (ordinal int or name text). Interactive webview panel shows a live preview of the generated Drift code with options to copy, open as editor tab, or save to file. New files: isar-gen/isar-gen-types.ts, isar-gen/isar-parser.ts, isar-gen/isar-json-parser.ts, isar-gen/isar-type-mapper.ts, isar-gen/isar-drift-codegen.ts, isar-gen/isar-gen-panel.ts, isar-gen/isar-gen-html.ts, isar-gen/isar-gen-commands.ts, isar-gen/isar-workspace-scanner.ts.

  • VS Code extension: Pre-launch health check tasks — Register VS Code tasks ("Drift: Health Check", "Drift: Anomaly Scan", "Drift: Index Coverage") that can be wired into launch.json as preLaunchTask to automatically scan for database issues every time you press F5. Tasks use CustomExecution with a Pseudoterminal for formatted terminal output showing connection status, index coverage gaps, and data anomalies with severity icons. Exit code 1 blocks launch when errors are found; warnings pass by default (configurable via driftViewer.tasks.blockOnWarnings). A drift-health problem matcher routes task output to the Problems panel. New API client methods: indexSuggestions(), anomalies(). New files: tasks/drift-task-provider.ts, tasks/health-check-runner.ts.

  • VS Code extension: Peek / Go to Definition for SQL names — Place the cursor on a table or column name inside a raw SQL string in Dart code, then press Alt+F12 (Peek Definition) or F12 (Go to Definition) to jump to the corresponding Drift table class or column getter. Table names are resolved via snake_case-to-PascalCase conversion (e.g. usersclass Users extends Table), and column names match both snake_case and camelCase getters (e.g. created_atget createdAt). Schema metadata is cached from the API with 30-second TTL and auto-cleared on generation changes. New files: definition/drift-definition-provider.ts, definition/sql-string-detector.ts.

  • VS Code extension: CodeLens on Drift table classes — Inline annotations appear above class ... extends Table definitions in Dart files. Each table class shows a live row count from the running server (e.g. "42 rows"), a "View in Drift Viewer" action that opens the webview panel, and a "Run Query" action that executes SELECT * and opens the results as JSON in a side editor. Row counts update automatically via the generation watcher. When the server is offline, lenses show "not connected". Dart PascalCase class names are mapped to SQL snake_case table names with case-insensitive fallback. New files: codelens/drift-codelens-provider.ts, codelens/table-name-mapper.ts. New commands: driftViewer.viewTableInPanel, driftViewer.runTableQuery.

  • VS Code extension: Query Performance Panel in Debug sidebar — Live-updating tree panel appears in the Run & Debug sidebar during active Dart debug sessions when the Drift server is connected. Shows aggregate stats (query count, total/avg duration), slow queries (>500ms with flame icon, >100ms with watch icon), and recent queries in collapsible categories. Click any query to view full SQL with duration, row count, and timestamp in a readonly editor. Auto-refreshes every 3 seconds (configurable via driftViewer.performance.refreshIntervalMs). Panel visibility controlled by compound when clause (inDebugMode && driftViewer.serverConnected) with server health check on debug session start. Toolbar buttons for manual refresh and clearing stats. Concurrency guard prevents overlapping refresh calls. New files: debug/performance-items.ts, debug/performance-tree-provider.ts. New commands: driftViewer.refreshPerformance, driftViewer.clearPerformance, driftViewer.showQueryDetail. New settings: driftViewer.performance.slowThresholdMs, driftViewer.performance.refreshIntervalMs.

  • VS Code extension: Saropa Log Capture integration — Optional bridge to the Saropa Log Capture extension for unified log timeline visibility. When saropa.saropa-log-capture is installed, registers as an integration provider contributing session-start headers (server URL, slow threshold) and session-end summaries (query stats, top slow queries). Connection lifecycle events are written via writeLine(). Supports three verbosity modes via driftViewer.performance.logToCapture setting: off, slow-only (default), and all. No hard dependency — all methods are no-ops when the extension is absent. New file: debug/log-capture-bridge.ts.

  • Web UI: visual query builder — Collapsible "Query builder" section appears below table metadata when viewing any table. Build SQL queries visually with SELECT column checkboxes, type-aware WHERE clause builder (text: contains/equals/starts-with; numeric: comparison operators; blob: null checks only), ORDER BY column/direction picker, and LIMIT control. Live SQL preview updates as selections change. "Run query" executes via POST /api/sql with loading state feedback; "Reset to table view" returns to raw data. Query builder state is persisted per table via localStorage. Column types sourced from existing /api/schema/metadata endpoint — no new server endpoints.

  • Web UI: copy cell to clipboard — Hover over any data table cell to reveal a copy button. Click copies the raw cell value via navigator.clipboard.writeText() with a brief "Copied!" toast notification (auto-dismisses after 1.2s). Works alongside FK navigation links without interference (copy button uses stopPropagation). Copy buttons are preserved during search highlighting.

  • Web UI: filter state caching per table — Table view state (row filter text, pagination limit/offset, display format preference, query builder configuration) is automatically saved to localStorage when switching tables and restored when returning. "Clear state" button in the pagination bar resets all cached state for the current table. localStorage key pattern: drift-viewer-table-state-{tableName}.

  • Web UI: data type display toggle — "Display: Raw / Formatted" dropdown in the table toolbar toggles between raw SQLite values and human-readable formatting. Epoch timestamps (seconds or milliseconds after year 2000) in date-named columns display as ISO 8601 strings. Integer 0/1 in boolean-named columns (is_*, has_*, *_enabled, etc.) display as true/false. Formatted cells show the raw value below in muted text and in the tooltip, both individually copyable. Preference is saved per table as part of filter state caching.


0.2.4 #

This release adds powerful web UI features for exploring and understanding your data: charts, natural language queries, anomaly detection, collaborative sharing, and a query performance monitor.

Added #

  • Collaborative debug sessions — Share the current viewer state (selected table, SQL query, filters, pagination) as a URL. Click the "Share" button in the header, optionally add a note, and the URL is copied to the clipboard. Teammates open the URL to see the exact same view with an info bar and any text annotations. Server stores sessions in memory with 1-hour auto-expiry and a 50-session cap. Three new endpoints: POST /api/session/share, GET /api/session/{id}, POST /api/session/{id}/annotate. Session business logic is extracted into a dedicated DriftDebugSessionStore class (lib/src/drift_debug_session.dart) for clean separation from HTTP handling. Client-side JS is modularized into seven named functions for state capture, clipboard handling, UI restoration, and annotation rendering.
  • Web UI: SQL bookmarks — Save, name, and organize frequently used SQL queries. Bookmarks persist in localStorage and appear in a dropdown below the history selector. Save current query with a custom name, delete selected bookmarks, export all as JSON for version control, and import from JSON with automatic deduplication. Purely client-side — no server changes.
  • Web UI: EXPLAIN QUERY PLAN viewer — "Explain" button next to Run in the SQL runner. Sends POST /api/sql/explain to visualize SQLite's query execution plan as an indented tree. Full table scans are highlighted red with a warning; index lookups are highlighted green. Read-only SQL validation is enforced before explaining. Server handler reuses shared body-reading/validation helper (_readAndValidateSqlBody) to avoid duplication with the Run SQL handler. Run and Explain buttons disable each other during requests to prevent race conditions.
  • Web UI: data charts — Bar, pie, line/time-series, and histogram charts rendered as inline SVG from SQL query results. Chart type selector, X/Y axis pickers, and Render button appear after SQL results. Large datasets (>500 rows) are automatically sampled for SVG performance. Pie chart groups slices below 2% into "Other" and handles single-slice (100%) rendering. All chart colors use CSS variables for theme support. Zero new dependencies (pure inline SVG).
  • Web UI: natural language to SQL — "Ask in English" input converts plain English questions (e.g. "how many users", "latest 5 orders", "average price") to SQL via pattern matching. New GET /api/schema/metadata endpoint provides table names, column names/types, primary keys, and row counts. Schema metadata is cached client-side. Supports count, average, sum, min/max, distinct, latest/oldest, and group-by patterns. Converted SQL is editable before running. No external API keys or dependencies.
  • Web UI: interactive table relationships — Click any foreign key value in the data table to navigate directly to the referenced row in the parent table. New GET /api/table/{name}/fk-meta endpoint returns FK metadata from PRAGMA foreign_key_list. FK columns display an arrow icon (↗) in the header and values render as clickable links (→). Navigation breadcrumb trail tracks the path through tables with a Back button. FK metadata is cached per table. Loading indicator shown during first FK fetch. Data renders as an HTML table (replacing JSON <pre> blocks) in all view modes. Zero new dependencies.
  • Web UI: data anomaly detection — One-click "Scan for anomalies" analyzes all tables for data quality issues: NULL values in nullable columns (with percentage), empty strings in text columns, orphaned foreign key references, duplicate rows, and numeric outliers (max > 10× average). Results display as a severity-coded list (error/warning/info) with colored border indicators. Server-side analysis via GET /api/analytics/anomalies using pure SQL heuristics — no AI/ML dependencies. Table row count is cached per-table to avoid redundant queries. Five modular detection methods keep the handler clean.
  • Web UI: data import (debug only) — Import CSV, JSON, or SQL files into any table during debug sessions via POST /api/import. Opt-in: requires passing the new DriftDebugWriteQuery callback to DriftDebugServer.start(); returns 501 if not configured. Collapsible UI section with table selector, format selector, file picker with preview, and confirmation dialog. Auto-detects format from file extension. Per-row error reporting with partial import support. Import logic extracted into modular DriftDebugImportProcessor class (lib/src/drift_debug_import.dart) and DriftDebugImportResult value class (lib/src/drift_debug_import_result.dart). CSV parser handles quoted fields, escaped quotes, CR+LF line endings, and UTF-8 BOM. Column names are SQL-escaped to prevent injection. Live-refresh triggers immediately after import via generation bump.
  • Web UI: live query performance monitor — Track execution time of every SQL query passing through the debug server. Collapsible "Query performance" panel with Refresh and Clear buttons. GET /api/analytics/performance returns summary stats (total queries, total/avg duration), slow queries (>100ms, top 20 sorted by duration), query patterns (grouped by first 60 chars, top 20 by total time), and recent queries (last 50). DELETE /api/analytics/performance clears the timing buffer. Query callback is wrapped with Stopwatch at start() so all queries (including internal ones) are timed automatically. 500-entry ring buffer with automatic eviction. Color-coded durations in the UI (red >100ms, orange >50ms). Auto-fetches data on first expand. QueryTiming data class in server_types.dart; route constants in server_constants.dart; JS in html_content.dart.

Fixed #

  • Mixin corruption — Removed JavaScript initPerformance code that was accidentally inserted into the DriftDebugServer.start() Dart parameter list across multiple prior commits, causing analyzer errors.

0.2.3 #

We're focusing on backend tooling and documentation in this release.

Fixed #

  • CI workflow: trigger branch changed from master to main to match the repository default branch; PRs and pushes now correctly run CI.
  • Static analysis: added curly braces to three bare if-body statements in drift_debug_server_io.dart (lint: always_put_control_body_on_new_line).
  • Static analysis: wrapped three doc-comment URL paths containing angle brackets in backticks to prevent HTML interpretation (lint: unintended_html_in_doc_comment).
  • Dependency lower bounds: bumped webview_flutter from ^4.12.0 to ^4.13.0 so the minimum version includes onSslAuthError/SslAuthError (added in 4.13.0), fixing the downgrade analysis failure.

Changed #

  • Added a banner image to the README
  • Publish tooling: scripts/publish.py now checks whether the package already exists on pub.dev before offering a local dart pub publish for first-time publishes.
  • CI workflow: removed the one-time "Add uploader" workflow and inline step; maintainers can use dart pub uploader or the pub.dev UI directly when needed.
  • Tooling docs: clarified in analysis_options.yaml comments that saropa_lints 6.x does not provide analysis_options.yaml as an include target.
  • Upgraded saropa_lints from 6.2.2 to 8.0.7 (professional tier: 1649 → 1666 rules enabled).

0.2.2 #

Housekeeping release to re-publish with corrected package metadata.

Changed #

  • Bump for release.

0.2.1 #

In this release we only updated the CHANGELOG link to point at the repo until the package was live on pub.dev.

Changed #

  • CHANGELOG: link to GitHub until package was on pub.dev.

0.2.0 #

In this release we focused on making the viewer more useful day to day: the table view now refreshes when data changes, you can run read-only SQL from the browser, and you can protect the viewer with a token or Basic auth when using a dev tunnel. We added a schema diagram, CSV export, snapshot/time travel, and a Flutter overlay so you can open the viewer from your app.

Fixed #

  • Lint and validation — DriftDebugServer singleton uses nullable backing field + getter (no late) for avoid_late_keyword. POST /api/sql checks Content-Type before decoding; body decode/validation in _parseSqlBody (require_content_type_validation, require_api_response_validation). WebView route: buildWebViewRoute uses Uri.tryParse and allows only http/https; invalid URLs show a localized error screen with overflow-safe text. Load errors in WebView logged via _logLoadError in debug. POST /api/sql rejects non-application/json Content-Type with 400; unit test added. Bug reports filed for linter false positives (safe area, named routes, WebView sandbox, extension type conflict, API validation flow) and moved to saropa_lints/bugs/history.

  • Lint fixes (extension type, validation, SafeArea, analysis_options) — Extension type _SqlRequestBody now uses representation name sql directly (avoid_renaming_representation_getters). _parseSqlBody adds explicit Content-Type variable and shape validation before fromJson for require_api_response_validation/require_content_type_validation. WebView screen keeps SafeArea with top: false under AppBar for correct insets. Rules disabled in analysis_options.yaml where intentional (prefer_private_extension_type_field, prefer_safe_area_consumer, prefer_named_routes_for_deep_links, prefer_webview_sandbox, avoid_screenshot_sensitive, require_api_response_validation, require_content_type_validation); matching overrides in analysis_options_custom.yaml.

  • Project rule compliance — Removed all // ignore and // ignore_for_file comments from the codebase. Lint rules are disabled only via analysis_options_custom.yaml (e.g. avoid_platform_specific_imports, prefer_correct_throws, avoid_unnecessary_to_list, prefer_extension_over_utility_class, unnecessary_await_in_return). Preserved return await in the extension for async stack traces.

Added #

  • Code review (comments and tests) — Expanded concise code comments across the library (architecture, platform export, stub, error logger, extension, server implementation). Added unit tests: POST /api/sql rejects wrong Content-Type (400); read-only SQL edge cases (multi-statement, WITH...INSERT) (400, read-only). Flutter overlay: localized semantic label for floating button icon (_sDriftViewer).

  • Defensive coding — Param validation: port must be 0..65535 (ArgumentError otherwise); Basic auth requires both user and password or neither. Query result normalization: null or non-List/non-Map rows from the query callback are handled safely (empty list / skip invalid rows). Offset query param capped at 2M to avoid unbounded queries. Example app: init timeout (30s) with clear error message; AppDatabase.create() wrapped in try/catch with context; ViewerInitResult documented. New tests: port/auth validation, query throws → 500, query returns null → 200 empty list, unknown table → 400, limit/offset edge cases, empty getDatabaseBytes → 200, ErrorLogger empty prefix/message, extension non-List/bad row.data → 500, viewer_status errorMessage and running+url null.

  • Example app — Flutter example in example/ (Drift DB + viewer); run from repo root with flutter run -d windows, then open http://127.0.0.1:8642. See example/README.md.

  • DevTools / IDE integration — Run Task → "Open Drift Viewer" (.vscode/tasks.json) opens the viewer in the browser; optional minimal VS Code/Cursor extension in extension/ with one command. Web UI supports URL hash #TableName so links open with that table selected.

  • Live refresh — Table view updates automatically when data changes (e.g. after the app writes). Server runs a lightweight change check every 2s (table row-count fingerprint); clients long-poll GET /api/generation?since=N and refetch table list and current table when the generation changes. UI shows "● Live" in the header and "Updating…" briefly during refresh. No manual refresh needed.

  • Secure dev tunnel — Optional authToken and/or HTTP Basic (basicAuthUser / basicAuthPassword) so the viewer can be used over ngrok or port forwarding without exposing an open server. When authToken is set, requests must include Authorization: Bearer <token> or ?token=<token>. The web UI injects the token when opened with a valid ?token= so all API calls are authenticated. See README “Secure dev tunnel”.

  • Read-only SQL runner — In the web UI, a collapsible “Run SQL (read-only)” section: run ad-hoc SELECT (or WITH ... SELECT) from the browser. Only read-only SQL is accepted; INSERT/UPDATE/DELETE and DDL are rejected. Templates (e.g. “SELECT * FROM table LIMIT 10”), table and column dropdowns (autofill from GET /api/tables and GET /api/table/<name>/columns), result as table or JSON, loading states (“Running…”, “Loading…” for columns), and race-safe column fetch. POST /api/sql with body {"sql": "SELECT ..."} returns {"rows": [...]}. GET /api/table/<name>/columns returns a JSON array of column names for autofill.

  • SQL runner: query history — The web UI remembers the last ~20 successful SQL runner queries in browser localStorage and offers a “History” dropdown to reuse them.

  • Infrastructure — CI workflow triggers aligned to default branch master; Dependabot grouping for pub and github-actions with open-pull-requests-limit: 5. Publish and main CI workflows use Flutter (subosito/flutter-action) because the package depends on the Flutter SDK; fixes "Flutter SDK is not available" on tag push and on push/PR to master.

  • Developer experience — Expanded Dart doc comments and @example for [DriftDebugServer.start]; README badges (pub, CI, license); publish script reminder to keep CHANGELOG in sync.

  • Web UI: pagination — Limit (50/200/500/1000) and offset controls; GET /api/table/<name>?limit=&offset=.

  • Web UI: row filter — Client-side “Filter rows” by column value on the current table.

  • Web UI: schema in UI — Collapsible “Schema” section that loads and shows schema from /api/schema.

  • Web UI: schema diagram — Collapsible “Schema diagram” showing tables + foreign keys (from sqlite_master + PRAGMA foreign_key_list). Click a table to open it.

  • Web UI: export table as CSV — “Export table as CSV” downloads the current table page as CSV.

  • Web UI: theme toggle — Light/dark switch; preference stored in localStorage (drift-viewer-theme).

  • Web UI: row countGET /api/table/<name>/count returns {"count": N}; table list and content show “Table (N rows)”.

  • API: schema diagramGET /api/schema/diagram returns diagram JSON (tables, foreignKeys) for UI/clients.

  • Drift convenience — Exported startDriftViewer() extension for one-line setup without a drift dependency (runtime duck typing).

  • loopbackOnly — Option to bind to 127.0.0.1 only instead of 0.0.0.0.

  • corsOrigin — Option to set, restrict, or disable the Access-Control-Allow-Origin header ('*', specific origin, or null).

  • GET /api/health — Returns {"ok": true} for scripts or readiness probes.

  • DriftDebugServer.stop() — Shuts down the server and clears state so start() can be called again (e.g. tests, graceful teardown).

  • Export schema (no data)GET /api/schema returns a downloadable schema.sql with CREATE statements only. UI link: "Export schema (no data)".

  • Export full dump (schema + data)GET /api/dump returns a downloadable dump.sql with schema plus INSERTs for every row. UI link with "Preparing dump…" loading feedback; may be slow for large DBs.

  • Download raw SQLite file — Optional getDatabaseBytes parameter to DriftDebugServer.start (e.g. () => File(dbPath).readAsBytes()). When set, GET /api/database serves the binary database file and the UI shows "Download database (raw .sqlite)" for opening in DB Browser or similar. When not set, the endpoint returns 501 with an explanatory message.

  • Snapshot / time travel — Optional in-memory snapshot of table state. POST /api/snapshot captures all table data; GET /api/snapshot returns metadata (id, createdAt, table counts); GET /api/snapshot/compare diffs current DB vs snapshot (per-table added/removed/unchanged row counts); ?format=download returns the diff as snapshot-diff.json; DELETE /api/snapshot clears the snapshot. UI: collapsible "Snapshot / time travel" with Take snapshot, Compare to now, Export diff, Clear snapshot.

  • Database diff — Optional queryCompare parameter to DriftDebugServer.start. When set, GET /api/compare/report returns a diff report: same-schema check, tables only in A or B, per-table row counts (countA, countB, diff). ?format=download returns diff-report.json. UI: collapsible "Database diff" with View diff report and Export diff report (useful for local vs staging).

  • Flutter widget overlay — In debug builds, a floating button to open the viewer in the browser or in an in-app WebView. Import package:saropa_drift_viewer/flutter.dart and wrap your app with DriftViewerOverlay(child: MaterialApp(...)), or place DriftViewerFloatingButton() in your own Stack. Button only visible when kDebugMode is true and the server is running. Popup menu: "Open in browser" (url_launcher) or "Open in WebView" (full-screen WebView). Example app updated to use the overlay.

0.1.0 #

In this release we shipped the first version: a debug-only HTTP server that exposes your SQLite or Drift tables as JSON and a small web UI. It works with any SQLite executor, so you don’t need Drift as a dependency.

Fixed #

  • analysis_options.yaml: Removed invalid include: package:saropa_lints/analysis_options.yaml (that URI is not provided by saropa_lints; use custom_lint CLI for its rules).
  • DriftDebugErrorLogger: Replaced print with stderr.writeln in log/error fallbacks to satisfy avoid_print; added defensive try/catch to logCallback so logging never throws.

Added #

  • DriftDebugServer: Debug-only HTTP server that exposes SQLite/Drift table data as JSON and a minimal web UI.
  • DriftDebugQuery typedef: callback that runs SQL and returns rows as list of maps.
  • DriftDebugOnLog / DriftDebugOnError: optional logging callbacks.
  • No dependency on Drift — works with any SQLite executor via the query callback.
  • Default port 8642; configurable port, enabled flag, and optional log/error handlers.
1
likes
150
points
1.88k
downloads

Documentation

API reference

Publisher

verified publishersaropa.com

Weekly Downloads

Debug-only HTTP server that exposes SQLite/Drift table data as JSON and a minimal web viewer. Use from any Drift (or raw SQLite) app via an injectable query callback.

Homepage
Repository (GitHub)
View/report issues
Contributing

License

MIT (license)

Dependencies

collection, crypto, flutter, intl, meta, url_launcher, webview_flutter, webview_flutter_android

More

Packages that depend on saropa_drift_advisor