Skip to content

feat(editor): the web editor's run decision as one shared function (#2204, part 1) - #2240

Merged
cevheri merged 8 commits into
mainfrom
feat/2204-statement-analysis
Nov 4, 2026
Merged

cevheri merged 8 commits into
mainfrom
feat/2204-statement-analysis

Conversation

@cevheri

@cevheri cevheri commented Nov 4, 2026

Copy link
Copy Markdown
Member

Part 1 of #2204: the web editor's run decision as one shared function, with no behaviour change. The route that serves it to the mobile client comes in part 2.

  • analyzeStatement in src/lib/editor/statement-analysis.ts answers nothing, refuse, run or confirm, with the statement, its range, the route, the unreadable flag and the typed confirmation, the way the web editor decides today.
  • The pieces it composes now have a single implementation each: hasUnreadableRun (the gate and the safety dialog), runnableTarget and editorLanguageOf (moved out of the VS Code child), runsAsScript and typedConfirmationExpected (the web hook and the dialog).
  • A parity test runs every case of section 5 of S-06: POST /api/db/statement/analyze, the web editor's run decision for clients outside the browser #2204 through both analyzeStatement and the web composition. The known divergences are pinned: comment-only and blank targets, an unclosed block comment target, and the etcd typed name on a connection with no name.
  • docs/BACKLOG.md gets U200 (the comment-only divergence) and U201 (VS Code does not apply the per-engine refusal, so Redis GET a\nDEL b runs there without asking).

The web hook, the dialog and the extension's query/target tests pass unedited. Locally: the full gate set, build:lib and attw, coverage at 100%, and the extension's unit, coverage and node integration legs.

…afety dialog

The gate asked whether a run never closes or a line comment holds a lone carriage return before it read a keyword, and the safety dialog asked the same two questions again to say why it asks. hasUnreadableRun in src/lib/sql/dangerous-query.ts is that predicate, and both now call it, so they cannot drift apart. No behaviour changes; tests/unit/sql/dangerous-query.test.ts is the gate module's own unit file.

Part of #2204.
…ableTarget

query/target answered an empty statement when the run target held no code under the sql editor language, with a countCodeStatements check written in the child. runnableTarget in src/lib/sql/run-target.ts is runTarget with that rule, so the statement analysis can share it, and the child calls it. Every query/target answer stays as it was: the extension's query/target unit tests pass unchanged.

Part of #2204.
…language

The child read the editor language of a provider's text with a local editorLanguageOf over resolveTabType and editorLanguageForTabType. It now lives beside them in src/lib/editor/tab-language.ts, so the statement analysis reads the same answer, and connection/open and query/target call it there.

Part of #2204.
…confirmation value

Whether a run takes /api/db/multi-query was written inline in use-query-execution.ts, and the text a typed confirmation is compared with was a private function of QuerySafetyDialog. Both move to the new src/lib/editor/statement-analysis.ts as runsAsScript and typedConfirmationExpected, which hold no component, and the hook and the dialog call them there. The hook keeps every other routing condition and its "sql" default while the provider's metadata loads, so the route of every run is unchanged.

Part of #2204.
…function

analyzeStatement in src/lib/editor/statement-analysis.ts takes the editor's text, selection and caret, the connection's type, capabilities and name, and answers nothing, refuse, run or confirm, with the exact statement to send, its range, its route, the unreadable notice and the typed value. It composes runnableTarget, statementRefusal, runsAsScript, isDangerousQuery, vocabularyTypedConfirmation, typedConfirmationExpected and hasUnreadableRun in the web editor's order, opens no connection, and is the decision the statement analysis route of #2204 will answer.

Its test drives the 62 non-HTTP acceptance cases of #2204 on each engine's real capabilities, built without connecting, and a parity test holds each one to the web editor's own composition of the same parts. The one divergence, a target that holds no code, which the web sends and the analysis answers as nothing to run, is recorded as docs/BACKLOG.md U200.

Part of #2204.
…l gap

docs/VSCODE_EXTENSION.md names runnableTarget and editorLanguageOf as what the child calls, and section 8 says that Run in the extension does not apply the connection type's refusal, so a statement the web editor refuses before sending reaches query/run without a question and only the provider's guard stops it, recorded as docs/BACKLOG.md U201. docs/ARCHITECTURE.md says which functions analyzeStatement composes and which of them each caller uses.

Part of #2204.
…ctIsSql

The routing condition use-query-execution.ts kept in a local dialectIsSql is now runsAsScript, so the comments in the hook and Redis provider tests and the paragraph in docs/providers/redis.md that named the local now name the function. No behaviour changes.

Part of #2204.
… editor does

The embedded store reads its text as SQL, so an unclosed literal there is unreadable; a new row pins that answer.
A caret target that is an unclosed block comment holds no code, and the web asks about it before sending it, so the recorded divergence now admits that confirm, with two rows and U200 saying so.
At a name-typed confirmation on a connection with no name, the web's dialog keeps Proceed disabled rather than refusing, and the test now composes that state instead of copying the refusal.
@codecov

codecov Bot commented Nov 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

sonarqubecloud Bot commented Nov 4, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant