Repository navigation
feat(mongodb): 内嵌 QuickJS 运行时执行 MongoDB shell JavaScript 脚本 - #12661
Open
q396921921 wants to merge 5 commits into
Open
q396921921 wants to merge 5 commits into
q396921921 wants to merge 5 commits into
Conversation
…ntime Add an explicit "Run as MongoDB script" toolbar action for MongoDB tabs that executes multi-statement shell JavaScript (IIFE, var/let, loops, forEach, toArray, print) in a sandboxed QuickJS runtime behind the new `mongo-script` feature. The regular Run button never enters the runtime: parser failures stay failures and only hint at the script action. Safety boundaries (per the review on t8y2#6158): - Every host operation is checked on the backend against the database it actually targets (getSiblingDB, $out/$merge included); unknown connections are treated as production. The client only reports that the user confirmed production writes; client-sent policy flags are ignored. - Cancellation and timeouts report confirmed completed operations versus writes with an unknown outcome, and state that writes are not rolled back. Server-rejected writes (e.g. E11000) are reported as failed, not unknown. Caught write failures are still summarized on success. - Server-side limits: maxRows clamped to [1, 10000], 256 KiB source limit before parsing, 16 MiB per host reply and per result, bounded print output, 10 minute ceiling on the connection query timeout. - A global permit (4 concurrent runtimes) with cancellable, deadline aware queueing; permits are released only after the runtime is dropped. Data fidelity: host replies are canonical Extended JSON document arrays so documents read in a script and written back keep their BSON types and heterogeneous documents gain no null fields. Cursors over the row limit fail loudly instead of truncating, cursor.count() issues countDocuments, insert generates client-side _id values, and update results carry the server's matched/modified/upserted counts. Build and CI: rquickjs is only a dependency on targets where rquickjs-sys ships bindings, the backend exposes a capability flag (Tauri `mongo_script_available`, Web `GET /api/mongo/script-available`) so the button is hidden when the runtime is not compiled in, and `mongo-script` is added to the CI feature set so the runtime tests and clippy run on CI. Typed Extended JSON literals ($numberInt, $numberDouble, $numberDecimal, $date{$numberLong}, $binary, $timestamp, $uuid) now count as bounded filter values in the shell safety check. Fixes t8y2#3050
added 4 commits
October 19, 2026 22:16
…ript # Conflicts: # apps/desktop/src/composables/__tests__/useSqlExecution.spec.ts
This branch has not been deployed
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.







变更说明 / Change Description
MongoDB 标签页新增「作为 MongoDB 脚本执行」工具栏按钮,用内嵌的 QuickJS 运行时执行多语句 shell JavaScript(IIFE、
var/let、循环、forEach、toArray、print等),对应 #3050 里"mongo 下执行 js 脚本报Use MongoDB-specific commands"的诉求。与 #6158 的关系:#6158 用同样的 QuickJS 方案做同一功能,维护者三轮 review 提出了明确的安全边界要求,但该 PR 自 8 月 24 日起没有再推进。我们日常确实需要这个能力,所以在它的基础上重新实现并逐条落实了那三轮 review 的全部意见,另外修掉了自查中发现的一批数据正确性问题。如果 #6158 的作者愿意继续,我们也乐意配合合并到同一个 PR。
对 #6158 三轮 review 意见的处理
mongoExecuteScript全仓库只有这一个调用点db.*操作按它实际写入的库判断(含getSiblingDB、$out/$merge);连接配置查不到时一律按生产库处理。前端只传"用户已确认生产写入",客户端传来的productionDatabase/allowWrites一律忽略getSiblingDB("prod")写被标记为生产的库会被拦截,库内无写入;确认后才写入;请求里伪造旧字段同样拦截catch住的写失败也在成功结果里汇总maxRows要在服务端 clamp 到硬上限[1, 10000](默认 1000),发请求前截断;__dbx_exec直接传大 limit 也绕不过Semaphore(4);排队可取消、受 deadline 约束;名额在 QuickJS Runtime 析构之后才释放自查补充修复
null字段。limit()或分批),cursor.count()改发countDocuments;只有脚本最终返回值(仅用于展示)允许截断并标记 truncated。updateOne/updateMany返回服务端真实的 matched/modified/upserted 计数;insertOne/insertMany在客户端生成_id并返回insertedId(s)。print输出 10000 行 / 4 MB(按 UTF-8 字节计)。rquickjs只在 rquickjs-sys 自带 bindings 的 target 上作为依赖;后端新增能力位(Taurimongo_script_available、WebGET /api/mongo/script-available),运行时未编入时前端隐藏按钮;mongo-script加入ci-rust.mjs的 CI 特性集,让运行时的单测和 clippy 真正在 CI 上跑。$numberInt/$numberDouble/$numberDecimal/$date{$numberLong}/$binary/$timestamp/$uuid这类 Extended JSON 字面量算作有效过滤值(脚本发出的是 canonical EJSON)。这同样作用于普通命令,属于修正误拦截。已知限制(设计取舍,特此说明)
2.0)写回后变成 Int32,JS 区分不了2和2.0,mongosh 行为相同。ISODate("…")的普通字符串在 driver 写入路径会被转成日期,普通命令也是如此,本 PR 未改。aggregate/distinct返回 relaxed EJSON,大于 2^53 的整数在 JS 里会丢精度。runCommand、drop、无过滤条件的删除/更新、$out/$merge一律拦截,需作为单独命令执行;db.getCollectionNames()、db.adminCommand()暂不支持,会给出明确的"not supported in DBX scripts"错误。包体积:macOS arm64 release 版
dbx-web开启mongo-script后增加约 638 KiB(+1.17%)。变更类型 / Change Type
涉及前端 / Frontend Changes
真机截图(web 模式,MongoDB 8.2.3)见下方评论。
验证 / Validation
make check通过 /make checkpasses(connection-types / format / lint / typecheck / vitest 全量)make cargo-check-fast通过 /make cargo-check-fastpasses相关测试通过 / Relevant tests pass
CI 同款 clippy(
ci-rust.mjs clippy workspace full,-D warnings):开启和关闭mongo-script两种特性组合均无警告Rust 单测:
dbx-coremongo_script38/38;dbx-driver-mongodbmongo_shell/mongo_driver全部通过真机集成测试
crates/dbx-core/tests/live_mongodb_script.rs(MongoDB 8.2.3):12/12,覆盖类型往返、异构文档、行数上限、写返回值、重复键分类、catch 后统计、生产库getSiblingDB拦截、取消/超时进度报告手工验证(web 模式):按钮与 tooltip、IIFE 脚本结果、普通运行只提示、超上限报错、取消时的进度报告、生产库确认框、写入统计消息
关联 Issue / Related Issue
Fixes #3050
Related #6158