Conversation
Strangler-fig migration starts. New Vite + React 18 + TS strict app under client-next/, mounted by Express at /v3 behind PGLENS_V3 flag while legacy client/ stays default. Ports six screens against the existing API: landing, sidebar (connections + schemas + tables search), table viewer (TanStack Table + react-virtual + page/sort), schema viz (@xyflow/react with FK edges), connection dialog (URL + params modes, create + edit), and query runner (lazy Monaco editor, Cmd/Ctrl+Enter). Adds POST /api/query as the advanced-mode escape hatch. Stack: shadcn/ui + Tailwind, TanStack Query + Router, Zustand for active-connection state (persisted), Zod for all API response validation.
Implements roadmap 3.3. Connection passwords move out of plaintext
~/.pglens/connections.json into the OS keychain via keytar; existing
records are migrated transparently on first boot and the file becomes
metadata-only. The server binds 127.0.0.1 (override with PGLENS_BIND)
and gates every route behind a per-install token stored at
~/.pglens/token; the CLI prints a token-bearing URL and the server sets
an HttpOnly cookie + 302s to a clean path on first visit. Replaces the
`[a-zA-Z0-9_]+` identifier regex with a proper double-quote escaper so
mixed-case and Unicode identifiers work. Standardizes error responses
to `{ error: { code, message, hint? } }` with a legacy `errorMessage`
mirror for the v2 client. All API routes pick up Zod request validation
(body / query / params). Adds pino daily-rotating JSON logs at
~/.pglens/logs/pglens.log.N plus `pglens logs`, `pglens token`, and
`pglens url` CLI commands. v3 client sends the cookie via
credentials:'same-origin' and parses the new envelope (with fallback to
the legacy string shape).
Implements roadmap §3.4. Adds three test tiers and a GitHub Actions matrix. Backend uses node:test with 33 unit tests covering identifier escaping, connection-URL parsing, error envelope, request validation, and the token middleware — overall 87% line / 75% branch coverage, well above the 60% bar set in the roadmap. Frontend uses Vitest + jsdom + Testing Library with 11 unit tests covering the ApiError envelope parser and the persisted Zustand store (75% coverage on lib + store). Integration tests boot the real Express server against a postgres:16 service container (docker-compose.test.yml locally, GitHub services in CI) and exercise the full auth + connect + masked URL + mixed-case identifier flow — env-gated via PGLENS_TEST_DB_URL so they skip cleanly without docker. Playwright drives the v3 landing through a real `pglens serve` to verify the token redirect and 401 envelope end-to-end. CI runs the unit suite on Node 18/20/22 across ubuntu/macos/windows, with integration + e2e gated to ubuntu. Refactors auth.js to export createTokenMiddleware(expected) so the middleware is testable without touching the on-disk token file. </parameter>
Closes Phase 0 §3.5 of the roadmap. The vanilla `client/` directory is deleted and the React/TS app is now served at `/`; the legacy `/v3/*` path 301-redirects to `/` so existing bookmarks still work, and the package + CLI banner are bumped to 3.0.0. Reaches feature parity with 2.3.0 in the new stack: multi-tab workspace, theme switcher (light/dark/system, persisted, OS-preference-aware), Cmd+K spotlight search, per-connection Edit/Disconnect menu, schema PATCH on dropdown change, landing page connections grid, streaming backup export with a bottom-right progress toast (current table + bytes written + cancel), themed scrollbars (color-scheme + WebKit pseudo-elements), and an Asimovian wordmark font on the logo. Schema visualizer rewritten on top of @dagrejs/dagre with LR/TB direction toggle, hover spotlight, smoothstep edges + arrows, theme-synced MiniMap that highlights the hovered table, and an export menu that ships SVG + Mermaid ER (copy to clipboard or download .mmd). Edit Connection dialog now prefills both URL and Parameters modes; the server treats a "***" password as "keep the existing keychain entry" so name/SSL/schema can be saved without retyping the password. Table viewer gets a top progress bar, inline "updating…" spinner, and dimmed grid during refetch, and no longer briefly renders the previous table's rows when switching tables (placeholderData is now scoped by tableName). Misc UI fixes: custom Select chevron centered against the input's full height, per-page dropdown width + label tightened, MiniMap visible in both themes with explicit background + border. CHANGELOG.md updated with the full 3.0.0 entry under Added / Changed / Removed / Security.
Table reads ran 4 sequential round-trips per page (metadata, PK, count, data), ~2.3s/page on remote DBs where each query costs a full RTT. Cache column metadata per (connection, schema, table) with a 30s TTL so pagination/sort skips the catalog introspection, derive the primary key from cached columns (drops a query), and run COUNT and the data fetch concurrently. Cache-hit page time drops to ~one RTT (~0.95s). Invalidate metadata on /query (DDL), /import, and /disconnect so schema changes don't serve stale columns past the TTL.
Add a Spinner/Loading component backed by unicode-spinner (subscribe
mode, braille variant) and use it for every loading indicator: table
rows, connections, tables, schema, editor, plus Run/Export/Connect
button pending states. Replaces the lucide Loader2 spinners. Generic
"Loading…" messages made specific (e.g. "Loading {table} rows…",
"Running query…", "Exporting backup…").
- TLS: sslMode `require` now verifies certs (rejectUnauthorized: true), closing a MITM gap; `prefer`/default stay lenient for self-signed dev DBs - add loopback Host-header allowlist as DNS-rebinding defense - fix protocol-relative open redirect in the /v3 handler - sanitize export filename to block Content-Disposition header injection - stop returning err.message on 500s (logged server-side, generic to client) - run /query SET search_path + the user SQL on one reserved connection so the search_path can't land on a different pooled backend - remove the unsupported /import route (unbounded body / memory DoS) - npm audit fix: resolve path-to-regexp ReDoS + qs DoS (0 vulnerabilities)
cmd.exe does not expand the `test/unit/*.test.js` glob and node 18/20 do not glob `--test` arguments, so Windows runners matched no files and exited 1. Enumerate the test dir explicitly via scripts/run-tests.js.
The published package must ship the built React frontend that the server serves from client-next/dist, and nothing else. - Add package.json "files" allowlist (bin, src, client-next/dist, README) so npm stops shipping TS source, coverage, lockfiles, and tests. - Add prepack to build client-next before packing so dist is fresh. - Add client-next/.npmignore so npm ignores that dir's .gitignore (which excludes dist); the root files allowlist still restricts to dist. - Delete .github/workflows/release.yml: it built electron .dmg/.exe via nonexistent dist:<platform> scripts; pglens is a CLI npm package.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.