From 307460f4a66e8d68df202a29bca5bd87742b1d6f Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Wed, 13 Aug 2025 21:45:45 +0600 Subject: [PATCH 01/15] [deps]: added `node-gyp@^11.0.0`; --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 99490a1d..91ca1ed9 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,10 @@ "devDependencies": { "@types/node": "20", "@types/progress": "^2.0.1", + "node-gyp": "^11.0.0", "node-test-github-reporter": "^1.2.0", "prettier": "^3.3.1", "tsx": "^4.10.5", "typescript": "^5.4.5" } -} +} \ No newline at end of file From 7870d74c70d9d52d344dd5926b8f0830903bbbfe Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Wed, 13 Aug 2025 21:46:21 +0600 Subject: [PATCH 02/15] [feature]: process killer w napi; --- lib/ctrlc.cc | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 lib/ctrlc.cc diff --git a/lib/ctrlc.cc b/lib/ctrlc.cc new file mode 100644 index 00000000..6bd06a0f --- /dev/null +++ b/lib/ctrlc.cc @@ -0,0 +1,149 @@ +#include +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +#include +#endif + +namespace ctrlc +{ + + using v8::FunctionCallbackInfo; + using v8::Isolate; + using v8::Local; + using v8::Object; + using v8::String; + using v8::Value; + + void SigintWindows(const v8::FunctionCallbackInfo &args) + { +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + v8::Isolate *isolate = args.GetIsolate(); + v8::HandleScope scope(isolate); + + // Check the number of arguments passed + if (args.Length() != 1) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, "Invalid arguments").ToLocalChecked(); + isolate->ThrowException(v8::Exception::TypeError(v8String)); + + return; + } + + // Check the argument types + if (!args[0]->IsUint32()) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, "Argument must be a number").ToLocalChecked(); + isolate->ThrowException(v8::Exception::TypeError(v8String)); + + return; + } + + DWORD processId = args[0]->Uint32Value(isolate->GetCurrentContext()).ToChecked(); + + HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, processId); + if (hProcess == NULL) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to open process. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + + return; + } + + // Try to attach to console + if (!AttachConsole(processId)) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to attach to console. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + + // If attaching to console fails, try sending Ctrl-C event directly + if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, processId)) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to send Ctrl-C event. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + + CloseHandle(hProcess); + + return; + } + else + { + args.GetReturnValue().Set(true); + return; + } + } + else + { + // Disable Ctrl-C handling for our program + if (!SetConsoleCtrlHandler(NULL, TRUE)) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to disable Ctrl-C handling. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + + CloseHandle(hProcess); + + return; + } + + // Send Ctrl-C event + if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to send Ctrl-C event. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + + // Re-enable Ctrl-C handling + if (!SetConsoleCtrlHandler(NULL, FALSE)) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to re-enable Ctrl-C handling. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + } + + FreeConsole(); + CloseHandle(hProcess); + return; + } + else + { + // Wait for process to exit + if (WaitForSingleObject(hProcess, 2000) != WAIT_OBJECT_0) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, "Process did not exit within 2 seconds.").ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + } + + // Re-enable Ctrl-C handling + if (!SetConsoleCtrlHandler(NULL, FALSE)) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to re-enable Ctrl-C handling. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + } + + FreeConsole(); + CloseHandle(hProcess); + return; + } + } + + // Re-enable Ctrl-C handling + if (!SetConsoleCtrlHandler(NULL, FALSE)) + { + v8::Local v8String = v8::String::NewFromUtf8(isolate, "Failed to re-enable Ctrl-C handling").ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + + CloseHandle(hProcess); + + return; + } + + FreeConsole(); + CloseHandle(hProcess); + args.GetReturnValue().Set(True(isolate)); +#endif + } + + void Init(Local exports) + { + NODE_SET_METHOD(exports, "sigintWindows", SigintWindows); + } + + NODE_MODULE(ctrlc, Init) + +} // namespace ctrlc \ No newline at end of file From f98040675c7d98a70cfdd35883bab15ffec8633f Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Wed, 13 Aug 2025 21:46:37 +0600 Subject: [PATCH 03/15] [lock]: regenerated lock file; --- yarn.lock | 624 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 624 insertions(+) diff --git a/yarn.lock b/yarn.lock index 91d3e4d0..7dad7aca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -155,6 +155,48 @@ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@isaacs/fs-minipass@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz#2d59ae3ab4b38fb4270bfa23d30f8e2e86c7fe32" + integrity sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w== + dependencies: + minipass "^7.0.4" + +"@npmcli/agent@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-3.0.0.tgz#1685b1fbd4a1b7bb4f930cbb68ce801edfe7aa44" + integrity sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q== + dependencies: + agent-base "^7.1.0" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.1" + lru-cache "^10.0.1" + socks-proxy-agent "^8.0.3" + +"@npmcli/fs@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-4.0.0.tgz#a1eb1aeddefd2a4a347eca0fab30bc62c0e1c0f2" + integrity sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q== + dependencies: + semver "^7.3.5" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@types/node@*": version "18.7.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83" @@ -174,16 +216,143 @@ dependencies: "@types/node" "*" +abbrev@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-3.0.1.tgz#8ac8b3b5024d31464fe2a5feeea9f4536bf44025" + integrity sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg== + +agent-base@^7.1.0, agent-base@^7.1.2: + version "7.1.4" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + b4a@^1.6.4: version "1.6.7" resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.7.tgz#a99587d4ebbfbd5a6e3b21bdb5d5fa385767abe4" integrity sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg== +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + bare-events@^2.2.0: version "2.5.0" resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.5.0.tgz#305b511e262ffd8b9d5616b056464f8e1b3329cc" integrity sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A== +brace-expansion@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== + dependencies: + balanced-match "^1.0.0" + +cacache@^19.0.1: + version "19.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-19.0.1.tgz#3370cc28a758434c85c2585008bd5bdcff17d6cd" + integrity sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ== + dependencies: + "@npmcli/fs" "^4.0.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^10.0.1" + minipass "^7.0.3" + minipass-collect "^2.0.1" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^7.0.2" + ssri "^12.0.0" + tar "^7.4.3" + unique-filename "^4.0.0" + +chownr@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-3.0.0.tgz#9855e64ecd240a9cc4267ce8a4aa5d24a1da15e4" + integrity sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g== + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@4, debug@^4.3.4: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== + dependencies: + ms "^2.1.3" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + error-stack-parser@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" @@ -226,11 +395,36 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +exponential-backoff@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91" + integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== + fast-fifo@^1.2.0, fast-fifo@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== +fdir@^6.4.4: + version "6.4.6" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.6.tgz#2b268c0232697063111bbf3f64810a2a741ba281" + integrity sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w== + +foreground-child@^3.1.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" + integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== + dependencies: + cross-spawn "^7.0.6" + signal-exit "^4.0.1" + +fs-minipass@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== + dependencies: + minipass "^7.0.3" + fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -243,6 +437,203 @@ get-tsconfig@^4.7.5: dependencies: resolve-pkg-maps "^1.0.0" +glob@^10.2.2: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +graceful-fs@^4.2.6: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +http-cache-semantics@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" + integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== + +http-proxy-agent@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + +https-proxy-agent@^7.0.1: + version "7.0.6" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== + dependencies: + agent-base "^7.1.2" + debug "4" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +ip-address@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.0.1.tgz#a8180b783ce7788777d796286d61bce4276818ed" + integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isexe@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" + integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== + +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +lru-cache@^10.0.1, lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +make-fetch-happen@^14.0.3: + version "14.0.3" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz#d74c3ecb0028f08ab604011e0bc6baed483fcdcd" + integrity sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ== + dependencies: + "@npmcli/agent" "^3.0.0" + cacache "^19.0.1" + http-cache-semantics "^4.1.1" + minipass "^7.0.2" + minipass-fetch "^4.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^1.0.0" + proc-log "^5.0.0" + promise-retry "^2.0.1" + ssri "^12.0.0" + +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minipass-collect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863" + integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw== + dependencies: + minipass "^7.0.3" + +minipass-fetch@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-4.0.1.tgz#f2d717d5a418ad0b1a7274f9b913515d3e78f9e5" + integrity sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ== + dependencies: + minipass "^7.0.3" + minipass-sized "^1.0.3" + minizlib "^3.0.1" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3, minipass@^7.0.4, minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +minizlib@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-3.0.2.tgz#f33d638eb279f664439aa38dc5f91607468cb574" + integrity sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA== + dependencies: + minipass "^7.1.2" + +mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + +node-gyp@^11.0.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-11.3.0.tgz#e543e3dcd69877e4a9a682ce355150c5d6a6947b" + integrity sha512-9J0+C+2nt3WFuui/mC46z2XCZ21/cKlFDuywULmseD/LlmnOrSeEAE4c/1jw6aybXLmpZnQY3/LmOJfgyHIcng== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + graceful-fs "^4.2.6" + make-fetch-happen "^14.0.3" + nopt "^8.0.0" + proc-log "^5.0.0" + semver "^7.3.5" + tar "^7.4.3" + tinyglobby "^0.2.12" + which "^5.0.0" + node-test-github-reporter@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/node-test-github-reporter/-/node-test-github-reporter-1.2.0.tgz#316914021ae66fc944c216080971da4d388e5283" @@ -258,16 +649,64 @@ node-test-parser@^2.2.1: resolved "https://registry.yarnpkg.com/node-test-parser/-/node-test-parser-2.2.2.tgz#486f0d0c08e31e6b341eadf6a9f574e8c53d8259" integrity sha512-Cbe0pabtJaZOrjvCguHe9kZLDrHZpRr+4+JO29hNf143qFUhGn6Xn5HxwQmh4vmyyLFlF2YmnJGIwfEX+aQ7mw== +nopt@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-8.1.0.tgz#b11d38caf0f8643ce885818518064127f602eae3" + integrity sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A== + dependencies: + abbrev "^3.0.0" + +p-map@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-7.0.3.tgz#7ac210a2d36f81ec28b736134810f7ba4418cdb6" + integrity sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA== + +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +picomatch@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" + integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== + prettier@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== +proc-log@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-5.0.0.tgz#e6c93cf37aef33f835c53485f314f50ea906a9d8" + integrity sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ== + progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + queue-tick@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" @@ -278,6 +717,67 @@ resolve-pkg-maps@^1.0.0: resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^7.3.5: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^8.0.3: + version "8.0.5" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz#b9cdb4e7e998509d7659d689ce7697ac21645bee" + integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw== + dependencies: + agent-base "^7.1.2" + debug "^4.3.4" + socks "^2.8.3" + +socks@^2.8.3: + version "2.8.7" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea" + integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A== + dependencies: + ip-address "^10.0.1" + smart-buffer "^4.2.0" + +ssri@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-12.0.0.tgz#bcb4258417c702472f8191981d3c8a771fee6832" + integrity sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ== + dependencies: + minipass "^7.0.3" + stack-utils@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -301,6 +801,54 @@ streamx@^2.15.0: optionalDependencies: bare-events "^2.2.0" +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + tar-stream@^3.1.7: version "3.1.7" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b" @@ -310,11 +858,31 @@ tar-stream@^3.1.7: fast-fifo "^1.2.0" streamx "^2.15.0" +tar@^7.4.3: + version "7.4.3" + resolved "https://registry.yarnpkg.com/tar/-/tar-7.4.3.tgz#88bbe9286a3fcd900e94592cda7a22b192e80571" + integrity sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw== + dependencies: + "@isaacs/fs-minipass" "^4.0.0" + chownr "^3.0.0" + minipass "^7.1.2" + minizlib "^3.0.1" + mkdirp "^3.0.1" + yallist "^5.0.0" + text-decoder@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/text-decoder/-/text-decoder-1.2.1.tgz#e173f5121d97bfa3ff8723429ad5ba92e1ead67e" integrity sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ== +tinyglobby@^0.2.12: + version "0.2.14" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d" + integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== + dependencies: + fdir "^6.4.4" + picomatch "^4.0.2" + tsx@^4.10.5: version "4.19.1" resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.1.tgz#b7bffdf4b565813e4dea14b90872af279cd0090b" @@ -346,3 +914,59 @@ undici@^5.25.4: integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== dependencies: "@fastify/busboy" "^2.0.0" + +unique-filename@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-4.0.0.tgz#a06534d370e7c977a939cd1d11f7f0ab8f1fed13" + integrity sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ== + dependencies: + unique-slug "^5.0.0" + +unique-slug@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-5.0.0.tgz#ca72af03ad0dbab4dad8aa683f633878b1accda8" + integrity sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg== + dependencies: + imurmurhash "^0.1.4" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/which/-/which-5.0.0.tgz#d93f2d93f79834d4363c7d0c23e00d07c466c8d6" + integrity sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ== + dependencies: + isexe "^3.1.1" + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yallist@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-5.0.0.tgz#00e2de443639ed0d78fd87de0d27469fbcffb533" + integrity sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw== From 03087b2bce8f505327154594f2fba4424e183c68 Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Wed, 13 Aug 2025 21:47:15 +0600 Subject: [PATCH 04/15] [feature]: registered process killer napi w node-gyp; --- binding.gyp | 1 + 1 file changed, 1 insertion(+) create mode 100644 binding.gyp diff --git a/binding.gyp b/binding.gyp new file mode 100644 index 00000000..58cdb172 --- /dev/null +++ b/binding.gyp @@ -0,0 +1 @@ +{"targets": [{"target_name": "ctrlc", "sources": ["lib/ctrlc.cc"]}]} From 6e3280c41495524b9fc324862b82761159da4ff8 Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Wed, 13 Aug 2025 21:49:25 +0600 Subject: [PATCH 05/15] [script]: to build napi; napi on post-install; --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 91ca1ed9..cec27e84 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,13 @@ "typings": "./build/lib/index.d.ts", "scripts": { "clean": "node script/clean.js", - "build": "yarn clean && tsc -p ./tsconfig.json && tsc -p ./examples/tsconfig.json", + "build": "yarn clean && yarn build:native && tsc -p ./tsconfig.json && tsc -p ./examples/tsconfig.json", + "build:native": "node-gyp rebuild", "prepack": "yarn build && yarn test", "postpublish": "git push --follow-tags", "test": "node script/test.mjs", "download-git": "node ./script/download-git.js", - "postinstall": "node ./script/download-git.js", + "postinstall": "node ./script/download-git.js && yarn build:native", "prettify": "prettier \"{examples,lib,script,test}/**/*.{ts,js,mjs}\" --write", "is-it-pretty": "prettier \"{examples,lib,script,test}/**/*.{ts,js,mjs}\" --check", "update-embedded-git": "node ./script/update-embedded-git.js" From a023e6398db8b391560e75a6b9696b695e046a0d Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 12:30:48 +0600 Subject: [PATCH 06/15] [feature]: integrate ctrl+c napi into ts; --- lib/process-termination.ts | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lib/process-termination.ts diff --git a/lib/process-termination.ts b/lib/process-termination.ts new file mode 100644 index 00000000..e4caff2a --- /dev/null +++ b/lib/process-termination.ts @@ -0,0 +1,44 @@ +import { ChildProcess } from 'child_process' + +let ctrlc: { sigintWindows: (pid: number) => boolean } | undefined + +// Only load the native addon on Windows and when it's available +if (process.platform === 'win32') { + try { + // @ts-ignore - Dynamic import of native module + ctrlc = require('./ctrlc.node') + } catch (error) { + // Native addon not available, fall back to regular termination + console.warn('dugite: Native Ctrl+C addon not available, using fallback termination method') + } +} + +/** + * Kill method to use Ctrl+C on Windows when available. + * This is a monkey-patche approach for the ChildProcess.kill method to keep the API consistent. + */ +export function processTerminator(childProcess: ChildProcess): void { + if (process.platform !== 'win32' || !ctrlc) { + return; + } + + const originalKill = childProcess.kill.bind(childProcess) + + childProcess.kill = function (signal?: NodeJS.Signals | number): boolean { + const pid = childProcess.pid + + // Try Ctrl+C first for SIGTERM/SIGINT on Windows, then fallback + if (pid && (signal === 'SIGTERM' || signal === 'SIGINT' || !signal)) { + try { + if (ctrlc!.sigintWindows(pid)) { + return true + } + } catch (_) { + // Fall through to original kill + } + } + + // Use original kill method being used as fallback here + return originalKill(signal) + } +} From c869cff9dc44cb1be6c97ef2e2e56b257edb071a Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 12:31:24 +0600 Subject: [PATCH 07/15] [feature]: integrate process terminator in `exec` and `spawn`; --- lib/exec.ts | 3 +++ lib/spawn.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/exec.ts b/lib/exec.ts index 06c50679..e82c3a6c 100644 --- a/lib/exec.ts +++ b/lib/exec.ts @@ -2,6 +2,7 @@ import { ChildProcess, execFile, ExecFileOptions } from 'child_process' import { setupEnvironment } from './git-environment' import { ExecError } from './errors' import { ignoreClosedInputStream } from './ignore-closed-input-stream' +import { processTerminator } from './process-termination' export interface IGitResult { /** The standard output from git. */ @@ -173,6 +174,8 @@ export function exec( ignoreClosedInputStream(cp) + processTerminator(cp) + if (options?.stdin !== undefined && cp.stdin) { // See https://github.com/nodejs/node/blob/7b5ffa46fe4d2868c1662694da06eb55ec744bde/test/parallel/test-stdin-pipe-large.js if (options.stdinEncoding) { diff --git a/lib/spawn.ts b/lib/spawn.ts index 688c466f..995dabfb 100644 --- a/lib/spawn.ts +++ b/lib/spawn.ts @@ -1,5 +1,6 @@ import { ignoreClosedInputStream } from './ignore-closed-input-stream' import { setupEnvironment } from './git-environment' +import { processTerminator } from './process-termination' import { spawn as _spawn } from 'child_process' /** @@ -28,5 +29,7 @@ export function spawn(args: string[], path: string, opts?: IGitSpawnOptions) { ignoreClosedInputStream(spawnedProcess) + processTerminator(spawnedProcess) + return spawnedProcess } From 6d88749033125e890a99a21874e0ea75de137402 Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 12:54:56 +0600 Subject: [PATCH 08/15] [script]: copy built native library to necessary places; --- script/copy-native.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 script/copy-native.js diff --git a/script/copy-native.js b/script/copy-native.js new file mode 100644 index 00000000..6dd46943 --- /dev/null +++ b/script/copy-native.js @@ -0,0 +1,23 @@ +const fs = require('fs'); +const path = require('path'); + +const rootDir = path.join(__dirname, '..'); // + +try { + // Copy to /lib/ctrlc.node + fs.copyFileSync( + path.join(rootDir, 'build', 'Release', 'ctrlc.node'), + path.join(rootDir, 'lib', 'ctrlc.node') + ); + + fs.mkdirSync(path.join(rootDir, 'build', 'lib'), { recursive: true }); + + // Copy to /build/lib/ctrlc.node + // attention if we switch swithc between `lib` or `build/lib` or `dist`, we need to update this + fs.copyFileSync( + path.join(rootDir, 'build', 'Release', 'ctrlc.node'), + path.join(rootDir, 'build', 'lib', 'ctrlc.node') + ); +} catch (e) { + console.warn('Warning: Could not copy native addon:', e.message); +} From 1330be1fe30b0a86cea29c45322ccb144194c18a Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 12:55:35 +0600 Subject: [PATCH 09/15] [script]: added native build and native copy in post install and build; --- package.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index cec27e84..3f2e00a7 100644 --- a/package.json +++ b/package.json @@ -6,13 +6,15 @@ "typings": "./build/lib/index.d.ts", "scripts": { "clean": "node script/clean.js", - "build": "yarn clean && yarn build:native && tsc -p ./tsconfig.json && tsc -p ./examples/tsconfig.json", - "build:native": "node-gyp rebuild", + "build": "yarn clean && yarn native:all && tsc -p ./tsconfig.json && tsc -p ./examples/tsconfig.json", + "native:all": "yarn native:build && yarn native:copy", + "native:build": "node-gyp rebuild", + "native:copy": "node ./script/copy-native.js", "prepack": "yarn build && yarn test", "postpublish": "git push --follow-tags", "test": "node script/test.mjs", "download-git": "node ./script/download-git.js", - "postinstall": "node ./script/download-git.js && yarn build:native", + "postinstall": "node ./script/download-git.js && yarn native:all", "prettify": "prettier \"{examples,lib,script,test}/**/*.{ts,js,mjs}\" --write", "is-it-pretty": "prettier \"{examples,lib,script,test}/**/*.{ts,js,mjs}\" --check", "update-embedded-git": "node ./script/update-embedded-git.js" From 0b609dab036429cfb82dfeadbd2ba5dc44ccc663 Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 12:56:38 +0600 Subject: [PATCH 10/15] [vcs]: ignore `.node` file as part of vcs; we build it on system --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d051b02b..54cc2904 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ build/ # git local install git/ +lib/ctrlc.node From ebb8e3f1ac5beedd650815673371661549e87363 Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 13:01:45 +0600 Subject: [PATCH 11/15] [test]: clone cancel test w large repo; --- test/slow/git-process-test.ts | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/slow/git-process-test.ts b/test/slow/git-process-test.ts index c4426ac4..6f846ae4 100644 --- a/test/slow/git-process-test.ts +++ b/test/slow/git-process-test.ts @@ -74,6 +74,50 @@ describe('git-process', () => { server.close() } }) + + it('can cancel clone operation with AbortController', async t => { + const testRepoPath = await createTestDir(t, 'desktop-git-clone-cancel') + const controller = new AbortController() + + // Cancel after 2 second to test cancellation during clone + // Cause those 4, 5 process creation takes a bit of time + const cancelTimeout = setTimeout(() => { + console.log('Cancelling git clone operation...') + controller.abort() + }, 2000) + + try { + // Using a real repository URL that's large enough to not complete instantly + const result = await exec( + [ + 'clone', + '--depth', '1', + 'http://github.com/maifeeulasad/maifeeulasad.github.io.git', + 'vscode-clone' + ], + testRepoPath, + { + signal: controller.signal, + processCallback: (process) => { + console.log(`Started git clone with PID: ${process.pid}`) + } + } + ) + + // If we get here, the clone completed before cancellation + console.log('Clone completed before cancellation') + verify(result, r => { + assert.equal(r.exitCode, 0) + }) + } catch (error: any) { + // This is expected when cancellation works + console.log(`Git clone was cancelled: ${error.code}`) + assert.equal(error.code, 'ABORT_ERR', 'Expected ABORT_ERR when clone is cancelled') + } finally { + clearTimeout(cancelTimeout) + } + }) + }) describe('fetch', () => { From 54eac232eb9b3cc105ad3deca7e8b04b258c2678 Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 13:09:01 +0600 Subject: [PATCH 12/15] [lint]: ran prettify; --- lib/process-termination.ts | 52 ++++++++++++++++++----------------- script/copy-native.js | 32 ++++++++++----------- test/slow/git-process-test.ts | 16 +++++++---- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/lib/process-termination.ts b/lib/process-termination.ts index e4caff2a..99229e9a 100644 --- a/lib/process-termination.ts +++ b/lib/process-termination.ts @@ -4,13 +4,15 @@ let ctrlc: { sigintWindows: (pid: number) => boolean } | undefined // Only load the native addon on Windows and when it's available if (process.platform === 'win32') { - try { - // @ts-ignore - Dynamic import of native module - ctrlc = require('./ctrlc.node') - } catch (error) { - // Native addon not available, fall back to regular termination - console.warn('dugite: Native Ctrl+C addon not available, using fallback termination method') - } + try { + // @ts-ignore - Dynamic import of native module + ctrlc = require('./ctrlc.node') + } catch (error) { + // Native addon not available, fall back to regular termination + console.warn( + 'dugite: Native Ctrl+C addon not available, using fallback termination method' + ) + } } /** @@ -18,27 +20,27 @@ if (process.platform === 'win32') { * This is a monkey-patche approach for the ChildProcess.kill method to keep the API consistent. */ export function processTerminator(childProcess: ChildProcess): void { - if (process.platform !== 'win32' || !ctrlc) { - return; - } + if (process.platform !== 'win32' || !ctrlc) { + return + } - const originalKill = childProcess.kill.bind(childProcess) + const originalKill = childProcess.kill.bind(childProcess) - childProcess.kill = function (signal?: NodeJS.Signals | number): boolean { - const pid = childProcess.pid + childProcess.kill = function (signal?: NodeJS.Signals | number): boolean { + const pid = childProcess.pid - // Try Ctrl+C first for SIGTERM/SIGINT on Windows, then fallback - if (pid && (signal === 'SIGTERM' || signal === 'SIGINT' || !signal)) { - try { - if (ctrlc!.sigintWindows(pid)) { - return true - } - } catch (_) { - // Fall through to original kill - } + // Try Ctrl+C first for SIGTERM/SIGINT on Windows, then fallback + if (pid && (signal === 'SIGTERM' || signal === 'SIGINT' || !signal)) { + try { + if (ctrlc!.sigintWindows(pid)) { + return true } - - // Use original kill method being used as fallback here - return originalKill(signal) + } catch (_) { + // Fall through to original kill + } } + + // Use original kill method being used as fallback here + return originalKill(signal) + } } diff --git a/script/copy-native.js b/script/copy-native.js index 6dd46943..5f482084 100644 --- a/script/copy-native.js +++ b/script/copy-native.js @@ -1,23 +1,23 @@ -const fs = require('fs'); -const path = require('path'); +const fs = require('fs') +const path = require('path') -const rootDir = path.join(__dirname, '..'); // +const rootDir = path.join(__dirname, '..') // try { - // Copy to /lib/ctrlc.node - fs.copyFileSync( - path.join(rootDir, 'build', 'Release', 'ctrlc.node'), - path.join(rootDir, 'lib', 'ctrlc.node') - ); + // Copy to /lib/ctrlc.node + fs.copyFileSync( + path.join(rootDir, 'build', 'Release', 'ctrlc.node'), + path.join(rootDir, 'lib', 'ctrlc.node') + ) - fs.mkdirSync(path.join(rootDir, 'build', 'lib'), { recursive: true }); + fs.mkdirSync(path.join(rootDir, 'build', 'lib'), { recursive: true }) - // Copy to /build/lib/ctrlc.node - // attention if we switch swithc between `lib` or `build/lib` or `dist`, we need to update this - fs.copyFileSync( - path.join(rootDir, 'build', 'Release', 'ctrlc.node'), - path.join(rootDir, 'build', 'lib', 'ctrlc.node') - ); + // Copy to /build/lib/ctrlc.node + // attention if we switch swithc between `lib` or `build/lib` or `dist`, we need to update this + fs.copyFileSync( + path.join(rootDir, 'build', 'Release', 'ctrlc.node'), + path.join(rootDir, 'build', 'lib', 'ctrlc.node') + ) } catch (e) { - console.warn('Warning: Could not copy native addon:', e.message); + console.warn('Warning: Could not copy native addon:', e.message) } diff --git a/test/slow/git-process-test.ts b/test/slow/git-process-test.ts index 6f846ae4..ddcd712f 100644 --- a/test/slow/git-process-test.ts +++ b/test/slow/git-process-test.ts @@ -91,16 +91,17 @@ describe('git-process', () => { const result = await exec( [ 'clone', - '--depth', '1', + '--depth', + '1', 'http://github.com/maifeeulasad/maifeeulasad.github.io.git', - 'vscode-clone' + 'vscode-clone', ], testRepoPath, { signal: controller.signal, - processCallback: (process) => { + processCallback: process => { console.log(`Started git clone with PID: ${process.pid}`) - } + }, } ) @@ -112,12 +113,15 @@ describe('git-process', () => { } catch (error: any) { // This is expected when cancellation works console.log(`Git clone was cancelled: ${error.code}`) - assert.equal(error.code, 'ABORT_ERR', 'Expected ABORT_ERR when clone is cancelled') + assert.equal( + error.code, + 'ABORT_ERR', + 'Expected ABORT_ERR when clone is cancelled' + ) } finally { clearTimeout(cancelTimeout) } }) - }) describe('fetch', () => { From 3ecb3459b7af3786001e5392ce047bbd3e4ca7b7 Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 14:23:43 +0600 Subject: [PATCH 13/15] [fix]: error handling in napi for `SigintWindows` for console attachment; --- lib/ctrlc.cc | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/lib/ctrlc.cc b/lib/ctrlc.cc index 6bd06a0f..39dde72d 100644 --- a/lib/ctrlc.cc +++ b/lib/ctrlc.cc @@ -51,24 +51,28 @@ namespace ctrlc // Try to attach to console if (!AttachConsole(processId)) { - v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to attach to console. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); - isolate->ThrowException(v8::Exception::Error(v8String)); + DWORD error = GetLastError(); - // If attaching to console fails, try sending Ctrl-C event directly - if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, processId)) + // If already attached to a console or no console, try direct termination + if (error == ERROR_ACCESS_DENIED || error == ERROR_INVALID_HANDLE) { - v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to send Ctrl-C event. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); - isolate->ThrowException(v8::Exception::Error(v8String)); + // Try to send Ctrl-C event directly to the process group + if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, processId)) + { + CloseHandle(hProcess); + args.GetReturnValue().Set(false); + return; + } CloseHandle(hProcess); - - return; - } - else - { args.GetReturnValue().Set(true); return; } + + v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to attach to console. Error code: " + std::to_string(error)).c_str()).ToLocalChecked(); + isolate->ThrowException(v8::Exception::Error(v8String)); + CloseHandle(hProcess); + return; } else { @@ -102,22 +106,15 @@ namespace ctrlc } else { - // Wait for process to exit - if (WaitForSingleObject(hProcess, 2000) != WAIT_OBJECT_0) - { - v8::Local v8String = v8::String::NewFromUtf8(isolate, "Process did not exit within 2 seconds.").ToLocalChecked(); - isolate->ThrowException(v8::Exception::Error(v8String)); - } + // Wait for process to exit (but don't fail if it takes longer) + WaitForSingleObject(hProcess, 2000); // Re-enable Ctrl-C handling - if (!SetConsoleCtrlHandler(NULL, FALSE)) - { - v8::Local v8String = v8::String::NewFromUtf8(isolate, ("Failed to re-enable Ctrl-C handling. Error code: " + std::to_string(GetLastError())).c_str()).ToLocalChecked(); - isolate->ThrowException(v8::Exception::Error(v8String)); - } + SetConsoleCtrlHandler(NULL, FALSE); FreeConsole(); CloseHandle(hProcess); + args.GetReturnValue().Set(true); return; } } @@ -135,7 +132,7 @@ namespace ctrlc FreeConsole(); CloseHandle(hProcess); - args.GetReturnValue().Set(True(isolate)); + args.GetReturnValue().Set(v8::Boolean::New(isolate, true)); #endif } From 816b3d4db7071143539f11b73952696ab356e89e Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 14:24:45 +0600 Subject: [PATCH 14/15] [fix]: refine process termination to explicit `SIGTERM`/`SIGINT`; --- lib/process-termination.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/process-termination.ts b/lib/process-termination.ts index 99229e9a..e95e936b 100644 --- a/lib/process-termination.ts +++ b/lib/process-termination.ts @@ -29,8 +29,8 @@ export function processTerminator(childProcess: ChildProcess): void { childProcess.kill = function (signal?: NodeJS.Signals | number): boolean { const pid = childProcess.pid - // Try Ctrl+C first for SIGTERM/SIGINT on Windows, then fallback - if (pid && (signal === 'SIGTERM' || signal === 'SIGINT' || !signal)) { + // Only try Ctrl+C for explicit SIGTERM/SIGINT signals on Windows + if (pid && (signal === 'SIGTERM' || signal === 'SIGINT')) { try { if (ctrlc!.sigintWindows(pid)) { return true From 2f63000b0088bc2ee36226fad1f4f82741283c8a Mon Sep 17 00:00:00 2001 From: Maifee Ul Asad Date: Thu, 14 Aug 2025 14:25:58 +0600 Subject: [PATCH 15/15] [test]: for clone abort test added delay before end; - for os to close all file and process handles; --- test/slow/git-process-test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/slow/git-process-test.ts b/test/slow/git-process-test.ts index ddcd712f..3cb08862 100644 --- a/test/slow/git-process-test.ts +++ b/test/slow/git-process-test.ts @@ -118,6 +118,11 @@ describe('git-process', () => { 'ABORT_ERR', 'Expected ABORT_ERR when clone is cancelled' ) + + // Wait 3 seconds after cancellation to allow file handles to be released + // 4,5 process takes a while to release as there are rolling file handles + console.log('Waiting 3 seconds for process cleanup...') + await new Promise(resolve => setTimeout(resolve, 3000)) } finally { clearTimeout(cancelTimeout) }