termdock 1.4.299 → 1.4.301
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/README.en.md +1 -1
- package/README.md +2 -1
- package/dist/client/assets/App-BziVLy1b.js +179 -0
- package/dist/client/assets/App-BziVLy1b.js.br +0 -0
- package/dist/client/assets/App-BziVLy1b.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-CARNBEqQ.js +12 -0
- package/dist/client/assets/ArchitecturePanel-CARNBEqQ.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-CARNBEqQ.js.gz +0 -0
- package/dist/client/assets/{ChangeWalkthroughPanel-2lXfrgk4.js → ChangeWalkthroughPanel-00oa0z6w.js} +2 -2
- package/dist/client/assets/ChangeWalkthroughPanel-00oa0z6w.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-00oa0z6w.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-DuEeKQKZ.js +1 -0
- package/dist/client/assets/CollaborationMainWorkspace-DuEeKQKZ.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-DuEeKQKZ.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-B_mzpNuw.js +2 -0
- package/dist/client/assets/ComputerControlView-C9v1Ooc9.js +5 -0
- package/dist/client/assets/ComputerControlView-C9v1Ooc9.js.br +0 -0
- package/dist/client/assets/ComputerControlView-C9v1Ooc9.js.gz +0 -0
- package/dist/client/assets/{DagPlayground-EFUb9S3u.js → DagPlayground-DfUpMALj.js} +1 -1
- package/dist/client/assets/DagPlayground-DfUpMALj.js.br +0 -0
- package/dist/client/assets/DagPlayground-DfUpMALj.js.gz +0 -0
- package/dist/client/assets/{DiffLab-CXWjSE2q.js → DiffLab-Cf_URhQt.js} +1 -1
- package/dist/client/assets/DiffLab-Cf_URhQt.js.br +0 -0
- package/dist/client/assets/DiffLab-Cf_URhQt.js.gz +0 -0
- package/dist/client/assets/{DiffReview-ByMkBaD9.js → DiffReview-DjG9vCpH.js} +1 -1
- package/dist/client/assets/DiffReview-DjG9vCpH.js.br +0 -0
- package/dist/client/assets/DiffReview-DjG9vCpH.js.gz +0 -0
- package/dist/client/assets/{DiffReviewLab-DoWaKm94.js → DiffReviewLab-BKOvHdJY.js} +2 -2
- package/dist/client/assets/DiffReviewLab-BKOvHdJY.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-BKOvHdJY.js.gz +0 -0
- package/dist/client/assets/{DiffViewer-B4hn9z0k.js → DiffViewer-6n3tgsdc.js} +8 -8
- package/dist/client/assets/DiffViewer-6n3tgsdc.js.br +0 -0
- package/dist/client/assets/DiffViewer-6n3tgsdc.js.gz +0 -0
- package/dist/client/assets/{ModelPreview-C-LJZ8so.js → ModelPreview-BNs2sRct.js} +1 -1
- package/dist/client/assets/ModelPreview-BNs2sRct.js.br +0 -0
- package/dist/client/assets/ModelPreview-BNs2sRct.js.gz +0 -0
- package/dist/client/assets/RightSidebar-CcMSU1v8.js +1677 -0
- package/dist/client/assets/RightSidebar-CcMSU1v8.js.br +0 -0
- package/dist/client/assets/RightSidebar-CcMSU1v8.js.gz +0 -0
- package/dist/client/assets/{abnfDiagram-VCTEODGH-BY-pfYKk.js → abnfDiagram-VCTEODGH-DogjvRKp.js} +1 -1
- package/dist/client/assets/abnfDiagram-VCTEODGH-DogjvRKp.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-DogjvRKp.js.gz +0 -0
- package/dist/client/assets/app-D6vN8PW-.js +35 -0
- package/dist/client/assets/app-D6vN8PW-.js.br +0 -0
- package/dist/client/assets/app-D6vN8PW-.js.gz +0 -0
- package/dist/client/assets/{arc-DIENgCZn.js → arc-Cqel4Ted.js} +1 -1
- package/dist/client/assets/arc-Cqel4Ted.js.br +0 -0
- package/dist/client/assets/arc-Cqel4Ted.js.gz +0 -0
- package/dist/client/assets/{architectureDiagram-5GKGNRK7-C1h4e4az.js → architectureDiagram-5GKGNRK7-DgvPtgNb.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DgvPtgNb.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-DgvPtgNb.js.gz +0 -0
- package/dist/client/assets/{blockDiagram-I7D4REHJ-B_yOr54K.js → blockDiagram-I7D4REHJ-BxbWO4x4.js} +1 -1
- package/dist/client/assets/blockDiagram-I7D4REHJ-BxbWO4x4.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-BxbWO4x4.js.gz +0 -0
- package/dist/client/assets/{c4Diagram-7LVT6UL2-DRD4zxIo.js → c4Diagram-7LVT6UL2-gsA37gjL.js} +1 -1
- package/dist/client/assets/c4Diagram-7LVT6UL2-gsA37gjL.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-gsA37gjL.js.gz +0 -0
- package/dist/client/assets/channel-CBc8-n7y.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-CXytnjmD.js → chunk-2Q5K7J3B-ChC9yYOd.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-Bjmajkf7.js → chunk-5VM5RSS4-Bi4Hc8yL.js} +1 -1
- package/dist/client/assets/{chunk-F27PBJKO-CQCL8mJG.js → chunk-F27PBJKO-DvVWvQEk.js} +1 -1
- package/dist/client/assets/chunk-F27PBJKO-DvVWvQEk.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-DvVWvQEk.js.gz +0 -0
- package/dist/client/assets/{chunk-IMKFNOWR-ruHGCADe.js → chunk-IMKFNOWR-BnwQLR5S.js} +1 -1
- package/dist/client/assets/chunk-IMKFNOWR-BnwQLR5S.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-BnwQLR5S.js.gz +0 -0
- package/dist/client/assets/{chunk-JWPE2WC7-U18S7rxZ.js → chunk-JWPE2WC7-BkNnaDiR.js} +1 -1
- package/dist/client/assets/{chunk-POPQ4Y6H-DWnwssfL.js → chunk-POPQ4Y6H-BRzm6Uzi.js} +1 -1
- package/dist/client/assets/{chunk-SVP7TREG-DMHj3NSq.js → chunk-SVP7TREG-CDYm-dzk.js} +1 -1
- package/dist/client/assets/chunk-SVP7TREG-CDYm-dzk.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-CDYm-dzk.js.gz +0 -0
- package/dist/client/assets/{chunk-TICWLB2K-Dh_ekvFW.js → chunk-TICWLB2K-BKaW9Z9i.js} +1 -1
- package/dist/client/assets/chunk-TICWLB2K-BKaW9Z9i.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-BKaW9Z9i.js.gz +0 -0
- package/dist/client/assets/{chunk-XXDRQBXY-Bq5wD6iJ.js → chunk-XXDRQBXY-DcHZ_FHb.js} +1 -1
- package/dist/client/assets/classDiagram-ZZMXUADV-CNFc2dOc.js +1 -0
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-CNFc2dOc.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-CsySWhYg.js → cose-bilkent-JH36ORCC-DCbbTNc6.js} +1 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-DCbbTNc6.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-DCbbTNc6.js.gz +0 -0
- package/dist/client/assets/{cynefin-OW5HDTMX-9DKE5wV7.js → cynefin-OW5HDTMX-i23hD0Z2.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-i23hD0Z2.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-i23hD0Z2.js.gz +0 -0
- package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-B_8fvr9c.js → cynefinDiagram-5FMLGOSQ-CbyLYcqc.js} +1 -1
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CbyLYcqc.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-CbyLYcqc.js.gz +0 -0
- package/dist/client/assets/{dagre-GXQ25YYZ-BOdsFNFT.js → dagre-GXQ25YYZ-iJ4VKzZm.js} +1 -1
- package/dist/client/assets/dagre-GXQ25YYZ-iJ4VKzZm.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-iJ4VKzZm.js.gz +0 -0
- package/dist/client/assets/{diagram-S7CK7UJ4-6v_qvAvi.js → diagram-S7CK7UJ4-BNVZcdsO.js} +1 -1
- package/dist/client/assets/diagram-S7CK7UJ4-BNVZcdsO.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-BNVZcdsO.js.gz +0 -0
- package/dist/client/assets/{diagram-UQ7AKVKN-c03oOGhD.js → diagram-UQ7AKVKN-1ghTvPiu.js} +1 -1
- package/dist/client/assets/diagram-UQ7AKVKN-1ghTvPiu.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-1ghTvPiu.js.gz +0 -0
- package/dist/client/assets/{diagram-VSXAHHWV-MMIhRYp_.js → diagram-VSXAHHWV-Ce_0nMd3.js} +1 -1
- package/dist/client/assets/diagram-VSXAHHWV-Ce_0nMd3.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-Ce_0nMd3.js.gz +0 -0
- package/dist/client/assets/{diagram-VX7I27RA-B_l-uebl.js → diagram-VX7I27RA-CLHEkhUt.js} +1 -1
- package/dist/client/assets/diagram-VX7I27RA-CLHEkhUt.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-CLHEkhUt.js.gz +0 -0
- package/dist/client/assets/{diagram-Z3DM3KII-DKoBC5gn.js → diagram-Z3DM3KII-iyb5DkP6.js} +1 -1
- package/dist/client/assets/diagram-Z3DM3KII-iyb5DkP6.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-iyb5DkP6.js.gz +0 -0
- package/dist/client/assets/{ebnfDiagram-PWID7BFC-Bs3wu8Az.js → ebnfDiagram-PWID7BFC-Dxh2TzXm.js} +1 -1
- package/dist/client/assets/ebnfDiagram-PWID7BFC-Dxh2TzXm.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-Dxh2TzXm.js.gz +0 -0
- package/dist/client/assets/{erDiagram-RLTQ6QDP-mYnHYbKl.js → erDiagram-RLTQ6QDP-Cr8IkdCC.js} +1 -1
- package/dist/client/assets/erDiagram-RLTQ6QDP-Cr8IkdCC.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-Cr8IkdCC.js.gz +0 -0
- package/dist/client/assets/{flowDiagram-HODETNUW-CwCLWbib.js → flowDiagram-HODETNUW-B8ZF1bwr.js} +1 -1
- package/dist/client/assets/flowDiagram-HODETNUW-B8ZF1bwr.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-B8ZF1bwr.js.gz +0 -0
- package/dist/client/assets/{ganttDiagram-EL5Y4UJY-mse8c-ni.js → ganttDiagram-EL5Y4UJY-zhdL10eM.js} +1 -1
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-zhdL10eM.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-zhdL10eM.js.gz +0 -0
- package/dist/client/assets/{gestureArbiter-BviL29ps.js → gestureArbiter-CXYHfU__.js} +1 -1
- package/dist/client/assets/gestureArbiter-CXYHfU__.js.br +0 -0
- package/dist/client/assets/gestureArbiter-CXYHfU__.js.gz +0 -0
- package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-BVUfLjAX.js → gitGraphDiagram-WWUBYQGX-BQf2fHBo.js} +1 -1
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BQf2fHBo.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BQf2fHBo.js.gz +0 -0
- package/dist/client/assets/{index-C6ftfFlG.css → index-CNY7CTVa.css} +1 -1
- package/dist/client/assets/index-CNY7CTVa.css.br +0 -0
- package/dist/client/assets/index-CNY7CTVa.css.gz +0 -0
- package/dist/client/assets/{infoDiagram-27XIBGKW-XjoFF4BC.js → infoDiagram-27XIBGKW-BT8xey7S.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-5VMMS53U-bH299bWL.js → ishikawaDiagram-5VMMS53U-DunPdwW9.js} +1 -1
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-DunPdwW9.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-DunPdwW9.js.gz +0 -0
- package/dist/client/assets/{journeyDiagram-3NMN7TZE-BG0u_X1A.js → journeyDiagram-3NMN7TZE-B0y75iIg.js} +1 -1
- package/dist/client/assets/journeyDiagram-3NMN7TZE-B0y75iIg.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-B0y75iIg.js.gz +0 -0
- package/dist/client/assets/{kanban-definition-UXKFOSKX-DRoc9N-i.js → kanban-definition-UXKFOSKX-BfgA5WLo.js} +1 -1
- package/dist/client/assets/kanban-definition-UXKFOSKX-BfgA5WLo.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-BfgA5WLo.js.gz +0 -0
- package/dist/client/assets/{layout-mh0t6JpE.js → layout-BvjABLff.js} +1 -1
- package/dist/client/assets/layout-BvjABLff.js.br +0 -0
- package/dist/client/assets/layout-BvjABLff.js.gz +0 -0
- package/dist/client/assets/{linear-B9KTRuUV.js → linear-DgeFRliF.js} +1 -1
- package/dist/client/assets/linear-DgeFRliF.js.br +0 -0
- package/dist/client/assets/linear-DgeFRliF.js.gz +0 -0
- package/dist/client/assets/{mermaid.core-Bu2G9zhK.js → mermaid.core-DM6Rlal9.js} +5 -5
- package/dist/client/assets/mermaid.core-DM6Rlal9.js.br +0 -0
- package/dist/client/assets/mermaid.core-DM6Rlal9.js.gz +0 -0
- package/dist/client/assets/{mindmap-definition-YA3MSWOX-Go6Bg5xm.js → mindmap-definition-YA3MSWOX-DhEiABv6.js} +1 -1
- package/dist/client/assets/mindmap-definition-YA3MSWOX-DhEiABv6.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-DhEiABv6.js.gz +0 -0
- package/dist/client/assets/{passwordBootstrap-C7-MUAHQ.js → passwordBootstrap-Dxv0I4wM.js} +1 -1
- package/dist/client/assets/passwordBootstrap-Dxv0I4wM.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-Dxv0I4wM.js.gz +0 -0
- package/dist/client/assets/{pegDiagram-XKGWAZYB-DKUIl_U6.js → pegDiagram-XKGWAZYB-LTlVaJfm.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-LTlVaJfm.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-LTlVaJfm.js.gz +0 -0
- package/dist/client/assets/{pieDiagram-E7YTZNPT-aoDNlV7J.js → pieDiagram-E7YTZNPT-9bnryna3.js} +1 -1
- package/dist/client/assets/pieDiagram-E7YTZNPT-9bnryna3.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-9bnryna3.js.gz +0 -0
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-BKuuaF2s.js → quadrantDiagram-AXDQQJYC-ZBmgIpsJ.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-AXDQQJYC-BKuuaF2s.js.br → quadrantDiagram-AXDQQJYC-ZBmgIpsJ.js.br} +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-ZBmgIpsJ.js.gz +0 -0
- package/dist/client/assets/{railroadDiagram-O6MQD6OU-BwfCW2bp.js → railroadDiagram-O6MQD6OU-DTtXvKOu.js} +1 -1
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DTtXvKOu.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-DTtXvKOu.js.gz +0 -0
- package/dist/client/assets/rdpSession-Ggo3N5s5.js +1 -0
- package/dist/client/assets/rdpSession-Ggo3N5s5.js.br +0 -0
- package/dist/client/assets/rdpSession-Ggo3N5s5.js.gz +0 -0
- package/dist/client/assets/referenceLongPress-Df8W2cyP.js +1 -0
- package/dist/client/assets/referenceLongPress-Df8W2cyP.js.br +0 -0
- package/dist/client/assets/referenceLongPress-Df8W2cyP.js.gz +0 -0
- package/dist/client/assets/{requirementDiagram-BXWQKSXE-DbpU9Uig.js → requirementDiagram-BXWQKSXE-BNia9zI0.js} +1 -1
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BNia9zI0.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-BNia9zI0.js.gz +0 -0
- package/dist/client/assets/{sankeyDiagram-P5KCCOFB-Bxa22XVM.js → sankeyDiagram-P5KCCOFB-uvg5npfK.js} +1 -1
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-uvg5npfK.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-uvg5npfK.js.gz +0 -0
- package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-C4GvzT9z.js → sequenceDiagram-WJ2MYXX4-DpJNf2MD.js} +1 -1
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-DpJNf2MD.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-DpJNf2MD.js.gz +0 -0
- package/dist/client/assets/{sizeCapture-INFHLROL-B9zJJwQw.js → sizeCapture-INFHLROL-CkWB2AnF.js} +1 -1
- package/dist/client/assets/sizeCapture-INFHLROL-CkWB2AnF.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-CkWB2AnF.js.gz +0 -0
- package/dist/client/assets/{sparkles-BJbfT-v-.js → sparkles-DOuEtn62.js} +1 -1
- package/dist/client/assets/{stateDiagram-D77RDMKH-fqbw6LZa.js → stateDiagram-D77RDMKH-CeMzMQq-.js} +1 -1
- package/dist/client/assets/stateDiagram-D77RDMKH-CeMzMQq-.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-CeMzMQq-.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CNYUpLxt.js +1 -0
- package/dist/client/assets/{swimlanes-42K2YHIH-Hpc28YZY.js → swimlanes-42K2YHIH-Bo9GejWo.js} +1 -1
- package/dist/client/assets/swimlanes-42K2YHIH-Bo9GejWo.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-Bo9GejWo.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-EB7zBRFR.js +8 -0
- package/dist/client/assets/{timeline-definition-24CTP7MA-qDieK7Re.js → timeline-definition-24CTP7MA-cvWXYEZ4.js} +1 -1
- package/dist/client/assets/timeline-definition-24CTP7MA-cvWXYEZ4.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-cvWXYEZ4.js.gz +0 -0
- package/dist/client/assets/{triangle-alert-YOCAWhtT.js → triangle-alert-DzV0gQXz.js} +1 -1
- package/dist/client/assets/{vennDiagram-4TSXK5OY-BJpZlHao.js → vennDiagram-4TSXK5OY-CzleWcmk.js} +1 -1
- package/dist/client/assets/{vennDiagram-4TSXK5OY-BJpZlHao.js.br → vennDiagram-4TSXK5OY-CzleWcmk.js.br} +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-CzleWcmk.js.gz +0 -0
- package/dist/client/assets/{videoCompression-DI9vP0dm.js → videoCompression-DCnzjEfU.js} +1 -1
- package/dist/client/assets/videoCompression-DCnzjEfU.js.br +0 -0
- package/dist/client/assets/videoCompression-DCnzjEfU.js.gz +0 -0
- package/dist/client/assets/{wardleyDiagram-VM6X3IG4-CQJfj6Ns.js → wardleyDiagram-VM6X3IG4-Cir1iutR.js} +1 -1
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-Cir1iutR.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-Cir1iutR.js.gz +0 -0
- package/dist/client/assets/{xychartDiagram-S5SC5T6Z-Cy-lkWBX.js → xychartDiagram-S5SC5T6Z-pNPcVJ1C.js} +1 -1
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-pNPcVJ1C.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-pNPcVJ1C.js.gz +0 -0
- package/dist/client/index.html +2 -2
- package/dist/client/index.html.br +0 -0
- package/dist/client/index.html.gz +0 -0
- package/dist/client/sw.js +1 -1
- package/dist/client/sw.js.br +0 -0
- package/dist/client/sw.js.gz +0 -0
- package/dist/server/agent/collaborationCli.js +56 -10
- package/dist/server/agent/collaborationGroupRoutes.js +10 -5
- package/dist/server/agent/collaborationLaunchProfiles.js +43 -0
- package/dist/server/agent/collaborationRoutes.js +6 -2
- package/dist/server/agent/collaborationService.js +8 -2
- package/dist/server/agent/collaborationStore.js +32 -1
- package/dist/server/agent/collaborationTaskCli.js +11 -3
- package/dist/server/agent/collaborationTaskService.js +16 -10
- package/dist/server/agent/collaborationTaskStore.js +70 -25
- package/dist/server/agent/collaborationTeam.js +3 -3
- package/dist/server/agent/integrationCli.js +243 -0
- package/dist/server/agent/integrationServer.js +331 -0
- package/dist/server/agent/integrationSessions.js +344 -0
- package/dist/server/agent/integrationStore.js +222 -0
- package/dist/server/cli.js +29 -0
- package/dist/server/entry.js +26 -7
- package/dist/server/routes/filesystem.js +120 -87
- package/dist/server/routes/terminal.js +196 -13
- package/dist/server/utils/localAccess.js +27 -7
- package/dist/server/utils/sessionDisplayName.js +53 -0
- package/docs/integrations.md +304 -0
- package/package.json +3 -2
- package/runtime-manifest.json +3 -3
- package/dist/client/assets/App-DzuUkEI_.js +0 -179
- package/dist/client/assets/App-DzuUkEI_.js.br +0 -0
- package/dist/client/assets/App-DzuUkEI_.js.gz +0 -0
- package/dist/client/assets/ArchitecturePanel-QodxiiCc.js +0 -7
- package/dist/client/assets/ArchitecturePanel-QodxiiCc.js.br +0 -0
- package/dist/client/assets/ArchitecturePanel-QodxiiCc.js.gz +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-2lXfrgk4.js.br +0 -0
- package/dist/client/assets/ChangeWalkthroughPanel-2lXfrgk4.js.gz +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-05-Py9N8.js +0 -1
- package/dist/client/assets/CollaborationMainWorkspace-05-Py9N8.js.br +0 -0
- package/dist/client/assets/CollaborationMainWorkspace-05-Py9N8.js.gz +0 -0
- package/dist/client/assets/CollaborationTaskContent-BJe9TUtZ.js +0 -2
- package/dist/client/assets/ComputerControlView-B5vigCoW.js +0 -5
- package/dist/client/assets/ComputerControlView-B5vigCoW.js.br +0 -0
- package/dist/client/assets/ComputerControlView-B5vigCoW.js.gz +0 -0
- package/dist/client/assets/DagPlayground-EFUb9S3u.js.br +0 -0
- package/dist/client/assets/DagPlayground-EFUb9S3u.js.gz +0 -0
- package/dist/client/assets/DiffLab-CXWjSE2q.js.br +0 -0
- package/dist/client/assets/DiffLab-CXWjSE2q.js.gz +0 -0
- package/dist/client/assets/DiffReview-ByMkBaD9.js.br +0 -0
- package/dist/client/assets/DiffReview-ByMkBaD9.js.gz +0 -0
- package/dist/client/assets/DiffReviewLab-DoWaKm94.js.br +0 -0
- package/dist/client/assets/DiffReviewLab-DoWaKm94.js.gz +0 -0
- package/dist/client/assets/DiffViewer-B4hn9z0k.js.br +0 -0
- package/dist/client/assets/DiffViewer-B4hn9z0k.js.gz +0 -0
- package/dist/client/assets/ModelPreview-C-LJZ8so.js.br +0 -0
- package/dist/client/assets/ModelPreview-C-LJZ8so.js.gz +0 -0
- package/dist/client/assets/RightSidebar-EaMm4prW.js +0 -1678
- package/dist/client/assets/RightSidebar-EaMm4prW.js.br +0 -0
- package/dist/client/assets/RightSidebar-EaMm4prW.js.gz +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BY-pfYKk.js.br +0 -0
- package/dist/client/assets/abnfDiagram-VCTEODGH-BY-pfYKk.js.gz +0 -0
- package/dist/client/assets/app-Ch0UDtJ-.js +0 -35
- package/dist/client/assets/app-Ch0UDtJ-.js.br +0 -0
- package/dist/client/assets/app-Ch0UDtJ-.js.gz +0 -0
- package/dist/client/assets/arc-DIENgCZn.js.br +0 -0
- package/dist/client/assets/arc-DIENgCZn.js.gz +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-C1h4e4az.js.br +0 -0
- package/dist/client/assets/architectureDiagram-5GKGNRK7-C1h4e4az.js.gz +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-B_yOr54K.js.br +0 -0
- package/dist/client/assets/blockDiagram-I7D4REHJ-B_yOr54K.js.gz +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DRD4zxIo.js.br +0 -0
- package/dist/client/assets/c4Diagram-7LVT6UL2-DRD4zxIo.js.gz +0 -0
- package/dist/client/assets/channel-MOXuUKM7.js +0 -1
- package/dist/client/assets/chunk-F27PBJKO-CQCL8mJG.js.br +0 -0
- package/dist/client/assets/chunk-F27PBJKO-CQCL8mJG.js.gz +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-ruHGCADe.js.br +0 -0
- package/dist/client/assets/chunk-IMKFNOWR-ruHGCADe.js.gz +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DMHj3NSq.js.br +0 -0
- package/dist/client/assets/chunk-SVP7TREG-DMHj3NSq.js.gz +0 -0
- package/dist/client/assets/chunk-TICWLB2K-Dh_ekvFW.js.br +0 -0
- package/dist/client/assets/chunk-TICWLB2K-Dh_ekvFW.js.gz +0 -0
- package/dist/client/assets/classDiagram-ZZMXUADV-CEXMdudw.js +0 -1
- package/dist/client/assets/classDiagram-v2-VYDZK3BY-CEXMdudw.js +0 -1
- package/dist/client/assets/cose-bilkent-JH36ORCC-CsySWhYg.js.br +0 -0
- package/dist/client/assets/cose-bilkent-JH36ORCC-CsySWhYg.js.gz +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-9DKE5wV7.js.br +0 -0
- package/dist/client/assets/cynefin-OW5HDTMX-9DKE5wV7.js.gz +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-B_8fvr9c.js.br +0 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-B_8fvr9c.js.gz +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-BOdsFNFT.js.br +0 -0
- package/dist/client/assets/dagre-GXQ25YYZ-BOdsFNFT.js.gz +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-6v_qvAvi.js.br +0 -0
- package/dist/client/assets/diagram-S7CK7UJ4-6v_qvAvi.js.gz +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-c03oOGhD.js.br +0 -0
- package/dist/client/assets/diagram-UQ7AKVKN-c03oOGhD.js.gz +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-MMIhRYp_.js.br +0 -0
- package/dist/client/assets/diagram-VSXAHHWV-MMIhRYp_.js.gz +0 -0
- package/dist/client/assets/diagram-VX7I27RA-B_l-uebl.js.br +0 -0
- package/dist/client/assets/diagram-VX7I27RA-B_l-uebl.js.gz +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-DKoBC5gn.js.br +0 -0
- package/dist/client/assets/diagram-Z3DM3KII-DKoBC5gn.js.gz +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-Bs3wu8Az.js.br +0 -0
- package/dist/client/assets/ebnfDiagram-PWID7BFC-Bs3wu8Az.js.gz +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-mYnHYbKl.js.br +0 -0
- package/dist/client/assets/erDiagram-RLTQ6QDP-mYnHYbKl.js.gz +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-CwCLWbib.js.br +0 -0
- package/dist/client/assets/flowDiagram-HODETNUW-CwCLWbib.js.gz +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-mse8c-ni.js.br +0 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-mse8c-ni.js.gz +0 -0
- package/dist/client/assets/gestureArbiter-BviL29ps.js.br +0 -0
- package/dist/client/assets/gestureArbiter-BviL29ps.js.gz +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BVUfLjAX.js.br +0 -0
- package/dist/client/assets/gitGraphDiagram-WWUBYQGX-BVUfLjAX.js.gz +0 -0
- package/dist/client/assets/index-C6ftfFlG.css.br +0 -0
- package/dist/client/assets/index-C6ftfFlG.css.gz +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-bH299bWL.js.br +0 -0
- package/dist/client/assets/ishikawaDiagram-5VMMS53U-bH299bWL.js.gz +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-BG0u_X1A.js.br +0 -0
- package/dist/client/assets/journeyDiagram-3NMN7TZE-BG0u_X1A.js.gz +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-DRoc9N-i.js.br +0 -0
- package/dist/client/assets/kanban-definition-UXKFOSKX-DRoc9N-i.js.gz +0 -0
- package/dist/client/assets/layout-mh0t6JpE.js.br +0 -0
- package/dist/client/assets/layout-mh0t6JpE.js.gz +0 -0
- package/dist/client/assets/linear-B9KTRuUV.js.br +0 -0
- package/dist/client/assets/linear-B9KTRuUV.js.gz +0 -0
- package/dist/client/assets/mermaid.core-Bu2G9zhK.js.br +0 -0
- package/dist/client/assets/mermaid.core-Bu2G9zhK.js.gz +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-Go6Bg5xm.js.br +0 -0
- package/dist/client/assets/mindmap-definition-YA3MSWOX-Go6Bg5xm.js.gz +0 -0
- package/dist/client/assets/passwordBootstrap-C7-MUAHQ.js.br +0 -0
- package/dist/client/assets/passwordBootstrap-C7-MUAHQ.js.gz +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DKUIl_U6.js.br +0 -0
- package/dist/client/assets/pegDiagram-XKGWAZYB-DKUIl_U6.js.gz +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-aoDNlV7J.js.br +0 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-aoDNlV7J.js.gz +0 -0
- package/dist/client/assets/quadrantDiagram-AXDQQJYC-BKuuaF2s.js.gz +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BwfCW2bp.js.br +0 -0
- package/dist/client/assets/railroadDiagram-O6MQD6OU-BwfCW2bp.js.gz +0 -0
- package/dist/client/assets/rdpSession--y6Q98uo.js +0 -1
- package/dist/client/assets/rdpSession--y6Q98uo.js.br +0 -0
- package/dist/client/assets/rdpSession--y6Q98uo.js.gz +0 -0
- package/dist/client/assets/referenceLongPress-BeG1PAdI.js +0 -1
- package/dist/client/assets/referenceLongPress-BeG1PAdI.js.br +0 -0
- package/dist/client/assets/referenceLongPress-BeG1PAdI.js.gz +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-DbpU9Uig.js.br +0 -0
- package/dist/client/assets/requirementDiagram-BXWQKSXE-DbpU9Uig.js.gz +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-Bxa22XVM.js.br +0 -0
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-Bxa22XVM.js.gz +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-C4GvzT9z.js.br +0 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-C4GvzT9z.js.gz +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-B9zJJwQw.js.br +0 -0
- package/dist/client/assets/sizeCapture-INFHLROL-B9zJJwQw.js.gz +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-fqbw6LZa.js.br +0 -0
- package/dist/client/assets/stateDiagram-D77RDMKH-fqbw6LZa.js.gz +0 -0
- package/dist/client/assets/stateDiagram-v2-MP3YSRHH-BO23Pbrn.js +0 -1
- package/dist/client/assets/swimlanes-42K2YHIH-Hpc28YZY.js.br +0 -0
- package/dist/client/assets/swimlanes-42K2YHIH-Hpc28YZY.js.gz +0 -0
- package/dist/client/assets/swimlanesDiagram-VR7AAH4N-BLS7y4Di.js +0 -8
- package/dist/client/assets/timeline-definition-24CTP7MA-qDieK7Re.js.br +0 -0
- package/dist/client/assets/timeline-definition-24CTP7MA-qDieK7Re.js.gz +0 -0
- package/dist/client/assets/vennDiagram-4TSXK5OY-BJpZlHao.js.gz +0 -0
- package/dist/client/assets/videoCompression-DI9vP0dm.js.br +0 -0
- package/dist/client/assets/videoCompression-DI9vP0dm.js.gz +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-CQJfj6Ns.js.br +0 -0
- package/dist/client/assets/wardleyDiagram-VM6X3IG4-CQJfj6Ns.js.gz +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-Cy-lkWBX.js.br +0 -0
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-Cy-lkWBX.js.gz +0 -0
package/dist/server/entry.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { IntegrationRuntime, integrationSocketPath } from './agent/integrationServer.js';
|
|
1
2
|
import { CollaborationService } from './agent/collaborationService.js';
|
|
2
3
|
import { X509Certificate } from 'node:crypto';
|
|
3
4
|
import { CollaborationPeerTransport, connectCollaborationRpc } from './agent/collaborationPeerTransport.js';
|
|
4
|
-
import { collaborationStore, collaborationTaskStore, deliverPeerCollaboration, collaborationLocalActivity, collaborationDirectorySessions, prepareCollaborationTaskWorker } from './routes/terminal.js';
|
|
5
|
+
import { collaborationStore, collaborationTaskStore, deliverPeerCollaboration, collaborationLocalActivity, collaborationDirectorySessions, prepareCollaborationTaskWorker, integrationSessionAdapter } from './routes/terminal.js';
|
|
5
6
|
import { CollaborationTaskService } from './agent/collaborationTaskService.js';
|
|
6
7
|
import { setPushTargetPeerId } from './notifications/pushService.js';
|
|
7
8
|
import { desktopDirectTargets } from './federation/desktopTargets.js';
|
|
@@ -571,7 +572,7 @@ export function startServer(options = {}) {
|
|
|
571
572
|
return routeInvitations.consume(code, subjectId);
|
|
572
573
|
},
|
|
573
574
|
});
|
|
574
|
-
void federation.then(runtime => {
|
|
575
|
+
void federation.then(async (runtime) => {
|
|
575
576
|
federationServiceId = runtime.serviceId;
|
|
576
577
|
setPushTargetPeerId(runtime.serviceId);
|
|
577
578
|
refreshDirectTargets();
|
|
@@ -634,6 +635,21 @@ export function startServer(options = {}) {
|
|
|
634
635
|
app.locals.collaborationService = collaborationService;
|
|
635
636
|
const collaborationTasks = new CollaborationTaskService(collaborationTaskStore, collaborationStore, collaborationService, deliverPeerCollaboration, (task, template, dependencies) => prepareCollaborationTaskWorker(task, template, dependencies, collaborationService, (taskId, dependencyId, offset) => collaborationTasks.dependencyChunk(taskId, dependencyId, offset)));
|
|
636
637
|
app.locals.collaborationTasks = collaborationTasks;
|
|
638
|
+
if (options.port !== 0) {
|
|
639
|
+
let integration;
|
|
640
|
+
try {
|
|
641
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
642
|
+
integration = new IntegrationRuntime({ directory: path.join(homedir(), '.termdock', 'integration-state', String(port)), socketPath: integrationSocketPath(port), adminToken: options.localApiToken,
|
|
643
|
+
messages: collaborationStore, taskStore: collaborationTaskStore, tasks: collaborationTasks, peers: collaborationService, sessions: integrationSessionAdapter });
|
|
644
|
+
await integration.listen();
|
|
645
|
+
app.locals.integrationRuntime = integration;
|
|
646
|
+
server.once('close', () => { void integration?.close(); });
|
|
647
|
+
}
|
|
648
|
+
catch {
|
|
649
|
+
await integration?.close();
|
|
650
|
+
console.error('[integrations] Local integration endpoint could not start; existing terminal service remains available');
|
|
651
|
+
}
|
|
652
|
+
}
|
|
637
653
|
collaborationTasks.start();
|
|
638
654
|
server.once('close', () => collaborationTasks.close());
|
|
639
655
|
collaborationService.start();
|
|
@@ -786,15 +802,18 @@ export function startServer(options = {}) {
|
|
|
786
802
|
return;
|
|
787
803
|
});
|
|
788
804
|
server.listen(port, host, () => {
|
|
805
|
+
const listeningAddress = server.address();
|
|
806
|
+
const listeningPort = listeningAddress && typeof listeningAddress !== 'string' ? listeningAddress.port : port;
|
|
807
|
+
const listeningHost = listeningAddress && typeof listeningAddress !== 'string' ? listeningAddress.address : host;
|
|
789
808
|
const displayHost = host === '0.0.0.0' ? 'localhost' : host;
|
|
790
|
-
console.log(`Termdock server running at ${scheme}://${displayHost}:${
|
|
791
|
-
console.log(`Health check: ${scheme}://${displayHost}:${
|
|
809
|
+
console.log(`Termdock server running at ${scheme}://${displayHost}:${listeningPort}`);
|
|
810
|
+
console.log(`Health check: ${scheme}://${displayHost}:${listeningPort}/health`);
|
|
792
811
|
const onboardingServerState = scheme === 'https'
|
|
793
|
-
? startOnboardingServer({ httpsPort:
|
|
812
|
+
? startOnboardingServer({ httpsPort: listeningPort, caCertPath: options.httpsCaPath })
|
|
794
813
|
: { server: null, url: null };
|
|
795
|
-
void localAccessManager.start({ host, port, scheme, caCertPath: options.httpsCaPath, onboardingPort: options.onboardingPort ??
|
|
814
|
+
void localAccessManager.start({ host: listeningHost, port: listeningPort, scheme, caCertPath: options.httpsCaPath, onboardingPort: options.onboardingPort ?? listeningPort }).then((state) => {
|
|
796
815
|
const publishState = () => {
|
|
797
|
-
const onboardingUrl = onboardingServerState.url ?? state.onboardingUrl;
|
|
816
|
+
const onboardingUrl = state.status === 'loopback-only' ? null : onboardingServerState.url ?? state.onboardingUrl;
|
|
798
817
|
latestLocalAccessState = state;
|
|
799
818
|
latestOnboardingUrl = onboardingUrl;
|
|
800
819
|
if (state.status === 'active') {
|
|
@@ -5064,89 +5064,136 @@ router.post('/upload', async (req, res) => {
|
|
|
5064
5064
|
res.status(400).json({ error: 'Missing dir query parameter', code: 'MISSING_DIR' });
|
|
5065
5065
|
return;
|
|
5066
5066
|
}
|
|
5067
|
+
// New clients can reject an oversized selection before sending any files.
|
|
5068
|
+
// Older clients are still checked against the actual multipart contents.
|
|
5069
|
+
const declaredCount = req.query.fileCount;
|
|
5070
|
+
if (declaredCount !== undefined && (typeof declaredCount !== 'string' || !/^\d+$/.test(declaredCount))) {
|
|
5071
|
+
res.status(400).json({ error: 'Invalid fileCount query parameter', code: 'INVALID_FILE_COUNT' });
|
|
5072
|
+
return;
|
|
5073
|
+
}
|
|
5074
|
+
if (typeof declaredCount === 'string' && Number(declaredCount) > MAX_UPLOAD_FILES) {
|
|
5075
|
+
res.status(413).json({ error: 'Upload limit exceeded', code: 'UPLOAD_LIMIT', files: [], results: [], maxFiles: MAX_UPLOAD_FILES });
|
|
5076
|
+
return;
|
|
5077
|
+
}
|
|
5067
5078
|
const resolvedDir = await pathValidator.validatePathAsync(dir);
|
|
5068
5079
|
const stat = await fs.promises.stat(resolvedDir);
|
|
5069
5080
|
if (!stat.isDirectory()) {
|
|
5070
5081
|
res.status(400).json({ error: 'Target is not a directory', code: 'NOT_A_DIRECTORY' });
|
|
5071
5082
|
return;
|
|
5072
5083
|
}
|
|
5073
|
-
const
|
|
5074
|
-
|
|
5075
|
-
let
|
|
5084
|
+
const results = [];
|
|
5085
|
+
const createdPaths = [];
|
|
5086
|
+
let failure;
|
|
5076
5087
|
let totalSize = 0;
|
|
5088
|
+
const fail = (error, code = 'UPLOAD_FAILED', status = 500) => {
|
|
5089
|
+
failure ??= { error, code, status };
|
|
5090
|
+
};
|
|
5077
5091
|
const bb = busboy({
|
|
5078
5092
|
headers: req.headers,
|
|
5079
5093
|
// Browser FormData sends UTF-8 filenames, while busboy defaults bare
|
|
5080
5094
|
// multipart filename parameters to latin1. Without this, dropped files
|
|
5081
5095
|
// named with CJK characters turn into mojibake like "æ¥è¯¢".
|
|
5082
5096
|
defParamCharset: 'utf8',
|
|
5083
|
-
|
|
5097
|
+
// Enforce the count in the file handler rather than Busboy's files limit:
|
|
5098
|
+
// the latter silently omits the names of files beyond the limit.
|
|
5099
|
+
// Busboy marks a stream truncated as soon as this boundary is reached;
|
|
5100
|
+
// one extra byte lets an exactly-100MB file remain a valid upload.
|
|
5101
|
+
limits: { fileSize: MAX_UPLOAD_SIZE + 1 },
|
|
5084
5102
|
});
|
|
5085
5103
|
const writePromises = [];
|
|
5086
5104
|
bb.on('file', (_fieldname, fileStream, info) => {
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
aborted = true;
|
|
5094
|
-
fileStream.resume();
|
|
5095
|
-
return;
|
|
5096
|
-
}
|
|
5097
|
-
const { filename } = info;
|
|
5098
|
-
const destName = sanitizeUploadFilename(filename, `file_${fileCount}`);
|
|
5105
|
+
const index = results.length;
|
|
5106
|
+
const destName = sanitizeUploadFilename(info.filename, `file_${index + 1}`);
|
|
5107
|
+
const result = { index, name: destName, status: 'failed' };
|
|
5108
|
+
results.push(result);
|
|
5109
|
+
if (results.length > MAX_UPLOAD_FILES)
|
|
5110
|
+
fail('Upload limit exceeded', 'UPLOAD_LIMIT', 413);
|
|
5099
5111
|
const baseDestPath = path.join(resolvedDir, destName);
|
|
5100
|
-
|
|
5112
|
+
fileStream.on('limit', () => fail('Upload limit exceeded', 'UPLOAD_LIMIT', 413));
|
|
5113
|
+
// Parsing/cancellation can destroy this stream while exclusive open is
|
|
5114
|
+
// pending. The async iterator below will still observe the same error.
|
|
5115
|
+
fileStream.on('error', () => { });
|
|
5101
5116
|
const writePromise = (async () => {
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5117
|
+
let destination;
|
|
5118
|
+
let fileSize = 0;
|
|
5119
|
+
try {
|
|
5120
|
+
if (!failure) {
|
|
5121
|
+
destination = await createUniqueUploadFile(baseDestPath);
|
|
5122
|
+
createdPaths.push(destination.path);
|
|
5123
|
+
}
|
|
5124
|
+
// Keep draining rejected files so every multipart item can be
|
|
5125
|
+
// reported, and Busboy can finish without a dangling write stream.
|
|
5126
|
+
for await (const chunk of fileStream) {
|
|
5127
|
+
const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
5128
|
+
fileSize += data.length;
|
|
5129
|
+
totalSize += data.length;
|
|
5130
|
+
if (totalSize > MAX_UPLOAD_SIZE)
|
|
5131
|
+
fail('Upload limit exceeded', 'UPLOAD_LIMIT', 413);
|
|
5132
|
+
if (destination && !failure) {
|
|
5133
|
+
try {
|
|
5134
|
+
await destination.handle.writeFile(data);
|
|
5135
|
+
}
|
|
5136
|
+
catch (error) {
|
|
5137
|
+
// Do not throw from the iterator body: that would destroy the
|
|
5138
|
+
// multipart source before Busboy can drain the rest of it.
|
|
5139
|
+
fail(error instanceof Error ? error.message : 'Upload failed');
|
|
5140
|
+
}
|
|
5114
5141
|
}
|
|
5115
|
-
}
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
}
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
}
|
|
5142
|
+
}
|
|
5143
|
+
if (destination && !failure) {
|
|
5144
|
+
result.status = 'uploaded';
|
|
5145
|
+
result.path = destination.path;
|
|
5146
|
+
result.size = fileSize;
|
|
5147
|
+
}
|
|
5148
|
+
}
|
|
5149
|
+
catch (error) {
|
|
5150
|
+
fail(error instanceof Error ? error.message : 'Upload failed');
|
|
5151
|
+
fileStream.resume();
|
|
5152
|
+
}
|
|
5153
|
+
finally {
|
|
5154
|
+
try {
|
|
5155
|
+
await destination?.handle.close();
|
|
5156
|
+
}
|
|
5157
|
+
catch (error) {
|
|
5158
|
+
fail(error instanceof Error ? error.message : 'Upload failed');
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
5126
5161
|
})();
|
|
5127
5162
|
writePromises.push(writePromise);
|
|
5128
5163
|
});
|
|
5129
|
-
bb.
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5164
|
+
const onAborted = () => bb.destroy(new Error('Upload canceled'));
|
|
5165
|
+
req.once('aborted', onAborted);
|
|
5166
|
+
try {
|
|
5167
|
+
await new Promise((resolve, reject) => {
|
|
5168
|
+
bb.once('finish', resolve);
|
|
5169
|
+
bb.once('error', reject);
|
|
5170
|
+
req.pipe(bb);
|
|
5171
|
+
});
|
|
5172
|
+
}
|
|
5173
|
+
catch (error) {
|
|
5174
|
+
fail(error instanceof Error ? error.message : 'Upload failed');
|
|
5175
|
+
}
|
|
5176
|
+
finally {
|
|
5177
|
+
req.off('aborted', onAborted);
|
|
5178
|
+
}
|
|
5179
|
+
await Promise.all(writePromises);
|
|
5180
|
+
if (res.destroyed)
|
|
5181
|
+
fail('Upload canceled');
|
|
5182
|
+
if (failure) {
|
|
5183
|
+
// Paths enter this list only after an exclusive create succeeded. Never
|
|
5184
|
+
// remove an existing file or another concurrent request's destination.
|
|
5185
|
+
await Promise.all(createdPaths.map(filePath => fs.promises.unlink(filePath).catch(error => {
|
|
5186
|
+
if (error.code !== 'ENOENT')
|
|
5187
|
+
throw error;
|
|
5188
|
+
})));
|
|
5189
|
+
const { error, code, status } = failure;
|
|
5190
|
+
if (!res.destroyed)
|
|
5191
|
+
res.status(status).json({ error, code, files: [], maxFiles: MAX_UPLOAD_FILES,
|
|
5192
|
+
results: results.map(result => ({ index: result.index, name: result.name, status: 'failed', error, code })) });
|
|
5193
|
+
return;
|
|
5194
|
+
}
|
|
5195
|
+
const files = results.map(result => ({ name: result.name, path: result.path, size: result.size }));
|
|
5196
|
+
res.status(200).json({ files, results });
|
|
5150
5197
|
}
|
|
5151
5198
|
catch (error) {
|
|
5152
5199
|
if (error instanceof Error && error.code === 'PATH_NOT_ALLOWED') {
|
|
@@ -5157,32 +5204,18 @@ router.post('/upload', async (req, res) => {
|
|
|
5157
5204
|
res.status(500).json({ error: message, code: 'UPLOAD_FAILED' });
|
|
5158
5205
|
}
|
|
5159
5206
|
});
|
|
5160
|
-
async function
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
const
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
}
|
|
5172
|
-
return candidate;
|
|
5173
|
-
}
|
|
5174
|
-
catch {
|
|
5175
|
-
// File doesn't exist — use as-is
|
|
5176
|
-
return filePath;
|
|
5177
|
-
}
|
|
5178
|
-
}
|
|
5179
|
-
async function exists(p) {
|
|
5180
|
-
try {
|
|
5181
|
-
await fs.promises.access(p);
|
|
5182
|
-
return true;
|
|
5183
|
-
}
|
|
5184
|
-
catch {
|
|
5185
|
-
return false;
|
|
5207
|
+
async function createUniqueUploadFile(filePath) {
|
|
5208
|
+
const ext = path.extname(filePath);
|
|
5209
|
+
const base = filePath.slice(0, filePath.length - ext.length);
|
|
5210
|
+
for (let counter = 0;; counter++) {
|
|
5211
|
+
const candidate = counter === 0 ? filePath : `${base}_${counter}${ext}`;
|
|
5212
|
+
try {
|
|
5213
|
+
return { path: candidate, handle: await fs.promises.open(candidate, 'wx') };
|
|
5214
|
+
}
|
|
5215
|
+
catch (error) {
|
|
5216
|
+
if (error.code !== 'EEXIST')
|
|
5217
|
+
throw error;
|
|
5218
|
+
}
|
|
5186
5219
|
}
|
|
5187
5220
|
}
|
|
5188
5221
|
export default router;
|