Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 31ff6f6e28 | |||
| 2946169360 | |||
| 7490da22c0 | |||
| 3b2a5982a2 | |||
| 099eff0b1e | |||
| 3a56040c5b |
19
changelog.md
19
changelog.md
@@ -1,5 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-03-27 - 3.6.3 - fix(tapbundle_serverside)
|
||||
add TapNodeTools cleanup hooks to stop SmartNetwork processes after tests
|
||||
|
||||
- replace the exported tapNodeTools singleton with a TapNodeTools class that registers cleanup on the tap instance
|
||||
- run registered cleanup functions at the end of tap.start() to prevent lingering background processes from keeping Node.js alive
|
||||
- stop SmartNetwork after selecting Chromium runtime ports and update smartnetwork to ^4.5.2
|
||||
|
||||
## 2026-03-27 - 3.6.2 - fix(cli,chromium-runtime)
|
||||
clean up long-lived test runner resources after runs to prevent hanging processes
|
||||
|
||||
- call TsTest.cleanup() after non-watch CLI runs so smartexit handlers are deregistered
|
||||
- terminate active WebSocket clients before closing the Chromium runtime server to release open connections cleanly
|
||||
|
||||
## 2026-03-26 - 3.6.1 - fix(chromium runtime)
|
||||
encode Chromium test bundle names correctly for nested file paths
|
||||
|
||||
- Use replaceAll() so bundle cache filenames consistently handle test paths with multiple directory separators.
|
||||
- URL-encode the bundleName query parameter before opening the Chromium test page to avoid lookup issues with generated bundle filenames.
|
||||
|
||||
## 2026-03-24 - 3.6.0 - feat(config)
|
||||
migrate project metadata to .smartconfig and refresh build configuration
|
||||
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"target": "ES2022"
|
||||
},
|
||||
"nodeModulesDir": true,
|
||||
"version": "3.6.0"
|
||||
"version": "3.6.3"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@git.zone/tstest",
|
||||
"version": "3.6.0",
|
||||
"version": "3.6.3",
|
||||
"private": false,
|
||||
"description": "A powerful, modern test runner for TypeScript with multi-runtime support (Node.js, Deno, Bun, Chromium) and a batteries-included test framework.",
|
||||
"exports": {
|
||||
@@ -43,7 +43,7 @@
|
||||
"@push.rocks/smartjson": "^6.0.0",
|
||||
"@push.rocks/smartlog": "^3.2.1",
|
||||
"@push.rocks/smartmongo": "^5.1.0",
|
||||
"@push.rocks/smartnetwork": "^4.4.0",
|
||||
"@push.rocks/smartnetwork": "^4.5.2",
|
||||
"@push.rocks/smartpath": "^6.0.0",
|
||||
"@push.rocks/smartpromise": "^4.2.3",
|
||||
"@push.rocks/smartrequest": "^5.0.1",
|
||||
|
||||
224
pnpm-lock.yaml
generated
224
pnpm-lock.yaml
generated
@@ -51,8 +51,8 @@ importers:
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0(socks@2.8.7)
|
||||
'@push.rocks/smartnetwork':
|
||||
specifier: ^4.4.0
|
||||
version: 4.4.0
|
||||
specifier: ^4.5.2
|
||||
version: 4.5.2
|
||||
'@push.rocks/smartpath':
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
@@ -661,89 +661,105 @@ packages:
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
@@ -948,9 +964,6 @@ packages:
|
||||
resolution: {integrity: sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@leichtgewicht/ip-codec@2.0.5':
|
||||
resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==}
|
||||
|
||||
'@lit-labs/ssr-dom-shim@1.4.0':
|
||||
resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==}
|
||||
|
||||
@@ -1104,8 +1117,8 @@ packages:
|
||||
'@push.rocks/smartdelay@3.0.5':
|
||||
resolution: {integrity: sha512-mUuI7kj2f7ztjpic96FvRIlf2RsKBa5arw81AHNsndbxO6asRcxuWL8dTVxouEIK8YsBUlj0AsrCkHhMbLQdHw==}
|
||||
|
||||
'@push.rocks/smartdns@7.6.1':
|
||||
resolution: {integrity: sha512-nnP5+A2GOt0WsHrYhtKERmjdEHUchc+QbCCBEqlyeQTn+mNfx2WZvKVI1DFRJt8lamvzxP6Hr/BSe3WHdh4Snw==}
|
||||
'@push.rocks/smartdns@7.9.0':
|
||||
resolution: {integrity: sha512-1nDUfyXQo6j9HTUfcjE+BLeAv9QZ7WtAsM1V28zIoFdUpjNg/5g382L024H73PHsxh6lSYNhYYmFvWqzFQhXKg==}
|
||||
|
||||
'@push.rocks/smartenv@5.0.13':
|
||||
resolution: {integrity: sha512-ACXmUcHZHl2CF2jnVuRw9saRRrZvJblCRs2d+K5aLR1DfkYFX3eA21kcMlKeLisI3aGNbIj9vz/rowN5qkRkfA==}
|
||||
@@ -1179,8 +1192,8 @@ packages:
|
||||
'@push.rocks/smartmongo@5.1.0':
|
||||
resolution: {integrity: sha512-2tpKf8K+SMdLHOEpafgKPIN+ypWTLwHc33hCUDNMQ1KaL7vokkavA44+fHxQydOGPMtDi22tSMFeVMCcUSzs4w==}
|
||||
|
||||
'@push.rocks/smartnetwork@4.4.0':
|
||||
resolution: {integrity: sha512-OvFtz41cvQ7lcXwaIOhghNUUlNoMxvwKDctbDvMyuZyEH08SpLjhyv2FuKbKL/mgwA/WxakTbohoC8SW7t+kiw==}
|
||||
'@push.rocks/smartnetwork@4.5.2':
|
||||
resolution: {integrity: sha512-lbMMyc2f/WWd5+qzZyF1ynXndjCtasxPWmj/d8GUuis9rDrW7sLIT1PlAPC2F6Qsy4H/K32JrYU+01d/6sWObg==}
|
||||
|
||||
'@push.rocks/smartnpm@2.0.6':
|
||||
resolution: {integrity: sha512-7anKDOjX6gXWs1IAc+YWz9ZZ8gDsTwaLh+CxRnGHjAawOmK788NrrgVCg2Fb3qojrPnoxecc46F8Ivp1BT7Izw==}
|
||||
@@ -1197,9 +1210,6 @@ packages:
|
||||
'@push.rocks/smartpdf@4.2.0':
|
||||
resolution: {integrity: sha512-+egzby5QKJGO10MDvWp+N69cJ8i5M354l9ntc+uLRpxuq/FEY9kigpRwMvRYF5qwOBTuGTLqvmvILzlLtboAQg==}
|
||||
|
||||
'@push.rocks/smartping@1.0.8':
|
||||
resolution: {integrity: sha512-Fvx1Db6hSsDOI6pdiCuS9GjtOX8ugx865YQrPg5vK2iw6Qj/srwyXcWLFYt+19WVKtvtWDJIAKbW+q3bXFsCeA==}
|
||||
|
||||
'@push.rocks/smartpromise@4.2.3':
|
||||
resolution: {integrity: sha512-Ycg/TJR+tMt+S3wSFurOpEoW6nXv12QBtKXgBcjMZ4RsdO28geN46U09osPn9N9WuwQy1PkmTV5J/V4F9U8qEw==}
|
||||
|
||||
@@ -1325,36 +1335,42 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.11':
|
||||
resolution: {integrity: sha512-jfndI9tsfm4APzjNt6QdBkYwre5lRPUgHeDHoI7ydKUuJvz3lZeCfMsI56BZj+7BYqiKsJm7cfd/6KYV7ubrBg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.11':
|
||||
resolution: {integrity: sha512-ZlFgw46NOAGMgcdvdYwAGu2Q+SLFA9LzbJLW+iyMOJyhj5wk6P3KEE9Gct4xWwSzFoPI7JCdYmYMzVtlgQ+zfw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.0.0-rc.11':
|
||||
resolution: {integrity: sha512-hIOYmuT6ofM4K04XAZd3OzMySEO4K0/nc9+jmNcxNAxRi6c5UWpqfw3KMFV4MVFWL+jQsSh+bGw2VqmaPMTLyw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.11':
|
||||
resolution: {integrity: sha512-qXBQQO9OvkjjQPLdUVr7Nr2t3QTZI7s4KZtfw7HzBgjbmAPSFwSv4rmET9lLSgq3rH/ndA3ngv3Qb8l2njoPNA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-rc.11':
|
||||
resolution: {integrity: sha512-/tpFfoSTzUkH9LPY+cYbqZBDyyX62w5fICq9qzsHLL8uTI6BHip3Q9Uzft0wylk/i8OOwKik8OxW+QAhDmzwmg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-rc.11':
|
||||
resolution: {integrity: sha512-mcp3Rio2w72IvdZG0oQ4bM2c2oumtwHfUfKncUM6zGgz0KgPz4YmDPQfnXEiY5t3+KD/i8HG2rOB/LxdmieK2g==}
|
||||
@@ -1396,21 +1412,25 @@ packages:
|
||||
resolution: {integrity: sha512-Z4reus7UxGM4+JuhiIht8KuGP1KgM7nNhOlXUHcQCMswP/Rymj5oJQN3TDWgijFUZs09ULl8t3T+AQAVTd/WvA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rspack/binding-linux-arm64-musl@1.7.10':
|
||||
resolution: {integrity: sha512-LYaoVmWizG4oQ3g+St3eM5qxsyfH07kLirP7NJcDMgvu3eQ29MeyTZ3ugkgW6LvlmJue7eTQyf6CZlanoF5SSg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rspack/binding-linux-x64-gnu@1.7.10':
|
||||
resolution: {integrity: sha512-aIm2G4Kcm3qxDTNqKarK0oaLY2iXnCmpRQQhAcMlR0aS2LmxL89XzVeRr9GFA1MzGrAsZONWCLkxQvn3WUbm4Q==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rspack/binding-linux-x64-musl@1.7.10':
|
||||
resolution: {integrity: sha512-SIHQbAgB9IPH0H3H+i5rN5jo9yA/yTMq8b7XfRkTMvZ7P7MXxJ0dE8EJu3BmCLM19sqnTc2eX+SVfE8ZMDzghA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rspack/binding-wasm32-wasi@1.7.10':
|
||||
resolution: {integrity: sha512-J9HDXHD1tj+9FmX4+K3CTkO7dCE2bootlR37YuC2Owc0Lwl1/i2oGT71KHnMqI9faF/hipAaQM5OywkiiuNB7w==}
|
||||
@@ -1712,21 +1732,12 @@ packages:
|
||||
'@tybys/wasm-util@0.10.1':
|
||||
resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
|
||||
|
||||
'@types/bn.js@5.2.0':
|
||||
resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==}
|
||||
|
||||
'@types/clean-css@4.2.11':
|
||||
resolution: {integrity: sha512-Y8n81lQVTAfP2TOdtJJEsCoYl1AnOkqDqMvXb9/7pfgZZ7r8YrEyurrAvAoAjHOGXKRybay+5CsExqIH6liccw==}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
||||
'@types/dns-packet@5.6.5':
|
||||
resolution: {integrity: sha512-qXOC7XLOEe43ehtWJCMnQXvgcIpv6rPmQ1jXT98Ad8A3TB1Ue50jsCbSSSyuazScEuZ/Q026vHbrOTVkmwA+7Q==}
|
||||
|
||||
'@types/elliptic@6.4.18':
|
||||
resolution: {integrity: sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==}
|
||||
|
||||
'@types/fs-extra@11.0.4':
|
||||
resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==}
|
||||
|
||||
@@ -1775,9 +1786,6 @@ packages:
|
||||
'@types/node@25.5.0':
|
||||
resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==}
|
||||
|
||||
'@types/ping@0.4.4':
|
||||
resolution: {integrity: sha512-ifvo6w2f5eJYlXm+HiVx67iJe8WZp87sfa683nlqED5Vnt9Z93onkokNoWqOG21EaE8fMxyKPobE+mkPEyxsdw==}
|
||||
|
||||
'@types/relateurl@0.2.33':
|
||||
resolution: {integrity: sha512-bTQCKsVbIdzLqZhLkF5fcJQreE4y1ro4DIyVrlDNSCJRRwHhB8Z+4zXXa8jN6eDvc2HbRsEYgbvrnGvi54EpSw==}
|
||||
|
||||
@@ -1913,6 +1921,10 @@ packages:
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
balanced-match@4.0.4:
|
||||
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
bare-events@2.8.2:
|
||||
resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==}
|
||||
peerDependencies:
|
||||
@@ -1961,9 +1973,6 @@ packages:
|
||||
bmp-ts@1.0.9:
|
||||
resolution: {integrity: sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==}
|
||||
|
||||
bn.js@4.12.2:
|
||||
resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==}
|
||||
|
||||
bowser@2.12.1:
|
||||
resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==}
|
||||
|
||||
@@ -1973,12 +1982,13 @@ packages:
|
||||
brace-expansion@2.0.2:
|
||||
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
|
||||
|
||||
brace-expansion@5.0.5:
|
||||
resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
broadcast-channel@7.2.0:
|
||||
resolution: {integrity: sha512-JgraikEriG/TxBUi2W/w2O0jhHjXZUtXAvCZH0Yr3whjxYVgAg0hSe6r/teM+I5H5Q/q6RhyuKdC2pHNlFyepQ==}
|
||||
|
||||
brorand@1.1.0:
|
||||
resolution: {integrity: sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=}
|
||||
|
||||
bson@6.10.4:
|
||||
resolution: {integrity: sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==}
|
||||
engines: {node: '>=16.20.1'}
|
||||
@@ -2163,10 +2173,6 @@ packages:
|
||||
devtools-protocol@0.0.1581282:
|
||||
resolution: {integrity: sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==}
|
||||
|
||||
dns-packet@5.6.1:
|
||||
resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -2174,9 +2180,6 @@ packages:
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
elliptic@6.6.1:
|
||||
resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
@@ -2439,9 +2442,6 @@ packages:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hash.js@1.1.7:
|
||||
resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -2459,9 +2459,6 @@ packages:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
hasBin: true
|
||||
|
||||
hmac-drbg@1.0.1:
|
||||
resolution: {integrity: sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=}
|
||||
|
||||
html-minifier@4.0.0:
|
||||
resolution: {integrity: sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -2557,9 +2554,6 @@ packages:
|
||||
resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
isopen@1.3.0:
|
||||
resolution: {integrity: sha512-AN6Q9J0UlqHFl1fN/2xJCHCBLCBCFDjZhpGBO1gh3wzgRPsFSFBUL36I2Lbfd9qkuoj58axmE7j83iejTQsk8Q==}
|
||||
|
||||
jackspeak@4.1.1:
|
||||
resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
|
||||
engines: {node: 20 || >=22}
|
||||
@@ -2652,6 +2646,10 @@ packages:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
maxmind@5.0.5:
|
||||
resolution: {integrity: sha512-1lcH2kMjbBpCFhuHaMU32vz8CuOsKttRcWMQyXvtlklopCzN7NNHSVR/h9RYa8JPuFTGmkn2vYARm+7cIGuqDw==}
|
||||
engines: {node: '>=12', npm: '>=6'}
|
||||
|
||||
mdast-util-find-and-replace@3.0.2:
|
||||
resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
|
||||
|
||||
@@ -2810,16 +2808,14 @@ packages:
|
||||
mingo@7.2.0:
|
||||
resolution: {integrity: sha512-UeX942qZpofn5L97h295SkS7j/ADf7Qac8gdRCMBPxi0/1m70aeB2owLFvWbyuMj1dowonlivlVRQVDx+6h+7Q==}
|
||||
|
||||
minimalistic-assert@1.0.1:
|
||||
resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
|
||||
|
||||
minimalistic-crypto-utils@1.0.1:
|
||||
resolution: {integrity: sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=}
|
||||
|
||||
minimatch@10.1.1:
|
||||
resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
minimatch@10.2.4:
|
||||
resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
@@ -2837,6 +2833,10 @@ packages:
|
||||
mitt@3.0.1:
|
||||
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
|
||||
|
||||
mmdb-lib@3.0.2:
|
||||
resolution: {integrity: sha512-7e87vk0DdWT647wjcfEtWeMtjm+zVGqNohN/aeIymbUfjHQ2T4Sx5kM+1irVDBSloNC3CkGKxswdMoo8yhqTDg==}
|
||||
engines: {node: '>=10', npm: '>=6'}
|
||||
|
||||
mongodb-connection-string-url@3.0.2:
|
||||
resolution: {integrity: sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==}
|
||||
|
||||
@@ -3043,10 +3043,6 @@ packages:
|
||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ping@0.4.4:
|
||||
resolution: {integrity: sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
pixelmatch@5.3.0:
|
||||
resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==}
|
||||
hasBin: true
|
||||
@@ -3324,12 +3320,6 @@ packages:
|
||||
symbol-tree@3.2.4:
|
||||
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
|
||||
|
||||
systeminformation@5.27.11:
|
||||
resolution: {integrity: sha512-K3Lto/2m3K2twmKHdgx5B+0in9qhXK4YnoT9rIlgwN/4v7OV5c8IjbeAUkuky/6VzCQC7iKCAqi8rZathCdjHg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
|
||||
hasBin: true
|
||||
|
||||
tagged-tag@1.0.0:
|
||||
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
|
||||
engines: {node: '>=20'}
|
||||
@@ -3355,6 +3345,10 @@ packages:
|
||||
through@2.3.8:
|
||||
resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=}
|
||||
|
||||
tiny-lru@11.4.7:
|
||||
resolution: {integrity: sha512-w/Te7uMUVeH0CR8vZIjr+XiN41V+30lkDdK+NRIDCUYKKuL9VcmaUEmaPISuwGhLlrTGh5yu18lENtR9axSxYw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
tiny-worker@2.3.0:
|
||||
resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==}
|
||||
|
||||
@@ -4784,8 +4778,6 @@ snapshots:
|
||||
'@jimp/types': 1.6.0
|
||||
tinycolor2: 1.6.0
|
||||
|
||||
'@leichtgewicht/ip-codec@2.0.5': {}
|
||||
|
||||
'@lit-labs/ssr-dom-shim@1.4.0': {}
|
||||
|
||||
'@lit/reactive-element@2.1.1':
|
||||
@@ -5185,19 +5177,15 @@ snapshots:
|
||||
dependencies:
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
|
||||
'@push.rocks/smartdns@7.6.1':
|
||||
'@push.rocks/smartdns@7.9.0':
|
||||
dependencies:
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartenv': 5.0.13
|
||||
'@push.rocks/smartenv': 6.0.0
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/smartrequest': 2.1.0
|
||||
'@tsclass/tsclass': 9.4.0
|
||||
'@types/dns-packet': 5.6.5
|
||||
'@types/elliptic': 6.4.18
|
||||
'@push.rocks/smartrust': 1.3.2
|
||||
'@tsclass/tsclass': 9.5.0
|
||||
acme-client: 5.4.0
|
||||
dns-packet: 5.6.1
|
||||
elliptic: 6.6.1
|
||||
minimatch: 10.1.1
|
||||
minimatch: 10.2.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -5423,14 +5411,11 @@ snapshots:
|
||||
- supports-color
|
||||
- vue
|
||||
|
||||
'@push.rocks/smartnetwork@4.4.0':
|
||||
'@push.rocks/smartnetwork@4.5.2':
|
||||
dependencies:
|
||||
'@push.rocks/smartdns': 7.6.1
|
||||
'@push.rocks/smartping': 1.0.8
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/smartstring': 4.1.0
|
||||
isopen: 1.3.0
|
||||
systeminformation: 5.27.11
|
||||
'@push.rocks/smartdns': 7.9.0
|
||||
'@push.rocks/smartrust': 1.3.2
|
||||
maxmind: 5.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -5471,7 +5456,7 @@ snapshots:
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
'@push.rocks/smartfs': 1.5.0
|
||||
'@push.rocks/smartjimp': 1.2.0
|
||||
'@push.rocks/smartnetwork': 4.4.0
|
||||
'@push.rocks/smartnetwork': 4.5.2
|
||||
'@push.rocks/smartpath': 6.0.0
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
'@push.rocks/smartpuppeteer': 2.0.5(typescript@6.0.2)
|
||||
@@ -5493,11 +5478,6 @@ snapshots:
|
||||
- utf-8-validate
|
||||
- vue
|
||||
|
||||
'@push.rocks/smartping@1.0.8':
|
||||
dependencies:
|
||||
'@types/ping': 0.4.4
|
||||
ping: 0.4.4
|
||||
|
||||
'@push.rocks/smartpromise@4.2.3': {}
|
||||
|
||||
'@push.rocks/smartpuppeteer@2.0.5(typescript@6.0.2)':
|
||||
@@ -6189,10 +6169,6 @@ snapshots:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@types/bn.js@5.2.0':
|
||||
dependencies:
|
||||
'@types/node': 25.5.0
|
||||
|
||||
'@types/clean-css@4.2.11':
|
||||
dependencies:
|
||||
'@types/node': 25.5.0
|
||||
@@ -6202,14 +6178,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/ms': 2.1.0
|
||||
|
||||
'@types/dns-packet@5.6.5':
|
||||
dependencies:
|
||||
'@types/node': 25.5.0
|
||||
|
||||
'@types/elliptic@6.4.18':
|
||||
dependencies:
|
||||
'@types/bn.js': 5.2.0
|
||||
|
||||
'@types/fs-extra@11.0.4':
|
||||
dependencies:
|
||||
'@types/jsonfile': 6.1.4
|
||||
@@ -6263,8 +6231,6 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 7.18.2
|
||||
|
||||
'@types/ping@0.4.4': {}
|
||||
|
||||
'@types/relateurl@0.2.33': {}
|
||||
|
||||
'@types/semver@7.7.1': {}
|
||||
@@ -6388,6 +6354,8 @@ snapshots:
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
balanced-match@4.0.4: {}
|
||||
|
||||
bare-events@2.8.2: {}
|
||||
|
||||
bare-fs@4.5.5:
|
||||
@@ -6427,8 +6395,6 @@ snapshots:
|
||||
|
||||
bmp-ts@1.0.9: {}
|
||||
|
||||
bn.js@4.12.2: {}
|
||||
|
||||
bowser@2.12.1: {}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
@@ -6440,6 +6406,10 @@ snapshots:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
brace-expansion@5.0.5:
|
||||
dependencies:
|
||||
balanced-match: 4.0.4
|
||||
|
||||
broadcast-channel@7.2.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
@@ -6447,8 +6417,6 @@ snapshots:
|
||||
p-queue: 6.6.2
|
||||
unload: 2.4.1
|
||||
|
||||
brorand@1.1.0: {}
|
||||
|
||||
bson@6.10.4: {}
|
||||
|
||||
buffer-crc32@0.2.13: {}
|
||||
@@ -6617,10 +6585,6 @@ snapshots:
|
||||
|
||||
devtools-protocol@0.0.1581282: {}
|
||||
|
||||
dns-packet@5.6.1:
|
||||
dependencies:
|
||||
'@leichtgewicht/ip-codec': 2.0.5
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
@@ -6629,16 +6593,6 @@ snapshots:
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
elliptic@6.6.1:
|
||||
dependencies:
|
||||
bn.js: 4.12.2
|
||||
brorand: 1.1.0
|
||||
hash.js: 1.1.7
|
||||
hmac-drbg: 1.0.1
|
||||
inherits: 2.0.4
|
||||
minimalistic-assert: 1.0.1
|
||||
minimalistic-crypto-utils: 1.0.1
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
emoji-regex@9.2.2: {}
|
||||
@@ -6972,11 +6926,6 @@ snapshots:
|
||||
dependencies:
|
||||
has-symbols: 1.1.0
|
||||
|
||||
hash.js@1.1.7:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
minimalistic-assert: 1.0.1
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
@@ -7007,12 +6956,6 @@ snapshots:
|
||||
|
||||
he@1.2.0: {}
|
||||
|
||||
hmac-drbg@1.0.1:
|
||||
dependencies:
|
||||
hash.js: 1.1.7
|
||||
minimalistic-assert: 1.0.1
|
||||
minimalistic-crypto-utils: 1.0.1
|
||||
|
||||
html-minifier@4.0.0:
|
||||
dependencies:
|
||||
camel-case: 3.0.0
|
||||
@@ -7110,8 +7053,6 @@ snapshots:
|
||||
|
||||
isexe@4.0.0: {}
|
||||
|
||||
isopen@1.3.0: {}
|
||||
|
||||
jackspeak@4.1.1:
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
@@ -7225,6 +7166,11 @@ snapshots:
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
maxmind@5.0.5:
|
||||
dependencies:
|
||||
mmdb-lib: 3.0.2
|
||||
tiny-lru: 11.4.7
|
||||
|
||||
mdast-util-find-and-replace@3.0.2:
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
@@ -7566,14 +7512,14 @@ snapshots:
|
||||
|
||||
mingo@7.2.0: {}
|
||||
|
||||
minimalistic-assert@1.0.1: {}
|
||||
|
||||
minimalistic-crypto-utils@1.0.1: {}
|
||||
|
||||
minimatch@10.1.1:
|
||||
dependencies:
|
||||
'@isaacs/brace-expansion': 5.0.0
|
||||
|
||||
minimatch@10.2.4:
|
||||
dependencies:
|
||||
brace-expansion: 5.0.5
|
||||
|
||||
minimatch@3.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
@@ -7588,6 +7534,8 @@ snapshots:
|
||||
|
||||
mitt@3.0.1: {}
|
||||
|
||||
mmdb-lib@3.0.2: {}
|
||||
|
||||
mongodb-connection-string-url@3.0.2:
|
||||
dependencies:
|
||||
'@types/whatwg-url': 11.0.5
|
||||
@@ -7791,8 +7739,6 @@ snapshots:
|
||||
|
||||
picomatch@4.0.3: {}
|
||||
|
||||
ping@0.4.4: {}
|
||||
|
||||
pixelmatch@5.3.0:
|
||||
dependencies:
|
||||
pngjs: 6.0.0
|
||||
@@ -8162,8 +8108,6 @@ snapshots:
|
||||
|
||||
symbol-tree@3.2.4: {}
|
||||
|
||||
systeminformation@5.27.11: {}
|
||||
|
||||
tagged-tag@1.0.0: {}
|
||||
|
||||
tar-fs@3.1.2:
|
||||
@@ -8219,6 +8163,8 @@ snapshots:
|
||||
|
||||
through@2.3.8: {}
|
||||
|
||||
tiny-lru@11.4.7: {}
|
||||
|
||||
tiny-worker@2.3.0:
|
||||
dependencies:
|
||||
esm: 3.2.25
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
import { tapNodeTools } from '../../ts_tapbundle_serverside/index.js';
|
||||
import { TapNodeTools } from '../../ts_tapbundle_serverside/index.js';
|
||||
|
||||
const tapNodeTools = new TapNodeTools(tap);
|
||||
|
||||
tap.test('should find a single free port', async () => {
|
||||
const port = await tapNodeTools.findFreePort();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
import { TapNodeTools } from '../../ts_tapbundle_serverside/index.js';
|
||||
|
||||
import { tapNodeTools } from '../../ts_tapbundle_serverside/index.js';
|
||||
const tapNodeTools = new TapNodeTools(tap);
|
||||
|
||||
tap.test('should execure a command', async () => {
|
||||
const result = await tapNodeTools.runCommand('ls -la');
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@git.zone/tstest',
|
||||
version: '3.6.0',
|
||||
version: '3.6.3',
|
||||
description: 'A powerful, modern test runner for TypeScript with multi-runtime support (Node.js, Deno, Bun, Chromium) and a batteries-included test framework.'
|
||||
}
|
||||
|
||||
@@ -193,6 +193,7 @@ export const runCli = async () => {
|
||||
await tsTestInstance.runWatch(watchIgnorePatterns);
|
||||
} else {
|
||||
await tsTestInstance.run();
|
||||
await tsTestInstance.cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -83,6 +83,9 @@ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
|
||||
throw new Error('Could not find a free WebSocket port in range 30000-40000');
|
||||
}
|
||||
|
||||
// Stop the smartnetwork instance to release the Rust bridge process
|
||||
await smartnetwork.stop();
|
||||
|
||||
// Log selected ports for debugging
|
||||
if (!this.logger.options.quiet) {
|
||||
console.log(`Selected ports - HTTP: ${httpPort}, WebSocket: ${wsPort}`);
|
||||
@@ -103,7 +106,7 @@ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
|
||||
|
||||
// lets get all our paths sorted
|
||||
const tsbundleCacheDirPath = plugins.path.join(paths.cwd, './.nogit/tstest_cache');
|
||||
const bundleFileName = testFile.replace('/', '__') + '.js';
|
||||
const bundleFileName = testFile.replaceAll('/', '__') + '.js';
|
||||
const bundleFilePath = plugins.path.join(tsbundleCacheDirPath, bundleFileName);
|
||||
|
||||
// lets bundle the test
|
||||
@@ -159,7 +162,7 @@ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
|
||||
await this.smartbrowserInstance.start();
|
||||
|
||||
const evaluatePromise = this.smartbrowserInstance.evaluateOnPage(
|
||||
`http://localhost:${httpPort}/test?bundleName=${bundleFileName}`,
|
||||
`http://localhost:${httpPort}/test?bundleName=${encodeURIComponent(bundleFileName)}`,
|
||||
async () => {
|
||||
// lets enable real time comms
|
||||
const ws = new WebSocket(`ws://localhost:${globalThis.wsPort}`);
|
||||
@@ -277,6 +280,9 @@ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
|
||||
}
|
||||
|
||||
try {
|
||||
for (const client of wss.clients) {
|
||||
client.terminate();
|
||||
}
|
||||
wss.close();
|
||||
} catch (error) {
|
||||
// WebSocket server might already be closed
|
||||
|
||||
@@ -158,7 +158,14 @@ export class TsTest {
|
||||
|
||||
tapCombinator.evaluate();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean up all long-lived resources so the Node.js event loop can drain naturally.
|
||||
*/
|
||||
public async cleanup() {
|
||||
this.smartshellInstance.smartexit.deregister();
|
||||
}
|
||||
|
||||
public async runWatch(ignorePatterns: string[] = []) {
|
||||
const smartwatchInstance = new plugins.smartwatch.Smartwatch([this.testDir.cwd]);
|
||||
|
||||
@@ -386,341 +393,6 @@ export class TsTest {
|
||||
}
|
||||
}
|
||||
|
||||
public async runInNode(fileNameArg: string, index: number, total: number): Promise<TapParser> {
|
||||
this.logger.testFileStart(fileNameArg, 'node.js', index, total);
|
||||
const tapParser = new TapParser(fileNameArg + ':node', this.logger);
|
||||
|
||||
// tsrun options
|
||||
let tsrunOptions = '';
|
||||
if (process.argv.includes('--web')) {
|
||||
tsrunOptions += ' --web';
|
||||
}
|
||||
|
||||
// Set filter tags as environment variable
|
||||
if (this.filterTags.length > 0) {
|
||||
process.env.TSTEST_FILTER_TAGS = this.filterTags.join(',');
|
||||
}
|
||||
|
||||
// Check for 00init.ts file in test directory
|
||||
const testDir = plugins.path.dirname(fileNameArg);
|
||||
const initFile = plugins.path.join(testDir, '00init.ts');
|
||||
let runCommand = `tsrun ${fileNameArg}${tsrunOptions}`;
|
||||
|
||||
const initFileExists = await plugins.smartfsInstance.file(initFile).exists();
|
||||
|
||||
// If 00init.ts exists, run it first
|
||||
if (initFileExists) {
|
||||
// Create a temporary loader file that imports both 00init.ts and the test file
|
||||
const absoluteInitFile = plugins.path.resolve(initFile);
|
||||
const absoluteTestFile = plugins.path.resolve(fileNameArg);
|
||||
const loaderContent = `
|
||||
import '${absoluteInitFile.replace(/\\/g, '/')}';
|
||||
import '${absoluteTestFile.replace(/\\/g, '/')}';
|
||||
`;
|
||||
const loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(fileNameArg)}`);
|
||||
await plugins.smartfsInstance.file(loaderPath).write(loaderContent);
|
||||
runCommand = `tsrun ${loaderPath}${tsrunOptions}`;
|
||||
}
|
||||
|
||||
const execResultStreaming = await this.smartshellInstance.execStreamingSilent(runCommand);
|
||||
|
||||
// If we created a loader file, clean it up after test execution
|
||||
if (initFileExists) {
|
||||
const loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(fileNameArg)}`);
|
||||
const cleanup = () => {
|
||||
try {
|
||||
if (plugins.fs.existsSync(loaderPath)) {
|
||||
plugins.fs.rmSync(loaderPath, { force: true });
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
};
|
||||
|
||||
execResultStreaming.childProcess.on('exit', cleanup);
|
||||
execResultStreaming.childProcess.on('error', cleanup);
|
||||
}
|
||||
|
||||
// Start warning timer if no timeout was specified
|
||||
let warningTimer: NodeJS.Timeout | null = null;
|
||||
if (this.timeoutSeconds === null) {
|
||||
warningTimer = setTimeout(() => {
|
||||
console.error('');
|
||||
console.error(cs('⚠️ WARNING: Test file is running for more than 1 minute', 'orange'));
|
||||
console.error(cs(` File: ${fileNameArg}`, 'orange'));
|
||||
console.error(cs(' Consider using --timeout option to set a timeout for test files.', 'orange'));
|
||||
console.error(cs(' Example: tstest test --timeout=300 (for 5 minutes)', 'orange'));
|
||||
console.error('');
|
||||
}, 60000); // 1 minute
|
||||
}
|
||||
|
||||
// Handle timeout if specified
|
||||
if (this.timeoutSeconds !== null) {
|
||||
const timeoutMs = this.timeoutSeconds * 1000;
|
||||
let timeoutId: NodeJS.Timeout;
|
||||
|
||||
const timeoutPromise = new Promise<void>((_resolve, reject) => {
|
||||
timeoutId = setTimeout(async () => {
|
||||
// Use smartshell's terminate() to kill entire process tree
|
||||
await execResultStreaming.terminate();
|
||||
reject(new Error(`Test file timed out after ${this.timeoutSeconds} seconds`));
|
||||
}, timeoutMs);
|
||||
});
|
||||
|
||||
try {
|
||||
await Promise.race([
|
||||
tapParser.handleTapProcess(execResultStreaming.childProcess),
|
||||
timeoutPromise
|
||||
]);
|
||||
// Clear timeout if test completed successfully
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
// Clear warning timer if it was set
|
||||
if (warningTimer) {
|
||||
clearTimeout(warningTimer);
|
||||
}
|
||||
// Handle timeout error
|
||||
tapParser.handleTimeout(this.timeoutSeconds);
|
||||
// Ensure entire process tree is killed if still running
|
||||
try {
|
||||
await execResultStreaming.kill(); // This kills the entire process tree with SIGKILL
|
||||
} catch (killError) {
|
||||
// Process tree might already be dead
|
||||
}
|
||||
await tapParser.evaluateFinalResult();
|
||||
}
|
||||
} else {
|
||||
await tapParser.handleTapProcess(execResultStreaming.childProcess);
|
||||
}
|
||||
|
||||
// Clear warning timer if it was set
|
||||
if (warningTimer) {
|
||||
clearTimeout(warningTimer);
|
||||
}
|
||||
|
||||
return tapParser;
|
||||
}
|
||||
|
||||
private async findFreePorts(): Promise<{ httpPort: number; wsPort: number }> {
|
||||
const smartnetwork = new plugins.smartnetwork.SmartNetwork();
|
||||
|
||||
// Find random free HTTP port in range 30000-40000 to minimize collision chance
|
||||
const httpPort = await smartnetwork.findFreePort(30000, 40000, { randomize: true });
|
||||
if (!httpPort) {
|
||||
throw new Error('Could not find a free HTTP port in range 30000-40000');
|
||||
}
|
||||
|
||||
// Find random free WebSocket port, excluding the HTTP port to ensure they're different
|
||||
const wsPort = await smartnetwork.findFreePort(30000, 40000, {
|
||||
randomize: true,
|
||||
exclude: [httpPort]
|
||||
});
|
||||
if (!wsPort) {
|
||||
throw new Error('Could not find a free WebSocket port in range 30000-40000');
|
||||
}
|
||||
|
||||
// Log selected ports for debugging
|
||||
if (!this.logger.options.quiet) {
|
||||
console.log(`Selected ports - HTTP: ${httpPort}, WebSocket: ${wsPort}`);
|
||||
}
|
||||
return { httpPort, wsPort };
|
||||
}
|
||||
|
||||
public async runInChrome(fileNameArg: string, index: number, total: number): Promise<TapParser> {
|
||||
this.logger.testFileStart(fileNameArg, 'chromium', index, total);
|
||||
|
||||
// lets get all our paths sorted
|
||||
const tsbundleCacheDirPath = plugins.path.join(paths.cwd, './.nogit/tstest_cache');
|
||||
const bundleFileName = fileNameArg.replace('/', '__') + '.js';
|
||||
const bundleFilePath = plugins.path.join(tsbundleCacheDirPath, bundleFileName);
|
||||
|
||||
// lets bundle the test
|
||||
try { await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().delete(); } catch (e) { /* may not exist */ }
|
||||
await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().create();
|
||||
await this.tsbundleInstance.build(process.cwd(), fileNameArg, bundleFilePath, {
|
||||
bundler: 'esbuild',
|
||||
});
|
||||
|
||||
// Find free ports for HTTP and WebSocket
|
||||
const { httpPort, wsPort } = await this.findFreePorts();
|
||||
|
||||
// Use SmartServe with setHandler() to bypass global ControllerRegistry
|
||||
const fileServer = new plugins.smartserve.FileServer({ root: tsbundleCacheDirPath });
|
||||
const server = new plugins.smartserve.SmartServe({ port: httpPort });
|
||||
server.setHandler(async (request: Request) => {
|
||||
const url = new URL(request.url);
|
||||
if (url.pathname === '/test') {
|
||||
return new Response(`
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
globalThis.testdom = true;
|
||||
globalThis.wsPort = ${wsPort};
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
`, { headers: { 'Content-Type': 'text/html' } });
|
||||
}
|
||||
const staticResponse = await fileServer.serve(request);
|
||||
if (staticResponse) return staticResponse;
|
||||
return new Response('Not Found', { status: 404 });
|
||||
});
|
||||
await server.start();
|
||||
|
||||
// lets handle realtime comms
|
||||
const tapParser = new TapParser(fileNameArg + ':chrome', this.logger);
|
||||
const wss = new plugins.ws.WebSocketServer({ port: wsPort });
|
||||
wss.on('connection', (ws) => {
|
||||
ws.on('message', (message) => {
|
||||
const messageStr = message.toString();
|
||||
if (messageStr.startsWith('console:')) {
|
||||
const [, level, ...messageParts] = messageStr.split(':');
|
||||
this.logger.browserConsole(messageParts.join(':'), level);
|
||||
} else {
|
||||
tapParser.handleTapLog(messageStr);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// lets do the browser bit with timeout handling
|
||||
await this.smartbrowserInstance.start();
|
||||
|
||||
const evaluatePromise = this.smartbrowserInstance.evaluateOnPage(
|
||||
`http://localhost:${httpPort}/test?bundleName=${bundleFileName}`,
|
||||
async () => {
|
||||
// lets enable real time comms
|
||||
const ws = new WebSocket(`ws://localhost:${globalThis.wsPort}`);
|
||||
await new Promise((resolve) => (ws.onopen = resolve));
|
||||
|
||||
// Ensure this function is declared with 'async'
|
||||
const logStore = [];
|
||||
const originalLog = console.log;
|
||||
const originalError = console.error;
|
||||
|
||||
// Override console methods to capture the logs
|
||||
console.log = (...args: any[]) => {
|
||||
logStore.push(args.join(' '));
|
||||
ws.send(args.join(' '));
|
||||
originalLog(...args);
|
||||
};
|
||||
console.error = (...args: any[]) => {
|
||||
logStore.push(args.join(' '));
|
||||
ws.send(args.join(' '));
|
||||
originalError(...args);
|
||||
};
|
||||
|
||||
const bundleName = new URLSearchParams(window.location.search).get('bundleName');
|
||||
originalLog(`::TSTEST IN CHROMIUM:: Relevant Script name is: ${bundleName}`);
|
||||
|
||||
try {
|
||||
// Dynamically import the test module
|
||||
const testModule = await import(`/${bundleName}`);
|
||||
if (testModule && testModule.default && testModule.default instanceof Promise) {
|
||||
// Execute the exported test function
|
||||
await testModule.default;
|
||||
} else if (testModule && testModule.default && typeof testModule.default.then === 'function') {
|
||||
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
console.log('Test module default export is just promiselike: Something might be messing with your Promise implementation.');
|
||||
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
await testModule.default;
|
||||
} else if (globalThis.tapPromise && typeof globalThis.tapPromise.then === 'function') {
|
||||
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
console.log('Using globalThis.tapPromise');
|
||||
console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
await testModule.default;
|
||||
} else {
|
||||
console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
console.error('Test module does not export a default promise.');
|
||||
console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
console.log(`We got: ${JSON.stringify(testModule)}`);
|
||||
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
return logStore.join('\n');
|
||||
}
|
||||
);
|
||||
|
||||
// Start warning timer if no timeout was specified
|
||||
let warningTimer: NodeJS.Timeout | null = null;
|
||||
if (this.timeoutSeconds === null) {
|
||||
warningTimer = setTimeout(() => {
|
||||
console.error('');
|
||||
console.error(cs('⚠️ WARNING: Test file is running for more than 1 minute', 'orange'));
|
||||
console.error(cs(` File: ${fileNameArg}`, 'orange'));
|
||||
console.error(cs(' Consider using --timeout option to set a timeout for test files.', 'orange'));
|
||||
console.error(cs(' Example: tstest test --timeout=300 (for 5 minutes)', 'orange'));
|
||||
console.error('');
|
||||
}, 60000); // 1 minute
|
||||
}
|
||||
|
||||
// Handle timeout if specified
|
||||
if (this.timeoutSeconds !== null) {
|
||||
const timeoutMs = this.timeoutSeconds * 1000;
|
||||
let timeoutId: NodeJS.Timeout;
|
||||
|
||||
const timeoutPromise = new Promise<void>((_resolve, reject) => {
|
||||
timeoutId = setTimeout(() => {
|
||||
reject(new Error(`Test file timed out after ${this.timeoutSeconds} seconds`));
|
||||
}, timeoutMs);
|
||||
});
|
||||
|
||||
try {
|
||||
await Promise.race([
|
||||
evaluatePromise,
|
||||
timeoutPromise
|
||||
]);
|
||||
// Clear timeout if test completed successfully
|
||||
clearTimeout(timeoutId);
|
||||
} catch (error) {
|
||||
// Clear warning timer if it was set
|
||||
if (warningTimer) {
|
||||
clearTimeout(warningTimer);
|
||||
}
|
||||
// Handle timeout error
|
||||
tapParser.handleTimeout(this.timeoutSeconds);
|
||||
}
|
||||
} else {
|
||||
await evaluatePromise;
|
||||
}
|
||||
|
||||
// Clear warning timer if it was set
|
||||
if (warningTimer) {
|
||||
clearTimeout(warningTimer);
|
||||
}
|
||||
|
||||
// Always clean up resources, even on timeout
|
||||
try {
|
||||
await this.smartbrowserInstance.stop();
|
||||
} catch (error) {
|
||||
// Browser might already be stopped
|
||||
}
|
||||
|
||||
try {
|
||||
await server.stop();
|
||||
} catch (error) {
|
||||
// Server might already be stopped
|
||||
}
|
||||
|
||||
try {
|
||||
wss.close();
|
||||
} catch (error) {
|
||||
// WebSocket server might already be closed
|
||||
}
|
||||
|
||||
console.log(
|
||||
`${cs('=> ', 'blue')} Stopped ${cs(fileNameArg, 'orange')} chromium instance and server.`
|
||||
);
|
||||
// Always evaluate final result (handleTimeout just sets up the test state)
|
||||
await tapParser.evaluateFinalResult();
|
||||
return tapParser;
|
||||
}
|
||||
|
||||
public async runInDeno() {}
|
||||
|
||||
private async movePreviousLogFiles() {
|
||||
const logDir = plugins.path.join('.nogit', 'testlogs');
|
||||
const previousDir = plugins.path.join('.nogit', 'testlogs', 'previous');
|
||||
|
||||
@@ -117,7 +117,8 @@ export class Tap<T> {
|
||||
private settingsManager = new SettingsManager();
|
||||
private _skipCount = 0;
|
||||
private _filterTags: string[] = [];
|
||||
|
||||
private _cleanupFunctions: Array<() => Promise<void> | void> = [];
|
||||
|
||||
constructor() {
|
||||
// Get filter tags from environment
|
||||
if (typeof process !== 'undefined' && process.env && process.env.TSTEST_FILTER_TAGS) {
|
||||
@@ -125,6 +126,14 @@ export class Tap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a cleanup function to be called when tap.start() finishes.
|
||||
* Use this to tear down resources that would otherwise keep the event loop alive.
|
||||
*/
|
||||
public registerCleanup(fn: () => Promise<void> | void) {
|
||||
this._cleanupFunctions.push(fn);
|
||||
}
|
||||
|
||||
// Fluent test builder
|
||||
public tags(...tags: string[]) {
|
||||
const builder = new TestBuilder<T>(this);
|
||||
@@ -610,6 +619,15 @@ export class Tap<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// Run registered cleanup functions (e.g. tapNodeTools stopping SmartNetwork Rust bridge)
|
||||
for (const cleanupFn of this._cleanupFunctions) {
|
||||
try {
|
||||
await cleanupFn();
|
||||
} catch (e) {
|
||||
// Don't let cleanup errors break the test run
|
||||
}
|
||||
}
|
||||
|
||||
if (optionsArg && optionsArg.throwOnError && failReasons.length > 0) {
|
||||
if (!smartenvInstance.isBrowser && typeof process !== 'undefined') process.exit(1);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { TestFileProvider } from './classes.testfileprovider.js';
|
||||
import * as plugins from './plugins.js';
|
||||
|
||||
class TapNodeTools {
|
||||
export interface ITapCleanupTarget {
|
||||
registerCleanup: (fn: () => Promise<void> | void) => void;
|
||||
}
|
||||
|
||||
export class TapNodeTools {
|
||||
private smartshellInstance: plugins.smartshell.Smartshell;
|
||||
private smartnetworkInstance: plugins.smartnetwork.SmartNetwork;
|
||||
public testFileProvider = new TestFileProvider();
|
||||
|
||||
constructor() {}
|
||||
constructor(tapArg: ITapCleanupTarget) {
|
||||
tapArg.registerCleanup(() => this.cleanup());
|
||||
}
|
||||
|
||||
private qenv: plugins.qenv.Qenv;
|
||||
public async getQenv(): Promise<plugins.qenv.Qenv> {
|
||||
@@ -75,7 +81,7 @@ class TapNodeTools {
|
||||
/**
|
||||
* create and return a smartmongo instance
|
||||
*/
|
||||
public async createSmartmongo() {
|
||||
public async createSmartmongo() {
|
||||
const smartmongoMod = await import('@push.rocks/smartmongo');
|
||||
const smartmongoInstance = new smartmongoMod.SmartMongo();
|
||||
await smartmongoInstance.start();
|
||||
@@ -217,6 +223,15 @@ class TapNodeTools {
|
||||
`Could not find ${countArg} consecutive free ports in range ${options.startPort}-${options.endPort}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const tapNodeTools = new TapNodeTools();
|
||||
/**
|
||||
* Clean up long-lived resources (e.g. the SmartNetwork Rust bridge process)
|
||||
* so the Node.js event loop can drain naturally.
|
||||
*/
|
||||
public async cleanup() {
|
||||
if (this.smartnetworkInstance) {
|
||||
await this.smartnetworkInstance.stop();
|
||||
this.smartnetworkInstance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,11 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
||||
## Basic Usage
|
||||
|
||||
```typescript
|
||||
import { tapNodeTools } from '@git.zone/tstest/tapbundle_serverside';
|
||||
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||
import { TapNodeTools } from '@git.zone/tstest/tapbundle_serverside';
|
||||
|
||||
// Create an instance and pass `tap` so cleanup is automatic
|
||||
const tapNodeTools = new TapNodeTools(tap);
|
||||
|
||||
tap.test('should start server on free port', async () => {
|
||||
const port = await tapNodeTools.findFreePort();
|
||||
@@ -41,11 +44,15 @@ tap.test('should start server on free port', async () => {
|
||||
export default tap.start();
|
||||
```
|
||||
|
||||
### How cleanup works
|
||||
|
||||
`TapNodeTools` accepts any object with a `registerCleanup()` method (the `tap` instance). On construction, it registers a cleanup callback that stops long-lived background processes (e.g. the SmartNetwork Rust bridge). When `tap.start()` finishes running all tests, it calls all registered cleanup functions automatically, so the Node.js event loop can drain and the process exits cleanly.
|
||||
|
||||
## API Reference
|
||||
|
||||
### tapNodeTools
|
||||
### TapNodeTools
|
||||
|
||||
The main singleton instance providing all Node.js-specific utilities.
|
||||
Construct with a `tap` instance to enable automatic cleanup:
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user