dsh-remote 0.8.46 → 0.8.47

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.
Files changed (391) hide show
  1. package/LICENSE +21 -21
  2. package/README.en.md +361 -361
  3. package/README.md +368 -368
  4. package/cordis.patch.yml +9 -9
  5. package/lib/binding.js +172 -172
  6. package/lib/client.js +3637 -3637
  7. package/lib/credential.js +177 -177
  8. package/lib/deploy-tasks.js +142 -142
  9. package/lib/errors.js +87 -87
  10. package/lib/file-reference.js +457 -457
  11. package/lib/forwards.js +258 -258
  12. package/lib/hostkey.js +108 -108
  13. package/lib/http-transport.js +196 -196
  14. package/lib/ignore.js +156 -156
  15. package/lib/index.js +3771 -3747
  16. package/lib/openssh.js +838 -838
  17. package/lib/paths.js +225 -225
  18. package/lib/pool.js +757 -757
  19. package/lib/registry.js +95 -95
  20. package/lib/remote-fs.js +148 -143
  21. package/lib/routes-fs.js +233 -233
  22. package/lib/search.js +230 -230
  23. package/lib/sftp-surface.js +76 -76
  24. package/lib/sshconfig.js +454 -454
  25. package/lib/sync.js +275 -275
  26. package/lib/tasks.js +95 -95
  27. package/lib/telemetry.js +213 -213
  28. package/lib/update.js +472 -472
  29. package/lib/web-attach.js +850 -850
  30. package/lib/web-deploy-skill.js +205 -205
  31. package/lib/web-deploy.js +694 -694
  32. package/node_modules/asn1/Jenkinsfile +65 -0
  33. package/node_modules/asn1/LICENSE +19 -0
  34. package/node_modules/asn1/README.md +50 -0
  35. package/node_modules/asn1/lib/ber/errors.js +13 -0
  36. package/node_modules/asn1/lib/ber/index.js +27 -0
  37. package/node_modules/asn1/lib/ber/reader.js +262 -0
  38. package/node_modules/asn1/lib/ber/types.js +36 -0
  39. package/node_modules/asn1/lib/ber/writer.js +317 -0
  40. package/node_modules/asn1/lib/index.js +20 -0
  41. package/node_modules/asn1/package.json +31 -0
  42. package/node_modules/bcrypt-pbkdf/CONTRIBUTING.md +13 -0
  43. package/node_modules/bcrypt-pbkdf/LICENSE +66 -0
  44. package/node_modules/bcrypt-pbkdf/README.md +45 -0
  45. package/node_modules/bcrypt-pbkdf/index.js +556 -0
  46. package/node_modules/bcrypt-pbkdf/package.json +15 -0
  47. package/node_modules/buildcheck/.eslintrc.js +5 -0
  48. package/node_modules/buildcheck/.github/workflows/ci.yml +88 -0
  49. package/node_modules/buildcheck/.github/workflows/lint.yml +27 -0
  50. package/node_modules/buildcheck/.npmignore +3 -0
  51. package/node_modules/buildcheck/LICENSE +19 -0
  52. package/node_modules/buildcheck/README.md +106 -0
  53. package/node_modules/buildcheck/deps/Find-VisualStudio.cs +250 -0
  54. package/node_modules/buildcheck/lib/findvs.js +361 -0
  55. package/node_modules/buildcheck/lib/index.js +738 -0
  56. package/node_modules/buildcheck/package.json +36 -0
  57. package/node_modules/buildcheck/test/test.js +8 -0
  58. package/node_modules/cpu-features/.eslintrc.js +5 -0
  59. package/node_modules/cpu-features/.github/workflows/ci.yml +74 -0
  60. package/node_modules/cpu-features/.github/workflows/lint.yml +27 -0
  61. package/node_modules/cpu-features/LICENSE +19 -0
  62. package/node_modules/cpu-features/README.md +59 -0
  63. package/node_modules/cpu-features/binding.gyp +16 -0
  64. package/node_modules/cpu-features/buildcheck.js +32 -0
  65. package/node_modules/cpu-features/deps/cpu_features/.clang-format +4 -0
  66. package/node_modules/cpu-features/deps/cpu_features/.dockerignore +31 -0
  67. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/Dockerfile +5 -0
  68. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/aarch64_linux_cmake.yml +30 -0
  69. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_freebsd_cmake.yml +22 -0
  70. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_bazel.yml +26 -0
  71. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_linux_cmake.yml +31 -0
  72. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_macos_cmake.yml +43 -0
  73. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/amd64_windows_cmake.yml +25 -0
  74. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/arm_linux_cmake.yml +31 -0
  75. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/clang_format.yml +24 -0
  76. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/mips_linux_cmake.yml +30 -0
  77. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/power_linux_cmake.yml +29 -0
  78. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/riscv_linux_cmake.yml +28 -0
  79. package/node_modules/cpu-features/deps/cpu_features/.github/workflows/s390x_linux_cmake.yml +27 -0
  80. package/node_modules/cpu-features/deps/cpu_features/.grenrc.yml +21 -0
  81. package/node_modules/cpu-features/deps/cpu_features/BUILD.bazel +329 -0
  82. package/node_modules/cpu-features/deps/cpu_features/CMakeLists.txt +261 -0
  83. package/node_modules/cpu-features/deps/cpu_features/CONTRIBUTING.md +23 -0
  84. package/node_modules/cpu-features/deps/cpu_features/LICENSE +230 -0
  85. package/node_modules/cpu-features/deps/cpu_features/README.md +272 -0
  86. package/node_modules/cpu-features/deps/cpu_features/WORKSPACE +19 -0
  87. package/node_modules/cpu-features/deps/cpu_features/bazel/ci/README.md +5 -0
  88. package/node_modules/cpu-features/deps/cpu_features/bazel/platforms.bzl +11 -0
  89. package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesConfig.cmake.in +3 -0
  90. package/node_modules/cpu-features/deps/cpu_features/cmake/CpuFeaturesNdkCompatConfig.cmake.in +3 -0
  91. package/node_modules/cpu-features/deps/cpu_features/cmake/README.md +30 -0
  92. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/Makefile +252 -0
  93. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/README.md +40 -0
  94. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.dot +64 -0
  95. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/docker.svg +312 -0
  96. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/doc/generate_image.sh +7 -0
  97. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/amd64/Dockerfile +48 -0
  98. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/docker/toolchain/Dockerfile +34 -0
  99. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/CMakeLists.txt +22 -0
  100. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/sample/main.cpp +11 -0
  101. package/node_modules/cpu-features/deps/cpu_features/cmake/ci/vagrant/freebsd/Vagrantfile +107 -0
  102. package/node_modules/cpu-features/deps/cpu_features/cmake/googletest.CMakeLists.txt.in +15 -0
  103. package/node_modules/cpu-features/deps/cpu_features/cpu_features.gyp +105 -0
  104. package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_cache_info.h +54 -0
  105. package/node_modules/cpu-features/deps/cpu_features/include/cpu_features_macros.h +384 -0
  106. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_aarch64.h +259 -0
  107. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_arm.h +121 -0
  108. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_mips.h +74 -0
  109. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_ppc.h +149 -0
  110. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_riscv.h +72 -0
  111. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_s390x.h +108 -0
  112. package/node_modules/cpu-features/deps/cpu_features/include/cpuinfo_x86.h +288 -0
  113. package/node_modules/cpu-features/deps/cpu_features/include/internal/bit_utils.h +40 -0
  114. package/node_modules/cpu-features/deps/cpu_features/include/internal/cpuid_x86.h +37 -0
  115. package/node_modules/cpu-features/deps/cpu_features/include/internal/filesystem.h +39 -0
  116. package/node_modules/cpu-features/deps/cpu_features/include/internal/hwcaps.h +240 -0
  117. package/node_modules/cpu-features/deps/cpu_features/include/internal/stack_line_reader.h +49 -0
  118. package/node_modules/cpu-features/deps/cpu_features/include/internal/string_view.h +110 -0
  119. package/node_modules/cpu-features/deps/cpu_features/include/internal/windows_utils.h +70 -0
  120. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/CMakeLists.txt +60 -0
  121. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/README.md +4 -0
  122. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.c +205 -0
  123. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/cpu-features.h +320 -0
  124. package/node_modules/cpu-features/deps/cpu_features/ndk_compat/ndk-compat-test.c +12 -0
  125. package/node_modules/cpu-features/deps/cpu_features/patches/0001-Add-Apple-Silicon-Support.patch +456 -0
  126. package/node_modules/cpu-features/deps/cpu_features/scripts/generate_badges.d +165 -0
  127. package/node_modules/cpu-features/deps/cpu_features/scripts/make_release.sh +75 -0
  128. package/node_modules/cpu-features/deps/cpu_features/scripts/run_integration.sh +490 -0
  129. package/node_modules/cpu-features/deps/cpu_features/scripts/test_integration.sh +79 -0
  130. package/node_modules/cpu-features/deps/cpu_features/src/copy.inl +19 -0
  131. package/node_modules/cpu-features/deps/cpu_features/src/define_introspection.inl +86 -0
  132. package/node_modules/cpu-features/deps/cpu_features/src/define_introspection_and_hwcaps.inl +26 -0
  133. package/node_modules/cpu-features/deps/cpu_features/src/equals.inl +22 -0
  134. package/node_modules/cpu-features/deps/cpu_features/src/filesystem.c +62 -0
  135. package/node_modules/cpu-features/deps/cpu_features/src/hwcaps.c +169 -0
  136. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64__base_implementation.inl +88 -0
  137. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_linux_or_android.c +79 -0
  138. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_macos_or_iphone.c +82 -0
  139. package/node_modules/cpu-features/deps/cpu_features/src/impl_aarch64_windows.c +138 -0
  140. package/node_modules/cpu-features/deps/cpu_features/src/impl_arm_linux_or_android.c +212 -0
  141. package/node_modules/cpu-features/deps/cpu_features/src/impl_mips_linux_or_android.c +93 -0
  142. package/node_modules/cpu-features/deps/cpu_features/src/impl_ppc_linux.c +163 -0
  143. package/node_modules/cpu-features/deps/cpu_features/src/impl_riscv_linux.c +111 -0
  144. package/node_modules/cpu-features/deps/cpu_features/src/impl_s390x_linux.c +120 -0
  145. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86__base_implementation.inl +2055 -0
  146. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_freebsd.c +68 -0
  147. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_linux_or_android.c +58 -0
  148. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_macos.c +57 -0
  149. package/node_modules/cpu-features/deps/cpu_features/src/impl_x86_windows.c +58 -0
  150. package/node_modules/cpu-features/deps/cpu_features/src/stack_line_reader.c +132 -0
  151. package/node_modules/cpu-features/deps/cpu_features/src/string_view.c +192 -0
  152. package/node_modules/cpu-features/deps/cpu_features/src/utils/list_cpu_features.c +461 -0
  153. package/node_modules/cpu-features/deps/cpu_features/test/CMakeLists.txt +114 -0
  154. package/node_modules/cpu-features/deps/cpu_features/test/bit_utils_test.cc +53 -0
  155. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_aarch64_test.cc +396 -0
  156. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_arm_test.cc +384 -0
  157. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_mips_test.cc +176 -0
  158. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_ppc_test.cc +131 -0
  159. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_riscv_test.cc +180 -0
  160. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_s390x_test.cc +82 -0
  161. package/node_modules/cpu-features/deps/cpu_features/test/cpuinfo_x86_test.cc +1729 -0
  162. package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.cc +103 -0
  163. package/node_modules/cpu-features/deps/cpu_features/test/filesystem_for_testing.h +61 -0
  164. package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.cc +52 -0
  165. package/node_modules/cpu-features/deps/cpu_features/test/hwcaps_for_testing.h +31 -0
  166. package/node_modules/cpu-features/deps/cpu_features/test/stack_line_reader_test.cc +132 -0
  167. package/node_modules/cpu-features/deps/cpu_features/test/string_view_test.cc +202 -0
  168. package/node_modules/cpu-features/lib/index.js +5 -0
  169. package/node_modules/cpu-features/package.json +40 -0
  170. package/node_modules/cpu-features/src/binding.cc +151 -0
  171. package/node_modules/cpu-features/test/test.js +12 -0
  172. package/node_modules/nan/.github/workflows/ci.yml +46 -0
  173. package/node_modules/nan/.pre-commit-config.yaml +8 -0
  174. package/node_modules/nan/CHANGELOG.md +605 -0
  175. package/node_modules/nan/CMakeLists.txt +138 -0
  176. package/node_modules/nan/LICENSE.md +9 -0
  177. package/node_modules/nan/README.md +457 -0
  178. package/node_modules/nan/doc/asyncworker.md +146 -0
  179. package/node_modules/nan/doc/buffers.md +54 -0
  180. package/node_modules/nan/doc/callback.md +76 -0
  181. package/node_modules/nan/doc/converters.md +41 -0
  182. package/node_modules/nan/doc/errors.md +226 -0
  183. package/node_modules/nan/doc/json.md +62 -0
  184. package/node_modules/nan/doc/maybe_types.md +583 -0
  185. package/node_modules/nan/doc/methods.md +689 -0
  186. package/node_modules/nan/doc/new.md +147 -0
  187. package/node_modules/nan/doc/node_misc.md +123 -0
  188. package/node_modules/nan/doc/object_wrappers.md +263 -0
  189. package/node_modules/nan/doc/persistent.md +296 -0
  190. package/node_modules/nan/doc/scopes.md +73 -0
  191. package/node_modules/nan/doc/script.md +58 -0
  192. package/node_modules/nan/doc/string_bytes.md +81 -0
  193. package/node_modules/nan/doc/v8_internals.md +211 -0
  194. package/node_modules/nan/doc/v8_misc.md +85 -0
  195. package/node_modules/nan/include_dirs.js +1 -0
  196. package/node_modules/nan/nan.h +3202 -0
  197. package/node_modules/nan/nan_callbacks.h +141 -0
  198. package/node_modules/nan/nan_callbacks_12_inl.h +730 -0
  199. package/node_modules/nan/nan_callbacks_pre_12_inl.h +528 -0
  200. package/node_modules/nan/nan_converters.h +72 -0
  201. package/node_modules/nan/nan_converters_43_inl.h +68 -0
  202. package/node_modules/nan/nan_converters_pre_43_inl.h +42 -0
  203. package/node_modules/nan/nan_define_own_property_helper.h +29 -0
  204. package/node_modules/nan/nan_implementation_12_inl.h +446 -0
  205. package/node_modules/nan/nan_implementation_pre_12_inl.h +263 -0
  206. package/node_modules/nan/nan_json.h +166 -0
  207. package/node_modules/nan/nan_maybe_43_inl.h +360 -0
  208. package/node_modules/nan/nan_maybe_pre_43_inl.h +268 -0
  209. package/node_modules/nan/nan_new.h +340 -0
  210. package/node_modules/nan/nan_object_wrap.h +156 -0
  211. package/node_modules/nan/nan_persistent_12_inl.h +132 -0
  212. package/node_modules/nan/nan_persistent_pre_12_inl.h +242 -0
  213. package/node_modules/nan/nan_private.h +73 -0
  214. package/node_modules/nan/nan_scriptorigin.h +97 -0
  215. package/node_modules/nan/nan_string_bytes.h +305 -0
  216. package/node_modules/nan/nan_typedarray_contents.h +96 -0
  217. package/node_modules/nan/nan_weak.h +453 -0
  218. package/node_modules/nan/package.json +38 -0
  219. package/node_modules/nan/tools/1to2.js +412 -0
  220. package/node_modules/nan/tools/README.md +14 -0
  221. package/node_modules/nan/tools/package.json +19 -0
  222. package/node_modules/safer-buffer/LICENSE +21 -0
  223. package/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  224. package/node_modules/safer-buffer/Readme.md +156 -0
  225. package/node_modules/safer-buffer/dangerous.js +58 -0
  226. package/node_modules/safer-buffer/package.json +34 -0
  227. package/node_modules/safer-buffer/safer.js +77 -0
  228. package/node_modules/safer-buffer/tests.js +406 -0
  229. package/node_modules/ssh2/.eslintignore +4 -0
  230. package/node_modules/ssh2/.eslintrc.js +5 -0
  231. package/node_modules/ssh2/.github/workflows/ci.yml +110 -0
  232. package/node_modules/ssh2/.github/workflows/lint.yml +27 -0
  233. package/node_modules/ssh2/LICENSE +19 -0
  234. package/node_modules/ssh2/README.md +1529 -0
  235. package/node_modules/ssh2/SFTP.md +413 -0
  236. package/node_modules/ssh2/examples/server-chat.js +238 -0
  237. package/node_modules/ssh2/examples/sftp-server-download-only.js +134 -0
  238. package/node_modules/ssh2/install.js +27 -0
  239. package/node_modules/ssh2/lib/Channel.js +295 -0
  240. package/node_modules/ssh2/lib/agent.js +1123 -0
  241. package/node_modules/ssh2/lib/client.js +2176 -0
  242. package/node_modules/ssh2/lib/http-agents.js +84 -0
  243. package/node_modules/ssh2/lib/index.js +44 -0
  244. package/node_modules/ssh2/lib/keygen.js +582 -0
  245. package/node_modules/ssh2/lib/protocol/Protocol.js +2136 -0
  246. package/node_modules/ssh2/lib/protocol/SFTP.js +4052 -0
  247. package/node_modules/ssh2/lib/protocol/constants.js +356 -0
  248. package/node_modules/ssh2/lib/protocol/crypto/binding.gyp +23 -0
  249. package/node_modules/ssh2/lib/protocol/crypto/poly1305.js +43 -0
  250. package/node_modules/ssh2/lib/protocol/crypto/src/binding.cc +2300 -0
  251. package/node_modules/ssh2/lib/protocol/crypto.js +1602 -0
  252. package/node_modules/ssh2/lib/protocol/handlers.js +16 -0
  253. package/node_modules/ssh2/lib/protocol/handlers.misc.js +1285 -0
  254. package/node_modules/ssh2/lib/protocol/kex.js +1908 -0
  255. package/node_modules/ssh2/lib/protocol/keyParser.js +1484 -0
  256. package/node_modules/ssh2/lib/protocol/node-fs-compat.js +115 -0
  257. package/node_modules/ssh2/lib/protocol/utils.js +356 -0
  258. package/node_modules/ssh2/lib/protocol/zlib.js +255 -0
  259. package/node_modules/ssh2/lib/server.js +1380 -0
  260. package/node_modules/ssh2/lib/utils.js +336 -0
  261. package/node_modules/ssh2/package.json +49 -0
  262. package/node_modules/ssh2/test/common.js +316 -0
  263. package/node_modules/ssh2/test/fixtures/bad_rsa_private_key +26 -0
  264. package/node_modules/ssh2/test/fixtures/https_cert.pem +33 -0
  265. package/node_modules/ssh2/test/fixtures/https_key.pem +52 -0
  266. package/node_modules/ssh2/test/fixtures/id_dsa +12 -0
  267. package/node_modules/ssh2/test/fixtures/id_ecdsa +5 -0
  268. package/node_modules/ssh2/test/fixtures/id_rsa +15 -0
  269. package/node_modules/ssh2/test/fixtures/id_rsa.ppk +26 -0
  270. package/node_modules/ssh2/test/fixtures/id_rsa_enc +30 -0
  271. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa +21 -0
  272. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub +1 -0
  273. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.pub.result +7 -0
  274. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa.result +7 -0
  275. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc +22 -0
  276. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub +1 -0
  277. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.pub.result +7 -0
  278. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc.result +7 -0
  279. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm +23 -0
  280. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub +1 -0
  281. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.pub.result +7 -0
  282. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_dsa_enc_gcm.result +7 -0
  283. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa +9 -0
  284. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub +1 -0
  285. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.pub.result +7 -0
  286. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa.result +7 -0
  287. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc +10 -0
  288. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub +1 -0
  289. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.pub.result +8 -0
  290. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc.result +7 -0
  291. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm +10 -0
  292. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub +1 -0
  293. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.pub.result +8 -0
  294. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ecdsa_enc_gcm.result +7 -0
  295. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519 +7 -0
  296. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub +1 -0
  297. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.pub.result +7 -0
  298. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_ed25519.result +7 -0
  299. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa +27 -0
  300. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub +1 -0
  301. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.pub.result +7 -0
  302. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa.result +7 -0
  303. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc +28 -0
  304. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub +1 -0
  305. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.pub.result +8 -0
  306. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc.result +7 -0
  307. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm +29 -0
  308. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub +1 -0
  309. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.pub.result +8 -0
  310. package/node_modules/ssh2/test/fixtures/keyParser/openssh_new_rsa_enc_gcm.result +7 -0
  311. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa +12 -0
  312. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub +1 -0
  313. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.pub.result +7 -0
  314. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa.result +7 -0
  315. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc +15 -0
  316. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub +1 -0
  317. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.pub.result +8 -0
  318. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_dsa_enc.result +7 -0
  319. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa +5 -0
  320. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub +1 -0
  321. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.pub.result +7 -0
  322. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa.result +7 -0
  323. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc +8 -0
  324. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub +1 -0
  325. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.pub.result +8 -0
  326. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_ecdsa_enc.result +7 -0
  327. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa +27 -0
  328. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub +1 -0
  329. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.pub.result +7 -0
  330. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa.result +7 -0
  331. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc +30 -0
  332. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub +1 -0
  333. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.pub.result +8 -0
  334. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc.result +7 -0
  335. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256 +54 -0
  336. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub +1 -0
  337. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.pub.result +6 -0
  338. package/node_modules/ssh2/test/fixtures/keyParser/openssh_old_rsa_enc_aes256.result +6 -0
  339. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc +17 -0
  340. package/node_modules/ssh2/test/fixtures/keyParser/ppk_dsa_enc.result +7 -0
  341. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa +26 -0
  342. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa.result +7 -0
  343. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc +18 -0
  344. package/node_modules/ssh2/test/fixtures/keyParser/ppk_rsa_enc.result +7 -0
  345. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub +9 -0
  346. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa.pub.result +7 -0
  347. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub +10 -0
  348. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa2.pub.result +7 -0
  349. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub +11 -0
  350. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa3.pub.result +7 -0
  351. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub +11 -0
  352. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa4.pub.result +7 -0
  353. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub +8 -0
  354. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa5.pub.result +7 -0
  355. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub +13 -0
  356. package/node_modules/ssh2/test/fixtures/keyParser/rfc4716_rsa6.pub.result +7 -0
  357. package/node_modules/ssh2/test/fixtures/openssh_new_rsa +27 -0
  358. package/node_modules/ssh2/test/fixtures/ssh_host_dsa_key +12 -0
  359. package/node_modules/ssh2/test/fixtures/ssh_host_ecdsa_key +5 -0
  360. package/node_modules/ssh2/test/fixtures/ssh_host_rsa_key +15 -0
  361. package/node_modules/ssh2/test/test-exec.js +578 -0
  362. package/node_modules/ssh2/test/test-integration-openssh.js +486 -0
  363. package/node_modules/ssh2/test/test-keygen.js +60 -0
  364. package/node_modules/ssh2/test/test-misc-client-server.js +1460 -0
  365. package/node_modules/ssh2/test/test-openssh.js +261 -0
  366. package/node_modules/ssh2/test/test-protocol-crypto.js +631 -0
  367. package/node_modules/ssh2/test/test-protocol-keyparser.js +177 -0
  368. package/node_modules/ssh2/test/test-server-hostkeys.js +138 -0
  369. package/node_modules/ssh2/test/test-sftp.js +842 -0
  370. package/node_modules/ssh2/test/test-shell.js +109 -0
  371. package/node_modules/ssh2/test/test-userauth-agent-openssh.js +110 -0
  372. package/node_modules/ssh2/test/test-userauth-agent.js +171 -0
  373. package/node_modules/ssh2/test/test-userauth.js +611 -0
  374. package/node_modules/ssh2/test/test-worker-imports.js +25 -0
  375. package/node_modules/ssh2/test/test.js +20 -0
  376. package/node_modules/ssh2/util/build_pagent.bat +2 -0
  377. package/node_modules/ssh2/util/pagent.c +88 -0
  378. package/node_modules/ssh2/util/pagent.exe +0 -0
  379. package/node_modules/tweetnacl/.npmignore +4 -0
  380. package/node_modules/tweetnacl/AUTHORS.md +28 -0
  381. package/node_modules/tweetnacl/CHANGELOG.md +221 -0
  382. package/node_modules/tweetnacl/LICENSE +24 -0
  383. package/node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md +20 -0
  384. package/node_modules/tweetnacl/README.md +459 -0
  385. package/node_modules/tweetnacl/nacl-fast.js +2388 -0
  386. package/node_modules/tweetnacl/nacl-fast.min.js +2 -0
  387. package/node_modules/tweetnacl/nacl.d.ts +98 -0
  388. package/node_modules/tweetnacl/nacl.js +1175 -0
  389. package/node_modules/tweetnacl/nacl.min.js +1 -0
  390. package/node_modules/tweetnacl/package.json +58 -0
  391. package/package.json +95 -89
