atoo-studio 0.0.1 → 0.0.2
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/LICENSE +21 -0
- package/README.github.md +322 -0
- package/README.md +112 -0
- package/README.npm.md +112 -0
- package/bin/atoo-studio.js +90 -0
- package/dist/src/agents/claude-code-terminal/adapter.d.ts +42 -0
- package/dist/src/agents/claude-code-terminal/adapter.js +166 -0
- package/dist/src/agents/claude-code-terminal/index.d.ts +13 -0
- package/dist/src/agents/claude-code-terminal/index.js +45 -0
- package/dist/src/agents/claude-code-terminal/spawner.d.ts +9 -0
- package/dist/src/agents/claude-code-terminal/spawner.js +37 -0
- package/dist/src/agents/claude-code-terminal-chatro/adapter.d.ts +51 -0
- package/dist/src/agents/claude-code-terminal-chatro/adapter.js +301 -0
- package/dist/src/agents/claude-code-terminal-chatro/index.d.ts +13 -0
- package/dist/src/agents/claude-code-terminal-chatro/index.js +45 -0
- package/dist/src/agents/claude-code-terminal-chatro/jsonl-watcher.d.ts +67 -0
- package/dist/src/agents/claude-code-terminal-chatro/jsonl-watcher.js +431 -0
- package/dist/src/agents/claude-code-terminal-chatro/spawner.d.ts +9 -0
- package/dist/src/agents/claude-code-terminal-chatro/spawner.js +37 -0
- package/dist/src/agents/codex-terminal/adapter.d.ts +40 -0
- package/dist/src/agents/codex-terminal/adapter.js +160 -0
- package/dist/src/agents/codex-terminal/index.d.ts +13 -0
- package/dist/src/agents/codex-terminal/index.js +47 -0
- package/dist/src/agents/codex-terminal/spawner.d.ts +9 -0
- package/dist/src/agents/codex-terminal/spawner.js +56 -0
- package/dist/src/agents/codex-terminal-chatro/adapter.d.ts +58 -0
- package/dist/src/agents/codex-terminal-chatro/adapter.js +266 -0
- package/dist/src/agents/codex-terminal-chatro/index.d.ts +13 -0
- package/dist/src/agents/codex-terminal-chatro/index.js +50 -0
- package/dist/src/agents/codex-terminal-chatro/jsonl-watcher.d.ts +36 -0
- package/dist/src/agents/codex-terminal-chatro/jsonl-watcher.js +205 -0
- package/dist/src/agents/codex-terminal-chatro/spawner.d.ts +9 -0
- package/dist/src/agents/codex-terminal-chatro/spawner.js +57 -0
- package/dist/src/agents/lib/chain-builder.d.ts +21 -0
- package/dist/src/agents/lib/chain-builder.js +139 -0
- package/dist/src/agents/lib/claude/fs-sessions.d.ts +31 -0
- package/dist/src/agents/lib/claude/fs-sessions.js +329 -0
- package/dist/src/agents/lib/claude/jsonl-writer.d.ts +32 -0
- package/dist/src/agents/lib/claude/jsonl-writer.js +342 -0
- package/dist/src/agents/lib/claude/workspace-trust.d.ts +1 -0
- package/dist/src/agents/lib/claude/workspace-trust.js +29 -0
- package/dist/src/agents/lib/codex/fs-sessions.d.ts +34 -0
- package/dist/src/agents/lib/codex/fs-sessions.js +255 -0
- package/dist/src/agents/lib/codex/jsonl-mapper.d.ts +11 -0
- package/dist/src/agents/lib/codex/jsonl-mapper.js +154 -0
- package/dist/src/agents/lib/codex/jsonl-writer.d.ts +8 -0
- package/dist/src/agents/lib/codex/jsonl-writer.js +440 -0
- package/dist/src/agents/lib/fs-tracking.d.ts +36 -0
- package/dist/src/agents/lib/fs-tracking.js +109 -0
- package/dist/src/agents/lib/pty-activity-tracker.d.ts +37 -0
- package/dist/src/agents/lib/pty-activity-tracker.js +105 -0
- package/dist/src/agents/lib/session-id-utils.d.ts +46 -0
- package/dist/src/agents/lib/session-id-utils.js +147 -0
- package/dist/src/agents/lib/session-precreate.d.ts +17 -0
- package/dist/src/agents/lib/session-precreate.js +177 -0
- package/dist/src/agents/registry.d.ts +72 -0
- package/dist/src/agents/registry.js +337 -0
- package/dist/src/agents/types.d.ts +135 -0
- package/dist/src/agents/types.js +1 -0
- package/dist/src/auth/crypto-key.d.ts +6 -0
- package/dist/src/auth/crypto-key.js +45 -0
- package/dist/src/auth/middleware.d.ts +18 -0
- package/dist/src/auth/middleware.js +54 -0
- package/dist/src/auth/password.d.ts +2 -0
- package/dist/src/auth/password.js +12 -0
- package/dist/src/auth/session.d.ts +10 -0
- package/dist/src/auth/session.js +33 -0
- package/dist/src/auth/totp.d.ts +12 -0
- package/dist/src/auth/totp.js +61 -0
- package/dist/src/auth/webauthn.d.ts +6 -0
- package/dist/src/auth/webauthn.js +117 -0
- package/dist/src/config.d.ts +10 -0
- package/dist/src/config.js +16 -0
- package/dist/src/database/connection-manager.d.ts +25 -0
- package/dist/src/database/connection-manager.js +211 -0
- package/dist/src/database/discovery/container.d.ts +6 -0
- package/dist/src/database/discovery/container.js +226 -0
- package/dist/src/database/discovery/env-parser.d.ts +9 -0
- package/dist/src/database/discovery/env-parser.js +525 -0
- package/dist/src/database/discovery/local-files.d.ts +6 -0
- package/dist/src/database/discovery/local-files.js +58 -0
- package/dist/src/database/discovery/port-scan.d.ts +7 -0
- package/dist/src/database/discovery/port-scan.js +61 -0
- package/dist/src/database/drivers/cassandra.d.ts +12 -0
- package/dist/src/database/drivers/cassandra.js +91 -0
- package/dist/src/database/drivers/clickhouse.d.ts +11 -0
- package/dist/src/database/drivers/clickhouse.js +127 -0
- package/dist/src/database/drivers/elasticsearch.d.ts +12 -0
- package/dist/src/database/drivers/elasticsearch.js +169 -0
- package/dist/src/database/drivers/influxdb.d.ts +14 -0
- package/dist/src/database/drivers/influxdb.js +194 -0
- package/dist/src/database/drivers/memcached.d.ts +11 -0
- package/dist/src/database/drivers/memcached.js +117 -0
- package/dist/src/database/drivers/mongodb.d.ts +12 -0
- package/dist/src/database/drivers/mongodb.js +128 -0
- package/dist/src/database/drivers/mysql.d.ts +11 -0
- package/dist/src/database/drivers/mysql.js +112 -0
- package/dist/src/database/drivers/neo4j.d.ts +11 -0
- package/dist/src/database/drivers/neo4j.js +158 -0
- package/dist/src/database/drivers/postgresql.d.ts +11 -0
- package/dist/src/database/drivers/postgresql.js +133 -0
- package/dist/src/database/drivers/redis.d.ts +11 -0
- package/dist/src/database/drivers/redis.js +91 -0
- package/dist/src/database/drivers/sqlite.d.ts +10 -0
- package/dist/src/database/drivers/sqlite.js +100 -0
- package/dist/src/database/query-stream.d.ts +5 -0
- package/dist/src/database/query-stream.js +75 -0
- package/dist/src/database/types.d.ts +71 -0
- package/dist/src/database/types.js +1 -0
- package/dist/src/events/index.d.ts +3 -0
- package/dist/src/events/index.js +3 -0
- package/dist/src/events/types.d.ts +214 -0
- package/dist/src/events/types.js +22 -0
- package/dist/src/events/wire.d.ts +114 -0
- package/dist/src/events/wire.js +296 -0
- package/dist/src/fs-monitor-types.d.ts +24 -0
- package/dist/src/fs-monitor-types.js +1 -0
- package/dist/src/fs-monitor.d.ts +80 -0
- package/dist/src/fs-monitor.js +637 -0
- package/dist/src/handlers/auth.d.ts +1 -0
- package/dist/src/handlers/auth.js +170 -0
- package/dist/src/handlers/changes.d.ts +1 -0
- package/dist/src/handlers/changes.js +203 -0
- package/dist/src/handlers/containers.d.ts +12 -0
- package/dist/src/handlers/containers.js +379 -0
- package/dist/src/handlers/databases.d.ts +3 -0
- package/dist/src/handlers/databases.js +327 -0
- package/dist/src/handlers/environments.d.ts +3 -0
- package/dist/src/handlers/environments.js +286 -0
- package/dist/src/handlers/github.d.ts +1 -0
- package/dist/src/handlers/github.js +153 -0
- package/dist/src/handlers/projects.d.ts +1 -0
- package/dist/src/handlers/projects.js +895 -0
- package/dist/src/handlers/ssh.d.ts +1 -0
- package/dist/src/handlers/ssh.js +162 -0
- package/dist/src/handlers/users.d.ts +1 -0
- package/dist/src/handlers/users.js +195 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +228 -0
- package/dist/src/mcp/config.d.ts +32 -0
- package/dist/src/mcp/config.js +227 -0
- package/dist/src/mcp/server.d.ts +1 -0
- package/dist/src/mcp/server.js +574 -0
- package/dist/src/serial/cuse-device.d.ts +19 -0
- package/dist/src/serial/cuse-device.js +260 -0
- package/dist/src/serial/manager.d.ts +63 -0
- package/dist/src/serial/manager.js +206 -0
- package/dist/src/serial/pty-pair.d.ts +16 -0
- package/dist/src/serial/pty-pair.js +68 -0
- package/dist/src/services/fs-browser.d.ts +14 -0
- package/dist/src/services/fs-browser.js +98 -0
- package/dist/src/services/git-ops.d.ts +78 -0
- package/dist/src/services/git-ops.js +288 -0
- package/dist/src/services/github-ops.d.ts +104 -0
- package/dist/src/services/github-ops.js +192 -0
- package/dist/src/services/obfuscation.d.ts +2 -0
- package/dist/src/services/obfuscation.js +16 -0
- package/dist/src/services/preview/headless-backend.d.ts +62 -0
- package/dist/src/services/preview/headless-backend.js +698 -0
- package/dist/src/services/preview/injected-scripts.d.ts +9 -0
- package/dist/src/services/preview/injected-scripts.js +232 -0
- package/dist/src/services/preview/preview-backend.d.ts +92 -0
- package/dist/src/services/preview/preview-backend.js +15 -0
- package/dist/src/services/preview/universal-setter.d.ts +7 -0
- package/dist/src/services/preview/universal-setter.js +46 -0
- package/dist/src/services/preview-manager.d.ts +50 -0
- package/dist/src/services/preview-manager.js +216 -0
- package/dist/src/services/project-watcher.d.ts +6 -0
- package/dist/src/services/project-watcher.js +307 -0
- package/dist/src/services/remote-fs-browser.d.ts +11 -0
- package/dist/src/services/remote-fs-browser.js +50 -0
- package/dist/src/services/remote-git-ops.d.ts +71 -0
- package/dist/src/services/remote-git-ops.js +215 -0
- package/dist/src/services/session-search.d.ts +56 -0
- package/dist/src/services/session-search.js +303 -0
- package/dist/src/services/ssh-manager.d.ts +44 -0
- package/dist/src/services/ssh-manager.js +359 -0
- package/dist/src/session-writer.d.ts +9 -0
- package/dist/src/session-writer.js +66 -0
- package/dist/src/spawner.d.ts +56 -0
- package/dist/src/spawner.js +135 -0
- package/dist/src/state/db.d.ts +214 -0
- package/dist/src/state/db.js +897 -0
- package/dist/src/state/store.d.ts +37 -0
- package/dist/src/state/store.js +108 -0
- package/dist/src/state/types.d.ts +13 -0
- package/dist/src/state/types.js +1 -0
- package/dist/src/web/devtools-proxy.d.ts +7 -0
- package/dist/src/web/devtools-proxy.js +176 -0
- package/dist/src/web/port-proxy.d.ts +15 -0
- package/dist/src/web/port-proxy.js +124 -0
- package/dist/src/web/preview-ws.d.ts +5 -0
- package/dist/src/web/preview-ws.js +207 -0
- package/dist/src/web/server.d.ts +6 -0
- package/dist/src/web/server.js +1694 -0
- package/dist/src/ws/agent-ws.d.ts +5 -0
- package/dist/src/ws/agent-ws.js +93 -0
- package/frontend/dist/assets/_basePickBy-B-LibQ4-.js +1 -0
- package/frontend/dist/assets/_baseUniq-CprifHap.js +1 -0
- package/frontend/dist/assets/_createAssigner-ByDUqGii.js +1 -0
- package/frontend/dist/assets/abap-DuT-3z4x.js +1 -0
- package/frontend/dist/assets/addon-fit-CxQet2ja.js +1 -0
- package/frontend/dist/assets/addon-web-links-D_jRkPIl.js +1 -0
- package/frontend/dist/assets/apex-B-em86xX.js +1 -0
- package/frontend/dist/assets/api-SUPuHhSY.js +2 -0
- package/frontend/dist/assets/arc-Z0_eVteO.js +1 -0
- package/frontend/dist/assets/architecture-PBZL5I3N-hvVXGhqd.js +1 -0
- package/frontend/dist/assets/architectureDiagram-2XIMDMQ5-DiHPxX4j.js +36 -0
- package/frontend/dist/assets/array-CwG8vNfn.js +1 -0
- package/frontend/dist/assets/auth-store-R7eW5SVu.js +1 -0
- package/frontend/dist/assets/azcli-Bg9wQloi.js +1 -0
- package/frontend/dist/assets/bat-BM46z99L.js +1 -0
- package/frontend/dist/assets/bicep-DcBsJUfh.js +2 -0
- package/frontend/dist/assets/blockDiagram-WCTKOSBZ-C40u_hLo.js +132 -0
- package/frontend/dist/assets/c4Diagram-IC4MRINW-Ct7LjWFQ.js +10 -0
- package/frontend/dist/assets/cameligo-zw7JTtim.js +1 -0
- package/frontend/dist/assets/channel-ClCsE6HN.js +1 -0
- package/frontend/dist/assets/chunk-4BX2VUAB-zZ6P90VO.js +1 -0
- package/frontend/dist/assets/chunk-55IACEB6-DXllTDQl.js +1 -0
- package/frontend/dist/assets/chunk-7E7YKBS2-7zRaOLjj.js +1 -0
- package/frontend/dist/assets/chunk-7R4GIKGN-Csst1274.js +80 -0
- package/frontend/dist/assets/chunk-C72U2L5F-_JbQPbLN.js +1 -0
- package/frontend/dist/assets/chunk-CFjPhJqf.js +1 -0
- package/frontend/dist/assets/chunk-EGIJ26TM-B--aFyPw.js +1 -0
- package/frontend/dist/assets/chunk-FMBD7UC4-DVR34RNb.js +15 -0
- package/frontend/dist/assets/chunk-GEFDOKGD-CnmN6cC8.js +2 -0
- package/frontend/dist/assets/chunk-JSJVCQXG-CWxHBzeJ.js +1 -0
- package/frontend/dist/assets/chunk-KX2RTZJC-DkRk56s7.js +1 -0
- package/frontend/dist/assets/chunk-KYZI473N-DCCsG2dK.js +53 -0
- package/frontend/dist/assets/chunk-L3YUKLVL-C-DkZTMr.js +1 -0
- package/frontend/dist/assets/chunk-MX3YWQON-OUdzv5sZ.js +1 -0
- package/frontend/dist/assets/chunk-NQ4KR5QH-Bpu9FsM7.js +220 -0
- package/frontend/dist/assets/chunk-O4XLMI2P-BMLK6_ib.js +7 -0
- package/frontend/dist/assets/chunk-OZEHJAEY-CNNiJtG0.js +1 -0
- package/frontend/dist/assets/chunk-PQ6SQG4A-evVHD3KM.js +1 -0
- package/frontend/dist/assets/chunk-PU5JKC2W-DPFTYuvl.js +70 -0
- package/frontend/dist/assets/chunk-QZHKN3VN-JRdddPvu.js +1 -0
- package/frontend/dist/assets/chunk-R5LLSJPH-CHQzVVOV.js +1 -0
- package/frontend/dist/assets/chunk-WL4C6EOR-BNFU6IIi.js +189 -0
- package/frontend/dist/assets/chunk-XIRO2GV7-98T93G85.js +1 -0
- package/frontend/dist/assets/chunk-XZSTWKYB-BcW3cyNp.js +94 -0
- package/frontend/dist/assets/chunk-YBOYWFTD-BgKO1qAJ.js +1 -0
- package/frontend/dist/assets/classDiagram-VBA2DB6C-DikXzgcD.js +1 -0
- package/frontend/dist/assets/classDiagram-v2-RAHNMMFH-D7E3tQUK.js +1 -0
- package/frontend/dist/assets/clojure-FspFoNNQ.js +1 -0
- package/frontend/dist/assets/clone-mOXuZa7C.js +1 -0
- package/frontend/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- package/frontend/dist/assets/coffee-13n8Bk2W.js +1 -0
- package/frontend/dist/assets/cose-bilkent-S5V4N54A-zUOWQqLe.js +1 -0
- package/frontend/dist/assets/cpp-BVm2xGEs.js +1 -0
- package/frontend/dist/assets/csharp-D2kAWmUm.js +1 -0
- package/frontend/dist/assets/csp-Ezvgpf0e.js +1 -0
- package/frontend/dist/assets/css-CYxRwcFy.js +3 -0
- package/frontend/dist/assets/css.worker-Cd5h-ZOL.js +89 -0
- package/frontend/dist/assets/cssMode-CrXej49V.js +1 -0
- package/frontend/dist/assets/cypher-jg3SGErc.js +1 -0
- package/frontend/dist/assets/cytoscape.esm-kyyvzxNV.js +321 -0
- package/frontend/dist/assets/dagre-DH4bgZO7.js +1 -0
- package/frontend/dist/assets/dagre-KLK3FWXG-DNSqDkwT.js +4 -0
- package/frontend/dist/assets/dart-179jqhK4.js +1 -0
- package/frontend/dist/assets/defaultLocale-Dda4OpKy.js +1 -0
- package/frontend/dist/assets/diagram-E7M64L7V-RqPNT5Vs.js +24 -0
- package/frontend/dist/assets/diagram-IFDJBPK2-B-5NRyaE.js +43 -0
- package/frontend/dist/assets/diagram-P4PSJMXO-BrP69Hk0.js +24 -0
- package/frontend/dist/assets/dist-CU_Nb1G5.js +1 -0
- package/frontend/dist/assets/dockerfile-CIAtSGxS.js +1 -0
- package/frontend/dist/assets/ecl-CGVKfDxD.js +1 -0
- package/frontend/dist/assets/editor-Br_kD0ds.css +1 -0
- package/frontend/dist/assets/editor.api2-YXkDn0Gm.js +872 -0
- package/frontend/dist/assets/editor.main-fBaXZjJ0.js +6 -0
- package/frontend/dist/assets/elixir-BZ-6w0y3.js +1 -0
- package/frontend/dist/assets/erDiagram-INFDFZHY-BYiB9NYg.js +70 -0
- package/frontend/dist/assets/flow9-CVuOjTMv.js +1 -0
- package/frontend/dist/assets/flowDiagram-PKNHOUZH-Cwq47rsR.js +162 -0
- package/frontend/dist/assets/freemarker2-DM-pztJU.js +3 -0
- package/frontend/dist/assets/fsharp-q0pGJYr6.js +1 -0
- package/frontend/dist/assets/ganttDiagram-A5KZAMGK-Dnx3szD9.js +292 -0
- package/frontend/dist/assets/gitGraph-HDMCJU4V-COlTQ7bA.js +1 -0
- package/frontend/dist/assets/gitGraphDiagram-K3NZZRJ6-BaUxboNc.js +65 -0
- package/frontend/dist/assets/go-dzSPfdEO.js +1 -0
- package/frontend/dist/assets/graphlib-kEFlkt3U.js +1 -0
- package/frontend/dist/assets/graphql-CG4OUoEV.js +1 -0
- package/frontend/dist/assets/handlebars-BbK53Vec.js +1 -0
- package/frontend/dist/assets/hcl-Cy14JPk3.js +1 -0
- package/frontend/dist/assets/html-DYtTQNOG.js +1 -0
- package/frontend/dist/assets/html.worker-BjVEKLoU.js +502 -0
- package/frontend/dist/assets/htmlMode-C6GTouth.js +1 -0
- package/frontend/dist/assets/index-DMLxes_u.js +157 -0
- package/frontend/dist/assets/index-DmzeqkB1.css +1 -0
- package/frontend/dist/assets/info-3K5VOQVL-DBtHyA4C.js +1 -0
- package/frontend/dist/assets/infoDiagram-LFFYTUFH-yBXLgMPI.js +2 -0
- package/frontend/dist/assets/ini-Pbg8HGVD.js +1 -0
- package/frontend/dist/assets/init-D6KNwrax.js +1 -0
- package/frontend/dist/assets/ishikawaDiagram-PHBUUO56-Bld4two_.js +70 -0
- package/frontend/dist/assets/java-BmVu6Qrl.js +1 -0
- package/frontend/dist/assets/javascript-PbfQEdcJ.js +1 -0
- package/frontend/dist/assets/journeyDiagram-4ABVD52K-4HyMd4R2.js +139 -0
- package/frontend/dist/assets/json.worker-DqU5Wxnl.js +58 -0
- package/frontend/dist/assets/jsonMode-CASsGppE.js +7 -0
- package/frontend/dist/assets/julia-3cGnieBq.js +1 -0
- package/frontend/dist/assets/kanban-definition-K7BYSVSG-DpgsZmpG.js +89 -0
- package/frontend/dist/assets/katex-CEw3x5bf.js +261 -0
- package/frontend/dist/assets/kotlin-BuWkVcfV.js +1 -0
- package/frontend/dist/assets/less-CJ_VPy2C.js +2 -0
- package/frontend/dist/assets/lexon-BygAuZPu.js +1 -0
- package/frontend/dist/assets/line-CA_wh_TY.js +1 -0
- package/frontend/dist/assets/linear-BAcLW45z.js +1 -0
- package/frontend/dist/assets/liquid-kz84dle6.js +1 -0
- package/frontend/dist/assets/lspLanguageFeatures-C7hAHFn1.js +4 -0
- package/frontend/dist/assets/lua-C8Xs3dCx.js +1 -0
- package/frontend/dist/assets/m3-DTJeKBk4.js +1 -0
- package/frontend/dist/assets/markdown-QCgx8JqZ.js +1 -0
- package/frontend/dist/assets/math-D0YcMJAn.js +1 -0
- package/frontend/dist/assets/mdx-yRw0ap-E.js +1 -0
- package/frontend/dist/assets/mermaid-parser.core-DAeTodBQ.js +4 -0
- package/frontend/dist/assets/mindmap-definition-YRQLILUH-CoNlFyVl.js +68 -0
- package/frontend/dist/assets/mips-DopWaYgE.js +1 -0
- package/frontend/dist/assets/monaco.contribution-DeY0Qei-.js +2 -0
- package/frontend/dist/assets/msdax-BDis4ARV.js +1 -0
- package/frontend/dist/assets/mysql-BV6MLsOI.js +1 -0
- package/frontend/dist/assets/objective-c-B1UuzKs6.js +1 -0
- package/frontend/dist/assets/ordinal-jM7S0YHN.js +1 -0
- package/frontend/dist/assets/packet-RMMSAZCW-FF6-Tmai.js +1 -0
- package/frontend/dist/assets/pascal-BkvESCrc.js +1 -0
- package/frontend/dist/assets/pascaligo-lTy0kZYr.js +1 -0
- package/frontend/dist/assets/path-DNPd7Py7.js +1 -0
- package/frontend/dist/assets/perl-CrtUPXLV.js +1 -0
- package/frontend/dist/assets/pgsql-B9IbNWx2.js +1 -0
- package/frontend/dist/assets/php-CXvQBY2p.js +1 -0
- package/frontend/dist/assets/pie-UPGHQEXC-CFvXY2o-.js +1 -0
- package/frontend/dist/assets/pieDiagram-SKSYHLDU-CM_hbCcn.js +30 -0
- package/frontend/dist/assets/pla-DxBxuqWu.js +1 -0
- package/frontend/dist/assets/postiats-OkEuT5YF.js +1 -0
- package/frontend/dist/assets/powerquery-CMx5Tq4K.js +1 -0
- package/frontend/dist/assets/powershell-CstRxrEc.js +1 -0
- package/frontend/dist/assets/preload-helper-D4M6sveU.js +1 -0
- package/frontend/dist/assets/protobuf-Bx0Z-uRj.js +2 -0
- package/frontend/dist/assets/pug--W8vanWl.js +1 -0
- package/frontend/dist/assets/python-DA0rnlw3.js +1 -0
- package/frontend/dist/assets/qsharp-CRtr0YbN.js +1 -0
- package/frontend/dist/assets/quadrantDiagram-337W2JSQ-B3n3IUhC.js +7 -0
- package/frontend/dist/assets/r-C6E1d6iv.js +1 -0
- package/frontend/dist/assets/radar-KQ55EAFF-MPZu7SdX.js +1 -0
- package/frontend/dist/assets/razor-yd73uata.js +1 -0
- package/frontend/dist/assets/redis-Dx13voP3.js +1 -0
- package/frontend/dist/assets/redshift-D66HwlyV.js +1 -0
- package/frontend/dist/assets/requirementDiagram-Z7DCOOCP-CorP7L7F.js +73 -0
- package/frontend/dist/assets/restructuredtext-DQT2NKJ2.js +1 -0
- package/frontend/dist/assets/rough.esm-DxAX5Vpo.js +1 -0
- package/frontend/dist/assets/ruby-iFXI8hwH.js +1 -0
- package/frontend/dist/assets/rust-CSKiei34.js +1 -0
- package/frontend/dist/assets/sankeyDiagram-WA2Y5GQK-RDx6Bd-B.js +10 -0
- package/frontend/dist/assets/sb-Bo3ttdP2.js +1 -0
- package/frontend/dist/assets/scala-BC1D-Nxp.js +1 -0
- package/frontend/dist/assets/scheme-Z4OAo4Lv.js +1 -0
- package/frontend/dist/assets/scss-BvrdPs6B.js +3 -0
- package/frontend/dist/assets/sequenceDiagram-2WXFIKYE-JMqJSFq6.js +145 -0
- package/frontend/dist/assets/shell-Bh_aCyF-.js +1 -0
- package/frontend/dist/assets/solidity-CWHj6tSe.js +1 -0
- package/frontend/dist/assets/sophia-raoNtKtm.js +1 -0
- package/frontend/dist/assets/sparql-XzmoGnue.js +1 -0
- package/frontend/dist/assets/sql-BD0i9Gvg.js +1 -0
- package/frontend/dist/assets/src-Bn-kKzs7.js +1 -0
- package/frontend/dist/assets/st-DtVKyms6.js +1 -0
- package/frontend/dist/assets/stateDiagram-RAJIS63D-CgFfENdy.js +1 -0
- package/frontend/dist/assets/stateDiagram-v2-FVOUBMTO-C4Hh2P-U.js +1 -0
- package/frontend/dist/assets/swift--UZs77wT.js +1 -0
- package/frontend/dist/assets/systemverilog-CDnBSWUd.js +1 -0
- package/frontend/dist/assets/tcl-DdCEuTHZ.js +1 -0
- package/frontend/dist/assets/timeline-definition-YZTLITO2-BnatPBR5.js +61 -0
- package/frontend/dist/assets/treemap-KZPCXAKY-qb1Pl9la.js +1 -0
- package/frontend/dist/assets/ts.worker-DyPAEIuH.js +67719 -0
- package/frontend/dist/assets/tsMode-iuvyEpyO.js +11 -0
- package/frontend/dist/assets/twig-SSL-Altf.js +1 -0
- package/frontend/dist/assets/typescript-17918Hud.js +1 -0
- package/frontend/dist/assets/typespec-BT7S0ETg.js +1 -0
- package/frontend/dist/assets/vb-CrIgucua.js +1 -0
- package/frontend/dist/assets/vennDiagram-LZ73GAT5-DygS4Zzd.js +34 -0
- package/frontend/dist/assets/wgsl-BeKc3oEp.js +298 -0
- package/frontend/dist/assets/workers-DTfwKVoM.js +1 -0
- package/frontend/dist/assets/xml-CBMr_Wbw.js +1 -0
- package/frontend/dist/assets/xterm-BrP-ENHg.css +1 -0
- package/frontend/dist/assets/xterm-CBX2m0YM.js +36 -0
- package/frontend/dist/assets/xychartDiagram-JWTSCODW-D6wY1Jwd.js +7 -0
- package/frontend/dist/assets/yaml-CTjCH7Bv.js +1 -0
- package/frontend/dist/fonts/inter-300.ttf +0 -0
- package/frontend/dist/fonts/inter-400.ttf +0 -0
- package/frontend/dist/fonts/inter-500.ttf +0 -0
- package/frontend/dist/fonts/inter-600.ttf +0 -0
- package/frontend/dist/fonts/inter-700.ttf +0 -0
- package/frontend/dist/index.html +49 -0
- package/frontend/dist/logo_192x192.png +0 -0
- package/frontend/dist/logo_32x32.png +0 -0
- package/frontend/dist/logo_512x512.png +0 -0
- package/frontend/dist/logo_64x64.png +0 -0
- package/frontend/dist/logobg_192x192.png +0 -0
- package/frontend/dist/logobg_512x512.png +0 -0
- package/frontend/dist/logobg_64x64.png +0 -0
- package/frontend/dist/manifest.json +25 -0
- package/frontend/dist/sw.js +22 -0
- package/package.json +74 -7
- package/preload/Makefile +12 -0
- package/preload/atoo-studio-preload.c +647 -0
- package/preload/atoo-studio-preload.so +0 -0
- package/setup-cuse.sh +260 -0
- package/setup.sh +81 -0
- package/src/serial/native/binding.gyp +10 -0
- package/src/serial/native/pty_pair.c +222 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import memjs from 'memjs';
|
|
2
|
+
export class MemcachedDriver {
|
|
3
|
+
client = null;
|
|
4
|
+
async connect(params) {
|
|
5
|
+
const host = params.host || 'localhost';
|
|
6
|
+
const port = params.port || 11211;
|
|
7
|
+
this.client = memjs.Client.create(`${host}:${port}`);
|
|
8
|
+
}
|
|
9
|
+
async disconnect() {
|
|
10
|
+
if (this.client) {
|
|
11
|
+
this.client.close();
|
|
12
|
+
this.client = null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
isConnected() {
|
|
16
|
+
return this.client !== null;
|
|
17
|
+
}
|
|
18
|
+
async query(command, limit = 100) {
|
|
19
|
+
if (!this.client)
|
|
20
|
+
throw new Error('Not connected');
|
|
21
|
+
const start = Date.now();
|
|
22
|
+
const parts = command.trim().split(/\s+/);
|
|
23
|
+
const cmd = parts[0].toLowerCase();
|
|
24
|
+
let columns = [];
|
|
25
|
+
let rows = [];
|
|
26
|
+
switch (cmd) {
|
|
27
|
+
case 'get': {
|
|
28
|
+
if (!parts[1])
|
|
29
|
+
throw new Error('Usage: get <key>');
|
|
30
|
+
const key = parts[1];
|
|
31
|
+
const result = await this.client.get(key);
|
|
32
|
+
columns = ['key', 'value'];
|
|
33
|
+
const value = result.value ? result.value.toString() : '(nil)';
|
|
34
|
+
rows = [{ key, value }];
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
case 'set': {
|
|
38
|
+
if (!parts[1] || !parts[2])
|
|
39
|
+
throw new Error('Usage: set <key> <value>');
|
|
40
|
+
const key = parts[1];
|
|
41
|
+
const value = parts.slice(2).join(' ');
|
|
42
|
+
await this.client.set(key, value);
|
|
43
|
+
columns = ['result'];
|
|
44
|
+
rows = [{ result: 'STORED' }];
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case 'delete': {
|
|
48
|
+
if (!parts[1])
|
|
49
|
+
throw new Error('Usage: delete <key>');
|
|
50
|
+
const key = parts[1];
|
|
51
|
+
const success = await this.client.delete(key);
|
|
52
|
+
columns = ['result'];
|
|
53
|
+
rows = [{ result: success ? 'DELETED' : 'NOT_FOUND' }];
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'stats': {
|
|
57
|
+
const stats = await new Promise((resolve, reject) => {
|
|
58
|
+
this.client.stats((err, _server, stats) => {
|
|
59
|
+
if (err)
|
|
60
|
+
return reject(err);
|
|
61
|
+
resolve(stats || {});
|
|
62
|
+
});
|
|
63
|
+
}).catch(() => ({}));
|
|
64
|
+
columns = ['stat', 'value'];
|
|
65
|
+
for (const [stat, value] of Object.entries(stats)) {
|
|
66
|
+
rows.push({ stat, value: String(value) });
|
|
67
|
+
}
|
|
68
|
+
rows = rows.slice(0, limit);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'flush_all': {
|
|
72
|
+
await new Promise((resolve) => {
|
|
73
|
+
this.client.flush(() => resolve());
|
|
74
|
+
});
|
|
75
|
+
columns = ['result'];
|
|
76
|
+
rows = [{ result: 'OK' }];
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
default:
|
|
80
|
+
throw new Error(`Unsupported command: ${cmd}. Supported: get, set, delete, stats, flush_all`);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
columns,
|
|
84
|
+
rows,
|
|
85
|
+
row_count: rows.length,
|
|
86
|
+
execution_time_ms: Date.now() - start,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async getTables() {
|
|
90
|
+
if (!this.client)
|
|
91
|
+
throw new Error('Not connected');
|
|
92
|
+
try {
|
|
93
|
+
const stats = await new Promise((resolve, reject) => {
|
|
94
|
+
this.client.stats((err, _server, s) => {
|
|
95
|
+
if (err)
|
|
96
|
+
return reject(err);
|
|
97
|
+
resolve(s || {});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
return [{ name: 'memcached', type: 'server', row_count: Object.keys(stats).length }];
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return [{ name: 'memcached', type: 'server' }];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async describeTable(_table) {
|
|
107
|
+
return {
|
|
108
|
+
table: _table,
|
|
109
|
+
columns: [],
|
|
110
|
+
indexes: [],
|
|
111
|
+
foreign_keys: [],
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
async getDatabases() {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ConnectionParams, DatabaseDriver, QueryResult, TableInfo, SchemaInfo } from '../types.js';
|
|
2
|
+
export declare class MongoDBDriver implements DatabaseDriver {
|
|
3
|
+
private client;
|
|
4
|
+
private db;
|
|
5
|
+
connect(params: ConnectionParams): Promise<void>;
|
|
6
|
+
disconnect(): Promise<void>;
|
|
7
|
+
isConnected(): boolean;
|
|
8
|
+
query(queryStr: string, limit?: number): Promise<QueryResult>;
|
|
9
|
+
getTables(): Promise<TableInfo[]>;
|
|
10
|
+
describeTable(collection: string): Promise<SchemaInfo>;
|
|
11
|
+
getDatabases(): Promise<string[]>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { MongoClient } from 'mongodb';
|
|
2
|
+
export class MongoDBDriver {
|
|
3
|
+
client = null;
|
|
4
|
+
db = null;
|
|
5
|
+
async connect(params) {
|
|
6
|
+
const uri = params.connection_string ||
|
|
7
|
+
`mongodb://${params.username ? `${params.username}:${params.password}@` : ''}${params.host || 'localhost'}:${params.port || 27017}/${params.database || 'test'}`;
|
|
8
|
+
this.client = new MongoClient(uri);
|
|
9
|
+
await this.client.connect();
|
|
10
|
+
this.db = this.client.db(params.database || 'test');
|
|
11
|
+
}
|
|
12
|
+
async disconnect() {
|
|
13
|
+
if (this.client) {
|
|
14
|
+
await this.client.close();
|
|
15
|
+
this.client = null;
|
|
16
|
+
this.db = null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
isConnected() {
|
|
20
|
+
return this.client !== null;
|
|
21
|
+
}
|
|
22
|
+
async query(queryStr, limit = 100) {
|
|
23
|
+
if (!this.db)
|
|
24
|
+
throw new Error('Not connected');
|
|
25
|
+
const start = Date.now();
|
|
26
|
+
// Parse simple query format: collection.find({...}) or collection.aggregate([...])
|
|
27
|
+
const match = queryStr.match(/^(\w+)\.(find|aggregate|count|countDocuments|distinct)\((.*)?\)$/s);
|
|
28
|
+
if (!match) {
|
|
29
|
+
throw new Error('Query format: collection.find({filter}) or collection.aggregate([pipeline])');
|
|
30
|
+
}
|
|
31
|
+
const [, collName, method, argsStr] = match;
|
|
32
|
+
const collection = this.db.collection(collName);
|
|
33
|
+
let args;
|
|
34
|
+
try {
|
|
35
|
+
args = argsStr ? JSON.parse(argsStr) : {};
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
args = {};
|
|
39
|
+
}
|
|
40
|
+
let rows;
|
|
41
|
+
if (method === 'find') {
|
|
42
|
+
rows = await collection.find(args).limit(limit).toArray();
|
|
43
|
+
}
|
|
44
|
+
else if (method === 'aggregate') {
|
|
45
|
+
rows = await collection.aggregate(Array.isArray(args) ? args : [args]).toArray();
|
|
46
|
+
}
|
|
47
|
+
else if (method === 'countDocuments' || method === 'count') {
|
|
48
|
+
const count = await collection.countDocuments(args);
|
|
49
|
+
rows = [{ count }];
|
|
50
|
+
}
|
|
51
|
+
else if (method === 'distinct') {
|
|
52
|
+
const values = await collection.distinct(typeof args === 'string' ? args : Object.keys(args)[0] || '_id');
|
|
53
|
+
rows = values.map(v => ({ value: v }));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw new Error(`Unsupported method: ${method}`);
|
|
57
|
+
}
|
|
58
|
+
const elapsed = Date.now() - start;
|
|
59
|
+
// Serialize ObjectIds
|
|
60
|
+
const serialized = rows.map(r => {
|
|
61
|
+
const obj = {};
|
|
62
|
+
for (const [k, v] of Object.entries(r)) {
|
|
63
|
+
obj[k] = v && typeof v === 'object' && v.toString ? v.toString() : v;
|
|
64
|
+
}
|
|
65
|
+
return obj;
|
|
66
|
+
});
|
|
67
|
+
const columns = serialized.length > 0
|
|
68
|
+
? [...new Set(serialized.flatMap(r => Object.keys(r)))]
|
|
69
|
+
: [];
|
|
70
|
+
return {
|
|
71
|
+
columns,
|
|
72
|
+
rows: serialized.slice(0, limit),
|
|
73
|
+
row_count: serialized.length,
|
|
74
|
+
execution_time_ms: elapsed,
|
|
75
|
+
truncated: rows.length >= limit,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async getTables() {
|
|
79
|
+
if (!this.db)
|
|
80
|
+
throw new Error('Not connected');
|
|
81
|
+
const collections = await this.db.listCollections().toArray();
|
|
82
|
+
const tables = [];
|
|
83
|
+
for (const coll of collections) {
|
|
84
|
+
let row_count;
|
|
85
|
+
try {
|
|
86
|
+
row_count = await this.db.collection(coll.name).estimatedDocumentCount();
|
|
87
|
+
}
|
|
88
|
+
catch { }
|
|
89
|
+
tables.push({ name: coll.name, type: 'collection', row_count });
|
|
90
|
+
}
|
|
91
|
+
return tables.sort((a, b) => a.name.localeCompare(b.name));
|
|
92
|
+
}
|
|
93
|
+
async describeTable(collection) {
|
|
94
|
+
if (!this.db)
|
|
95
|
+
throw new Error('Not connected');
|
|
96
|
+
// Sample documents to infer schema
|
|
97
|
+
const sample = await this.db.collection(collection).find().limit(50).toArray();
|
|
98
|
+
const fieldTypes = new Map();
|
|
99
|
+
for (const doc of sample) {
|
|
100
|
+
for (const [key, value] of Object.entries(doc)) {
|
|
101
|
+
if (!fieldTypes.has(key))
|
|
102
|
+
fieldTypes.set(key, new Set());
|
|
103
|
+
const t = value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value;
|
|
104
|
+
fieldTypes.get(key).add(t);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const columns = [...fieldTypes.entries()].map(([name, types]) => ({
|
|
108
|
+
name,
|
|
109
|
+
type: [...types].join(' | '),
|
|
110
|
+
nullable: types.has('null') || types.has('undefined'),
|
|
111
|
+
primary_key: name === '_id',
|
|
112
|
+
}));
|
|
113
|
+
// Get indexes
|
|
114
|
+
const indexList = await this.db.collection(collection).indexes();
|
|
115
|
+
const indexes = indexList.map(idx => ({
|
|
116
|
+
name: idx.name || '',
|
|
117
|
+
columns: Object.keys(idx.key || {}),
|
|
118
|
+
unique: !!idx.unique,
|
|
119
|
+
}));
|
|
120
|
+
return { table: collection, columns, indexes, foreign_keys: [] };
|
|
121
|
+
}
|
|
122
|
+
async getDatabases() {
|
|
123
|
+
if (!this.client)
|
|
124
|
+
throw new Error('Not connected');
|
|
125
|
+
const result = await this.client.db('admin').admin().listDatabases();
|
|
126
|
+
return result.databases.map(d => d.name);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConnectionParams, DatabaseDriver, QueryResult, TableInfo, SchemaInfo } from '../types.js';
|
|
2
|
+
export declare class MySQLDriver implements DatabaseDriver {
|
|
3
|
+
private pool;
|
|
4
|
+
connect(params: ConnectionParams): Promise<void>;
|
|
5
|
+
disconnect(): Promise<void>;
|
|
6
|
+
isConnected(): boolean;
|
|
7
|
+
query(sql: string, limit?: number): Promise<QueryResult>;
|
|
8
|
+
getTables(): Promise<TableInfo[]>;
|
|
9
|
+
describeTable(table: string): Promise<SchemaInfo>;
|
|
10
|
+
getDatabases(): Promise<string[]>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import mysql from 'mysql2/promise';
|
|
2
|
+
export class MySQLDriver {
|
|
3
|
+
pool = null;
|
|
4
|
+
async connect(params) {
|
|
5
|
+
if (params.connection_string) {
|
|
6
|
+
this.pool = mysql.createPool(params.connection_string);
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
this.pool = mysql.createPool({
|
|
10
|
+
host: params.host || 'localhost',
|
|
11
|
+
port: params.port || 3306,
|
|
12
|
+
user: params.username || 'root',
|
|
13
|
+
password: params.password || '',
|
|
14
|
+
database: params.database,
|
|
15
|
+
connectionLimit: 5,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
// Test connection
|
|
19
|
+
const conn = await this.pool.getConnection();
|
|
20
|
+
conn.release();
|
|
21
|
+
}
|
|
22
|
+
async disconnect() {
|
|
23
|
+
if (this.pool) {
|
|
24
|
+
await this.pool.end();
|
|
25
|
+
this.pool = null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
isConnected() {
|
|
29
|
+
return this.pool !== null;
|
|
30
|
+
}
|
|
31
|
+
async query(sql, limit = 100) {
|
|
32
|
+
if (!this.pool)
|
|
33
|
+
throw new Error('Not connected');
|
|
34
|
+
const start = Date.now();
|
|
35
|
+
const [rows, fields] = await this.pool.query(sql);
|
|
36
|
+
const elapsed = Date.now() - start;
|
|
37
|
+
const rowArr = Array.isArray(rows) ? rows : [];
|
|
38
|
+
const columns = fields && Array.isArray(fields)
|
|
39
|
+
? fields.map((f) => f.name)
|
|
40
|
+
: (rowArr.length > 0 ? Object.keys(rowArr[0]) : []);
|
|
41
|
+
const truncated = rowArr.length > limit;
|
|
42
|
+
return {
|
|
43
|
+
columns,
|
|
44
|
+
rows: rowArr.slice(0, limit),
|
|
45
|
+
row_count: rows.affectedRows ?? rowArr.length,
|
|
46
|
+
execution_time_ms: elapsed,
|
|
47
|
+
truncated,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async getTables() {
|
|
51
|
+
if (!this.pool)
|
|
52
|
+
throw new Error('Not connected');
|
|
53
|
+
const [rows] = await this.pool.query(`
|
|
54
|
+
SELECT TABLE_NAME AS name, TABLE_TYPE AS type, TABLE_ROWS AS row_count, DATA_LENGTH AS size_bytes
|
|
55
|
+
FROM information_schema.tables
|
|
56
|
+
WHERE TABLE_SCHEMA = DATABASE()
|
|
57
|
+
ORDER BY TABLE_NAME
|
|
58
|
+
`);
|
|
59
|
+
return rows.map(r => ({
|
|
60
|
+
name: r.name,
|
|
61
|
+
type: r.type === 'BASE TABLE' ? 'table' : r.type?.toLowerCase(),
|
|
62
|
+
row_count: r.row_count != null ? parseInt(r.row_count) : undefined,
|
|
63
|
+
size_bytes: r.size_bytes != null ? parseInt(r.size_bytes) : undefined,
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
async describeTable(table) {
|
|
67
|
+
if (!this.pool)
|
|
68
|
+
throw new Error('Not connected');
|
|
69
|
+
const [cols] = await this.pool.query(`
|
|
70
|
+
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_KEY
|
|
71
|
+
FROM information_schema.columns
|
|
72
|
+
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?
|
|
73
|
+
ORDER BY ORDINAL_POSITION
|
|
74
|
+
`, [table]);
|
|
75
|
+
const columns = cols.map(c => ({
|
|
76
|
+
name: c.COLUMN_NAME,
|
|
77
|
+
type: c.DATA_TYPE,
|
|
78
|
+
nullable: c.IS_NULLABLE === 'YES',
|
|
79
|
+
default_value: c.COLUMN_DEFAULT || undefined,
|
|
80
|
+
primary_key: c.COLUMN_KEY === 'PRI',
|
|
81
|
+
}));
|
|
82
|
+
const [idxRows] = await this.pool.query(`SHOW INDEX FROM \`${table}\``);
|
|
83
|
+
const idxMap = new Map();
|
|
84
|
+
for (const r of idxRows) {
|
|
85
|
+
if (!idxMap.has(r.Key_name))
|
|
86
|
+
idxMap.set(r.Key_name, { columns: [], unique: !r.Non_unique });
|
|
87
|
+
idxMap.get(r.Key_name).columns.push(r.Column_name);
|
|
88
|
+
}
|
|
89
|
+
const indexes = [...idxMap.entries()].map(([name, v]) => ({ name, ...v }));
|
|
90
|
+
const [fkRows] = await this.pool.query(`
|
|
91
|
+
SELECT COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
|
|
92
|
+
FROM information_schema.KEY_COLUMN_USAGE
|
|
93
|
+
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND REFERENCED_TABLE_NAME IS NOT NULL
|
|
94
|
+
`, [table]);
|
|
95
|
+
return {
|
|
96
|
+
table,
|
|
97
|
+
columns,
|
|
98
|
+
indexes,
|
|
99
|
+
foreign_keys: fkRows.map(r => ({
|
|
100
|
+
column: r.COLUMN_NAME,
|
|
101
|
+
ref_table: r.REFERENCED_TABLE_NAME,
|
|
102
|
+
ref_column: r.REFERENCED_COLUMN_NAME,
|
|
103
|
+
})),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async getDatabases() {
|
|
107
|
+
if (!this.pool)
|
|
108
|
+
throw new Error('Not connected');
|
|
109
|
+
const [rows] = await this.pool.query('SHOW DATABASES');
|
|
110
|
+
return rows.map(r => r.Database);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConnectionParams, DatabaseDriver, QueryResult, TableInfo, SchemaInfo } from '../types.js';
|
|
2
|
+
export declare class Neo4jDriver implements DatabaseDriver {
|
|
3
|
+
private driver;
|
|
4
|
+
connect(params: ConnectionParams): Promise<void>;
|
|
5
|
+
disconnect(): Promise<void>;
|
|
6
|
+
isConnected(): boolean;
|
|
7
|
+
query(cypher: string, limit?: number): Promise<QueryResult>;
|
|
8
|
+
getTables(): Promise<TableInfo[]>;
|
|
9
|
+
describeTable(label: string): Promise<SchemaInfo>;
|
|
10
|
+
getDatabases(): Promise<string[]>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import neo4j from 'neo4j-driver';
|
|
2
|
+
function serializeValue(val) {
|
|
3
|
+
if (val === null || val === undefined)
|
|
4
|
+
return val;
|
|
5
|
+
if (neo4j.isInt(val))
|
|
6
|
+
return val.toNumber();
|
|
7
|
+
if (val instanceof neo4j.types.Node) {
|
|
8
|
+
return { labels: val.labels, properties: serializeRecord(val.properties) };
|
|
9
|
+
}
|
|
10
|
+
if (val instanceof neo4j.types.Relationship) {
|
|
11
|
+
return { type: val.type, properties: serializeRecord(val.properties) };
|
|
12
|
+
}
|
|
13
|
+
if (val instanceof neo4j.types.Path) {
|
|
14
|
+
const segments = val.segments.map((s) => `(${s.start.labels.join(':')})-[:${s.relationship.type}]->(${s.end.labels.join(':')})`);
|
|
15
|
+
return segments.join('');
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(val))
|
|
18
|
+
return val.map(serializeValue);
|
|
19
|
+
if (typeof val === 'object')
|
|
20
|
+
return serializeRecord(val);
|
|
21
|
+
return val;
|
|
22
|
+
}
|
|
23
|
+
function serializeRecord(obj) {
|
|
24
|
+
const out = {};
|
|
25
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
26
|
+
out[k] = serializeValue(v);
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
function inferType(val) {
|
|
31
|
+
if (val === null || val === undefined)
|
|
32
|
+
return 'unknown';
|
|
33
|
+
if (neo4j.isInt(val))
|
|
34
|
+
return 'integer';
|
|
35
|
+
if (typeof val === 'number')
|
|
36
|
+
return 'float';
|
|
37
|
+
if (typeof val === 'boolean')
|
|
38
|
+
return 'boolean';
|
|
39
|
+
if (typeof val === 'string')
|
|
40
|
+
return 'string';
|
|
41
|
+
if (Array.isArray(val))
|
|
42
|
+
return 'list';
|
|
43
|
+
if (val instanceof Date)
|
|
44
|
+
return 'datetime';
|
|
45
|
+
if (typeof val === 'object')
|
|
46
|
+
return 'map';
|
|
47
|
+
return typeof val;
|
|
48
|
+
}
|
|
49
|
+
export class Neo4jDriver {
|
|
50
|
+
driver = null;
|
|
51
|
+
async connect(params) {
|
|
52
|
+
const host = params.host || 'localhost';
|
|
53
|
+
const port = params.port || 7687;
|
|
54
|
+
const uri = params.connection_string || `bolt://${host}:${port}`;
|
|
55
|
+
const auth = params.username
|
|
56
|
+
? neo4j.auth.basic(params.username, params.password || '')
|
|
57
|
+
: undefined;
|
|
58
|
+
this.driver = neo4j.driver(uri, auth);
|
|
59
|
+
await this.driver.verifyConnectivity();
|
|
60
|
+
}
|
|
61
|
+
async disconnect() {
|
|
62
|
+
if (this.driver) {
|
|
63
|
+
await this.driver.close();
|
|
64
|
+
this.driver = null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
isConnected() {
|
|
68
|
+
return this.driver !== null;
|
|
69
|
+
}
|
|
70
|
+
async query(cypher, limit) {
|
|
71
|
+
if (!this.driver)
|
|
72
|
+
throw new Error('Not connected');
|
|
73
|
+
const session = this.driver.session();
|
|
74
|
+
const start = Date.now();
|
|
75
|
+
try {
|
|
76
|
+
const result = await session.run(cypher);
|
|
77
|
+
const elapsed = Date.now() - start;
|
|
78
|
+
const rows = result.records.map((record) => {
|
|
79
|
+
const obj = {};
|
|
80
|
+
for (const key of record.keys) {
|
|
81
|
+
obj[key] = serializeValue(record.get(key));
|
|
82
|
+
}
|
|
83
|
+
return obj;
|
|
84
|
+
});
|
|
85
|
+
const columns = result.records.length > 0
|
|
86
|
+
? result.records[0].keys
|
|
87
|
+
: [];
|
|
88
|
+
const truncated = limit !== undefined && rows.length >= limit;
|
|
89
|
+
const sliced = limit !== undefined ? rows.slice(0, limit) : rows;
|
|
90
|
+
return {
|
|
91
|
+
columns,
|
|
92
|
+
rows: sliced,
|
|
93
|
+
row_count: sliced.length,
|
|
94
|
+
execution_time_ms: elapsed,
|
|
95
|
+
truncated,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
await session.close();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async getTables() {
|
|
103
|
+
if (!this.driver)
|
|
104
|
+
throw new Error('Not connected');
|
|
105
|
+
const session = this.driver.session();
|
|
106
|
+
try {
|
|
107
|
+
const tables = [];
|
|
108
|
+
const labelsResult = await session.run('CALL db.labels()');
|
|
109
|
+
for (const record of labelsResult.records) {
|
|
110
|
+
tables.push({ name: record.get('label'), type: 'label' });
|
|
111
|
+
}
|
|
112
|
+
const relsResult = await session.run('CALL db.relationshipTypes()');
|
|
113
|
+
for (const record of relsResult.records) {
|
|
114
|
+
tables.push({ name: record.get('relationshipType'), type: 'relationship' });
|
|
115
|
+
}
|
|
116
|
+
return tables.sort((a, b) => a.name.localeCompare(b.name));
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
await session.close();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async describeTable(label) {
|
|
123
|
+
if (!this.driver)
|
|
124
|
+
throw new Error('Not connected');
|
|
125
|
+
const session = this.driver.session();
|
|
126
|
+
try {
|
|
127
|
+
const result = await session.run(`MATCH (n:\`${label}\`) WITH n LIMIT 50 UNWIND keys(n) AS key RETURN DISTINCT key, head(collect(n[key])) AS sample`);
|
|
128
|
+
const columns = result.records.map((record) => {
|
|
129
|
+
const name = record.get('key');
|
|
130
|
+
const sample = record.get('sample');
|
|
131
|
+
return {
|
|
132
|
+
name,
|
|
133
|
+
type: inferType(sample),
|
|
134
|
+
nullable: true,
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
return { table: label, columns, indexes: [], foreign_keys: [] };
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
await session.close();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async getDatabases() {
|
|
144
|
+
if (!this.driver)
|
|
145
|
+
throw new Error('Not connected');
|
|
146
|
+
const session = this.driver.session();
|
|
147
|
+
try {
|
|
148
|
+
const result = await session.run('SHOW DATABASES');
|
|
149
|
+
return result.records.map((record) => record.get('name'));
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return ['neo4j'];
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
await session.close();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConnectionParams, DatabaseDriver, QueryResult, TableInfo, SchemaInfo } from '../types.js';
|
|
2
|
+
export declare class PostgreSQLDriver implements DatabaseDriver {
|
|
3
|
+
private pool;
|
|
4
|
+
connect(params: ConnectionParams): Promise<void>;
|
|
5
|
+
disconnect(): Promise<void>;
|
|
6
|
+
isConnected(): boolean;
|
|
7
|
+
query(sql: string, limit?: number): Promise<QueryResult>;
|
|
8
|
+
getTables(): Promise<TableInfo[]>;
|
|
9
|
+
describeTable(table: string): Promise<SchemaInfo>;
|
|
10
|
+
getDatabases(): Promise<string[]>;
|
|
11
|
+
}
|