package/lib/routes-fs.js CHANGED
@@ -1,233 +1,233 @@
1
- // Sidebar file routes: /ls /read /write /fs.
2
- //
3
- // Machine-scoped callers (workspace picker, settings) omit sessionId and use
4
- // the active-machine pool. Session-scoped callers (explorer / file tab) MUST
5
- // pass sessionId (or local=mirror cwd); those requests resolve through the
6
- // same mirror binding as rw_* tools and never fall back to the active machine.
7
- import { mkdirSync } from 'node:fs'
8
- import path from 'node:path'
9
- import {
10
- normalizeRemotePath, joinRemotePath, remoteDirname, mkdirRemoteDirs, toDisplayPath,
11
- } from './paths.js'
12
- import { requestSessionHint } from './binding.js'
13
- import { listDirStructured, listRemoteDrives, removeRemoteTree, previewRemoteFile } from './remote-fs.js'
14
-
15
- export function createFsRoutes({
16
- sendJson,
17
- readBody,
18
- resolveRequestBinding,
19
- decodeBuf,
20
- encodeText,
21
- audit,
22
- config,
23
- mirrorDirFor,
24
- }) {
25
- const bindOrReply = async (req, res, body = {}) => {
26
- try {
27
- return await resolveRequestBinding(req, body)
28
- } catch (err) {
29
- sendJson(res, (err && err.httpStatus) || 500, { ok: false, error: String((err && err.message) || err) })
30
- return null
31
- }
32
- }
33
-
34
- return [
35
- {
36
- kind: 'exact',
37
- path: '/dsh-remote/ls',
38
- handler: async (req, res) => {
39
- try {
40
- const hint = requestSessionHint(req)
41
- const b = await bindOrReply(req, res, hint)
42
- if (!b) return
43
- // Identity echo (external-switch defense): name the machine this
44
- // listing is answered for, straight from the pool's target — the
45
- // picker validates every listing against the machine it INTENDED and
46
- // re-switches on mismatch (the settings page can change the active
47
- // machine under a memoized picker).
48
- const tgt = (b.pool && b.pool.config) || {}
49
- const machine = {
50
- host: String(tgt.host || b.host || ''),
51
- port: Number(tgt.port) || Number(b.port) || 22,
52
- username: String(tgt.username || b.username || ''),
53
- }
54
- await b.pool.detect()
55
- const q = new URL(req.url, 'http://localhost').searchParams
56
- const raw = q.get('path') ? decodeURIComponent(q.get('path')) : (b.ws || '')
57
- const canon = normalizeRemotePath(raw)
58
- const win = b.pool.platform === 'windows'
59
- if (canon === '/' || raw === '' || raw === '/') {
60
- if (win || b.pool.platform !== 'posix') {
61
- const drives = await listRemoteDrives(b.pool)
62
- if (drives.length) return sendJson(res, 200, { path: '', platform: 'windows', items: drives, bound: b.bound, machine })
63
- }
64
- if (win) return sendJson(res, 200, { path: '', platform: 'windows', items: [], bound: b.bound, machine })
65
- }
66
- const sftp = await b.pool.sftp()
67
- const out = await listDirStructured(sftp, canon)
68
- const items = out.items.map((it) => ({
69
- ...it,
70
- path: toDisplayPath(joinRemotePath(canon, it.name), b.pool.platform),
71
- }))
72
- return sendJson(res, 200, {
73
- path: toDisplayPath(out.path, b.pool.platform),
74
- platform: win ? 'windows' : 'posix',
75
- items,
76
- missing: !!out.missing,
77
- bound: b.bound,
78
- machine,
79
- })
80
- } catch (err) {
81
- return sendJson(res, 500, { error: String((err && err.message) || err) })
82
- }
83
- },
84
- },
85
- {
86
- kind: 'exact',
87
- path: '/dsh-remote/read',
88
- handler: async (req, res) => {
89
- if (req.method !== 'GET' && req.method !== 'POST') return sendJson(res, 405, { ok: false, error: 'method not allowed' })
90
- try {
91
- const q = new URL(req.url, 'http://localhost').searchParams
92
- let p = q.get('path') ? decodeURIComponent(q.get('path')) : ''
93
- let encoding = ''
94
- let maxBytes = 256 * 1024
95
- let body = {}
96
- if (req.method === 'POST') {
97
- body = JSON.parse((await readBody(req)) || '{}')
98
- if (!p) p = String(body.path || '')
99
- if (body.encoding) encoding = String(body.encoding)
100
- if (body.maxBytes) maxBytes = Number(body.maxBytes)
101
- }
102
- if (q.get('maxBytes')) maxBytes = Number(q.get('maxBytes'))
103
- if (!p) return sendJson(res, 400, { ok: false, error: 'path is required' })
104
- const b = await bindOrReply(req, res, body)
105
- if (!b) return
106
- const target = normalizeRemotePath(p)
107
- let sftp
108
- try {
109
- sftp = await b.pool.sftp()
110
- } catch (err) {
111
- return sendJson(res, 500, { ok: false, error: 'sftp unavailable: ' + ((err && err.message) || err) })
112
- }
113
- try {
114
- const preview = await previewRemoteFile(sftp, target, {
115
- maxBytes,
116
- encoding: encoding || config.encoding,
117
- decodeBuf,
118
- })
119
- return sendJson(res, 200, preview)
120
- } catch (err) {
121
- return sendJson(res, 500, { ok: false, error: 'read failed: ' + ((err && err.message) || err) })
122
- }
123
- } catch (err) {
124
- return sendJson(res, 500, { ok: false, error: String((err && err.message) || err) })
125
- }
126
- },
127
- },
128
- {
129
- kind: 'exact',
130
- path: '/dsh-remote/write',
131
- handler: async (req, res) => {
132
- if (req.method !== 'POST') return sendJson(res, 405, { ok: false, error: 'method not allowed' })
133
- try {
134
- const body = JSON.parse((await readBody(req)) || '{}')
135
- const p = normalizeRemotePath(String(body.path || ''))
136
- if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path is required' })
137
- const b = await bindOrReply(req, res, body)
138
- if (!b) return
139
- const sftp = await b.pool.sftp()
140
- let st = null
141
- try { st = await sftp.stat(p) } catch { /* new file */ }
142
- if (body.expectedMtime != null && st && st.mtime !== Number(body.expectedMtime)) {
143
- return sendJson(res, 409, { ok: false, error: `远端文件已变化(mtime ${st.mtime} ≠ ${body.expectedMtime}),已放弃保存——请重新读取后再编辑` })
144
- }
145
- const buf = encodeText(String(body.content ?? ''), body.encoding || config.encoding)
146
- if (!st) await mkdirRemoteDirs(sftp, remoteDirname(p))
147
- await sftp.writeFile(p, buf)
148
- audit('write', `write ${p}`, 0, b)
149
- const st2 = await sftp.stat(p).catch(() => null)
150
- return sendJson(res, 200, { ok: true, bytes: buf.byteLength, mtime: st2 ? st2.mtime : Math.floor(Date.now() / 1000) })
151
- } catch (err) {
152
- return sendJson(res, 500, { ok: false, error: String((err && err.message) || err) })
153
- }
154
- },
155
- },
156
- {
157
- kind: 'exact',
158
- path: '/dsh-remote/fs',
159
- handler: async (req, res) => {
160
- if (req.method !== 'POST') return sendJson(res, 405, { ok: false, error: 'method not allowed' })
161
- try {
162
- const body = JSON.parse((await readBody(req)) || '{}')
163
- const op = String(body.op || '')
164
- const b = await bindOrReply(req, res, body)
165
- if (!b) return
166
- const sftp = await b.pool.sftp()
167
- if (op === 'mkdir') {
168
- const p = normalizeRemotePath(String(body.path || ''))
169
- if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
170
- await mkdirRemoteDirs(sftp, p)
171
- audit('mkdir', `mkdir ${p}`, 0, b)
172
- return sendJson(res, 200, { ok: true })
173
- }
174
- if (op === 'rename') {
175
- const p = normalizeRemotePath(String(body.path || ''))
176
- const d = normalizeRemotePath(String(body.dest || ''))
177
- if (!p || !d) return sendJson(res, 400, { ok: false, error: 'path and dest required' })
178
- await sftp.rename(p, d)
179
- audit('move', `move ${p} → ${d}`, 0, b)
180
- return sendJson(res, 200, { ok: true })
181
- }
182
- if (op === 'remove') {
183
- const p = normalizeRemotePath(String(body.path || ''))
184
- if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
185
- const st = await sftp.stat(p).catch(() => null)
186
- if (!st) return sendJson(res, 404, { ok: false, error: 'not found' })
187
- if (st.isDirectory && st.isDirectory()) {
188
- await removeRemoteTree(sftp, p)
189
- } else {
190
- await sftp.unlink(p)
191
- }
192
- audit('remove', `remove ${p}`, 0, b)
193
- return sendJson(res, 200, { ok: true })
194
- }
195
- if (op === 'write' || op === 'append') {
196
- const p = normalizeRemotePath(String(body.path || ''))
197
- if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
198
- let content = ''
199
- if (op === 'append') {
200
- try { content = decodeBuf(await sftp.readFile(p), body.encoding || config.encoding) } catch { /* new */ }
201
- }
202
- const buf = encodeText(content + String(body.content ?? ''), body.encoding || config.encoding)
203
- if (op === 'write' && !(await sftp.stat(p).catch(() => null))) await mkdirRemoteDirs(sftp, remoteDirname(p))
204
- await sftp.writeFile(p, buf)
205
- audit(op, `${op} ${p}`, 0, b)
206
- return sendJson(res, 200, { ok: true, bytes: buf.byteLength })
207
- }
208
- if (op === 'download') {
209
- const p = normalizeRemotePath(String(body.path || ''))
210
- const ws = b.ws
211
- if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
212
- if (!ws) return sendJson(res, 400, { ok: false, error: 'no remote workspace set' })
213
- const st = await sftp.stat(p).catch(() => null)
214
- if (!st) return sendJson(res, 404, { ok: false, error: 'not found' })
215
- if (config.maxFileBytes > 0 && st.size > config.maxFileBytes) {
216
- return sendJson(res, 400, { ok: false, error: `file is ${st.size} bytes (over ${config.maxFileBytes} cap)` })
217
- }
218
- const base = b.mirrorDir || mirrorDirFor(ws, b.host, b.username, b.port)
219
- const rel = p.startsWith(ws) ? p.slice(ws.length).replace(/^\/+/, '') : p.slice(1)
220
- const local = path.join(base, rel)
221
- mkdirSync(path.dirname(local), { recursive: true })
222
- await sftp.fastGet(p, local)
223
- audit('download', `download ${p}`, 0, b)
224
- return sendJson(res, 200, { ok: true, bytes: st.size, local })
225
- }
226
- return sendJson(res, 400, { ok: false, error: 'unknown op' })
227
- } catch (err) {
228
- return sendJson(res, 500, { ok: false, error: String((err && err.message) || err) })
229
- }
230
- },
231
- },
232
- ]
233
- }
1
+ // Sidebar file routes: /ls /read /write /fs.
2
+ //
3
+ // Machine-scoped callers (workspace picker, settings) omit sessionId and use
4
+ // the active-machine pool. Session-scoped callers (explorer / file tab) MUST
5
+ // pass sessionId (or local=mirror cwd); those requests resolve through the
6
+ // same mirror binding as rw_* tools and never fall back to the active machine.
7
+ import { mkdirSync } from 'node:fs'
8
+ import path from 'node:path'
9
+ import {
10
+ normalizeRemotePath, joinRemotePath, remoteDirname, mkdirRemoteDirs, toDisplayPath,
11
+ } from './paths.js'
12
+ import { requestSessionHint } from './binding.js'
13
+ import { listDirStructured, listRemoteDrives, removeRemoteTree, previewRemoteFile } from './remote-fs.js'
14
+
15
+ export function createFsRoutes({
16
+ sendJson,
17
+ readBody,
18
+ resolveRequestBinding,
19
+ decodeBuf,
20
+ encodeText,
21
+ audit,
22
+ config,
23
+ mirrorDirFor,
24
+ }) {
25
+ const bindOrReply = async (req, res, body = {}) => {
26
+ try {
27
+ return await resolveRequestBinding(req, body)
28
+ } catch (err) {
29
+ sendJson(res, (err && err.httpStatus) || 500, { ok: false, error: String((err && err.message) || err) })
30
+ return null
31
+ }
32
+ }
33
+
34
+ return [
35
+ {
36
+ kind: 'exact',
37
+ path: '/dsh-remote/ls',
38
+ handler: async (req, res) => {
39
+ try {
40
+ const hint = requestSessionHint(req)
41
+ const b = await bindOrReply(req, res, hint)
42
+ if (!b) return
43
+ // Identity echo (external-switch defense): name the machine this
44
+ // listing is answered for, straight from the pool's target — the
45
+ // picker validates every listing against the machine it INTENDED and
46
+ // re-switches on mismatch (the settings page can change the active
47
+ // machine under a memoized picker).
48
+ const tgt = (b.pool && b.pool.config) || {}
49
+ const machine = {
50
+ host: String(tgt.host || b.host || ''),
51
+ port: Number(tgt.port) || Number(b.port) || 22,
52
+ username: String(tgt.username || b.username || ''),
53
+ }
54
+ await b.pool.detect()
55
+ const q = new URL(req.url, 'http://localhost').searchParams
56
+ const raw = q.get('path') ? decodeURIComponent(q.get('path')) : (b.ws || '')
57
+ const canon = normalizeRemotePath(raw)
58
+ const win = b.pool.platform === 'windows'
59
+ if (canon === '/' || raw === '' || raw === '/') {
60
+ if (win || b.pool.platform !== 'posix') {
61
+ const drives = await listRemoteDrives(b.pool)
62
+ if (drives.length) return sendJson(res, 200, { path: '', platform: 'windows', items: drives, bound: b.bound, machine })
63
+ }
64
+ if (win) return sendJson(res, 200, { path: '', platform: 'windows', items: [], bound: b.bound, machine })
65
+ }
66
+ const sftp = await b.pool.sftp()
67
+ const out = await listDirStructured(sftp, canon)
68
+ const items = out.items.map((it) => ({
69
+ ...it,
70
+ path: toDisplayPath(joinRemotePath(canon, it.name), b.pool.platform),
71
+ }))
72
+ return sendJson(res, 200, {
73
+ path: toDisplayPath(out.path, b.pool.platform),
74
+ platform: win ? 'windows' : 'posix',
75
+ items,
76
+ missing: !!out.missing,
77
+ bound: b.bound,
78
+ machine,
79
+ })
80
+ } catch (err) {
81
+ return sendJson(res, 500, { error: String((err && err.message) || err) })
82
+ }
83
+ },
84
+ },
85
+ {
86
+ kind: 'exact',
87
+ path: '/dsh-remote/read',
88
+ handler: async (req, res) => {
89
+ if (req.method !== 'GET' && req.method !== 'POST') return sendJson(res, 405, { ok: false, error: 'method not allowed' })
90
+ try {
91
+ const q = new URL(req.url, 'http://localhost').searchParams
92
+ let p = q.get('path') ? decodeURIComponent(q.get('path')) : ''
93
+ let encoding = ''
94
+ let maxBytes = 256 * 1024
95
+ let body = {}
96
+ if (req.method === 'POST') {
97
+ body = JSON.parse((await readBody(req)) || '{}')
98
+ if (!p) p = String(body.path || '')
99
+ if (body.encoding) encoding = String(body.encoding)
100
+ if (body.maxBytes) maxBytes = Number(body.maxBytes)
101
+ }
102
+ if (q.get('maxBytes')) maxBytes = Number(q.get('maxBytes'))
103
+ if (!p) return sendJson(res, 400, { ok: false, error: 'path is required' })
104
+ const b = await bindOrReply(req, res, body)
105
+ if (!b) return
106
+ const target = normalizeRemotePath(p)
107
+ let sftp
108
+ try {
109
+ sftp = await b.pool.sftp()
110
+ } catch (err) {
111
+ return sendJson(res, 500, { ok: false, error: 'sftp unavailable: ' + ((err && err.message) || err) })
112
+ }
113
+ try {
114
+ const preview = await previewRemoteFile(sftp, target, {
115
+ maxBytes,
116
+ encoding: encoding || config.encoding,
117
+ decodeBuf,
118
+ })
119
+ return sendJson(res, 200, preview)
120
+ } catch (err) {
121
+ return sendJson(res, 500, { ok: false, error: 'read failed: ' + ((err && err.message) || err) })
122
+ }
123
+ } catch (err) {
124
+ return sendJson(res, 500, { ok: false, error: String((err && err.message) || err) })
125
+ }
126
+ },
127
+ },
128
+ {
129
+ kind: 'exact',
130
+ path: '/dsh-remote/write',
131
+ handler: async (req, res) => {
132
+ if (req.method !== 'POST') return sendJson(res, 405, { ok: false, error: 'method not allowed' })
133
+ try {
134
+ const body = JSON.parse((await readBody(req)) || '{}')
135
+ const p = normalizeRemotePath(String(body.path || ''))
136
+ if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path is required' })
137
+ const b = await bindOrReply(req, res, body)
138
+ if (!b) return
139
+ const sftp = await b.pool.sftp()
140
+ let st = null
141
+ try { st = await sftp.stat(p) } catch { /* new file */ }
142
+ if (body.expectedMtime != null && st && st.mtime !== Number(body.expectedMtime)) {
143
+ return sendJson(res, 409, { ok: false, error: `远端文件已变化(mtime ${st.mtime} ≠ ${body.expectedMtime}),已放弃保存——请重新读取后再编辑` })
144
+ }
145
+ const buf = encodeText(String(body.content ?? ''), body.encoding || config.encoding)
146
+ if (!st) await mkdirRemoteDirs(sftp, remoteDirname(p))
147
+ await sftp.writeFile(p, buf)
148
+ audit('write', `write ${p}`, 0, b)
149
+ const st2 = await sftp.stat(p).catch(() => null)
150
+ return sendJson(res, 200, { ok: true, bytes: buf.byteLength, mtime: st2 ? st2.mtime : Math.floor(Date.now() / 1000) })
151
+ } catch (err) {
152
+ return sendJson(res, 500, { ok: false, error: String((err && err.message) || err) })
153
+ }
154
+ },
155
+ },
156
+ {
157
+ kind: 'exact',
158
+ path: '/dsh-remote/fs',
159
+ handler: async (req, res) => {
160
+ if (req.method !== 'POST') return sendJson(res, 405, { ok: false, error: 'method not allowed' })
161
+ try {
162
+ const body = JSON.parse((await readBody(req)) || '{}')
163
+ const op = String(body.op || '')
164
+ const b = await bindOrReply(req, res, body)
165
+ if (!b) return
166
+ const sftp = await b.pool.sftp()
167
+ if (op === 'mkdir') {
168
+ const p = normalizeRemotePath(String(body.path || ''))
169
+ if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
170
+ await mkdirRemoteDirs(sftp, p)
171
+ audit('mkdir', `mkdir ${p}`, 0, b)
172
+ return sendJson(res, 200, { ok: true })
173
+ }
174
+ if (op === 'rename') {
175
+ const p = normalizeRemotePath(String(body.path || ''))
176
+ const d = normalizeRemotePath(String(body.dest || ''))
177
+ if (!p || !d) return sendJson(res, 400, { ok: false, error: 'path and dest required' })
178
+ await sftp.rename(p, d)
179
+ audit('move', `move ${p} → ${d}`, 0, b)
180
+ return sendJson(res, 200, { ok: true })
181
+ }
182
+ if (op === 'remove') {
183
+ const p = normalizeRemotePath(String(body.path || ''))
184
+ if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
185
+ const st = await sftp.stat(p).catch(() => null)
186
+ if (!st) return sendJson(res, 404, { ok: false, error: 'not found' })
187
+ if (st.isDirectory && st.isDirectory()) {
188
+ await removeRemoteTree(sftp, p)
189
+ } else {
190
+ await sftp.unlink(p)
191
+ }
192
+ audit('remove', `remove ${p}`, 0, b)
193
+ return sendJson(res, 200, { ok: true })
194
+ }
195
+ if (op === 'write' || op === 'append') {
196
+ const p = normalizeRemotePath(String(body.path || ''))
197
+ if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
198
+ let content = ''
199
+ if (op === 'append') {
200
+ try { content = decodeBuf(await sftp.readFile(p), body.encoding || config.encoding) } catch { /* new */ }
201
+ }
202
+ const buf = encodeText(content + String(body.content ?? ''), body.encoding || config.encoding)
203
+ if (op === 'write' && !(await sftp.stat(p).catch(() => null))) await mkdirRemoteDirs(sftp, remoteDirname(p))
204
+ await sftp.writeFile(p, buf)
205
+ audit(op, `${op} ${p}`, 0, b)
206
+ return sendJson(res, 200, { ok: true, bytes: buf.byteLength })
207
+ }
208
+ if (op === 'download') {
209
+ const p = normalizeRemotePath(String(body.path || ''))
210
+ const ws = b.ws
211
+ if (!p || p === '/') return sendJson(res, 400, { ok: false, error: 'path required' })
212
+ if (!ws) return sendJson(res, 400, { ok: false, error: 'no remote workspace set' })
213
+ const st = await sftp.stat(p).catch(() => null)
214
+ if (!st) return sendJson(res, 404, { ok: false, error: 'not found' })
215
+ if (config.maxFileBytes > 0 && st.size > config.maxFileBytes) {
216
+ return sendJson(res, 400, { ok: false, error: `file is ${st.size} bytes (over ${config.maxFileBytes} cap)` })
217
+ }
218
+ const base = b.mirrorDir || mirrorDirFor(ws, b.host, b.username, b.port)
219
+ const rel = p.startsWith(ws) ? p.slice(ws.length).replace(/^\/+/, '') : p.slice(1)
220
+ const local = path.join(base, rel)
221
+ mkdirSync(path.dirname(local), { recursive: true })
222
+ await sftp.fastGet(p, local)
223
+ audit('download', `download ${p}`, 0, b)
224
+ return sendJson(res, 200, { ok: true, bytes: st.size, local })
225
+ }
226
+ return sendJson(res, 400, { ok: false, error: 'unknown op' })
227
+ } catch (err) {
228
+ return sendJson(res, 500, { ok: false, error: String((err && err.message) || err) })
229
+ }
230
+ },
231
+ },
232
+ ]
233
+ }