Support for isomorphic-git as an alternative git backend, part 1 (#5229) * Initial version of git adapter for alternate backend. Only clone is implemented. * Regenerate package-lock.json * Clarify comments in config.yaml regarding git backend options --------- Co-authored-by: Sanitised <sanitised@users.noreply.github.com> Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>

3db508a75936a42b7259675f9f5fc33edb35b366

Sanitised <bakeriesvader@gmail.com>

Signed
6 files changed, +565 -6Showing whitespace changes
default/config.yaml+7 -0
@@ -250,6 +250,13 @@ extensions:
250 speechToText: Xenova/whisper-small250 speechToText: Xenova/whisper-small
251 textToSpeech: Xenova/speecht5_tts251 textToSpeech: Xenova/speecht5_tts
252252
253# Git backend for plugin/extension repository operations.
254# - Use "auto" to prefer system git, falling back to the integrated backend
255# - Use "system" to force system backend
256# - Use "builtin" to force integrated backend
257git:
258 backend: auto
259
253# Additional model tokenizers can be downloaded on demand.260# Additional model tokenizers can be downloaded on demand.
254# Disabling will fallback to another locally available tokenizer.261# Disabling will fallback to another locally available tokenizer.
255enableDownloadableTokenizers: true262enableDownloadableTokenizers: true
package-lock.json+409 -1
@@ -72,6 +72,7 @@
72 "ip-regex": "^5.0.0",72 "ip-regex": "^5.0.0",
73 "ipaddr.js": "^2.2.0",73 "ipaddr.js": "^2.2.0",
74 "is-docker": "^3.0.0",74 "is-docker": "^3.0.0",
75 "isomorphic-git": "^1.36.3",
75 "localforage": "^1.10.0",76 "localforage": "^1.10.0",
76 "lodash": "^4.17.21",77 "lodash": "^4.17.21",
77 "mime-types": "^3.0.2",78 "mime-types": "^3.0.2",
@@ -2982,12 +2983,33 @@
2982 "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",2983 "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
2983 "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="2984 "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
2984 },2985 },
2986 "node_modules/async-lock": {
2987 "version": "1.4.1",
2988 "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz",
2989 "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==",
2990 "license": "MIT"
2991 },
2985 "node_modules/asynckit": {2992 "node_modules/asynckit": {
2986 "version": "0.4.0",2993 "version": "0.4.0",
2987 "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",2994 "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
2988 "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",2995 "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
2989 "license": "MIT"2996 "license": "MIT"
2990 },2997 },
2998 "node_modules/available-typed-arrays": {
2999 "version": "1.0.7",
3000 "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
3001 "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
3002 "license": "MIT",
3003 "dependencies": {
3004 "possible-typed-array-names": "^1.0.0"
3005 },
3006 "engines": {
3007 "node": ">= 0.4"
3008 },
3009 "funding": {
3010 "url": "https://github.com/sponsors/ljharb"
3011 }
3012 },
2991 "node_modules/await-to-js": {3013 "node_modules/await-to-js": {
2992 "version": "3.0.0",3014 "version": "3.0.0",
2993 "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz",3015 "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz",
@@ -3334,6 +3356,24 @@
3334 "node": ">=8"3356 "node": ">=8"
3335 }3357 }
3336 },3358 },
3359 "node_modules/call-bind": {
3360 "version": "1.0.8",
3361 "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
3362 "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
3363 "license": "MIT",
3364 "dependencies": {
3365 "call-bind-apply-helpers": "^1.0.0",
3366 "es-define-property": "^1.0.0",
3367 "get-intrinsic": "^1.2.4",
3368 "set-function-length": "^1.2.2"
3369 },
3370 "engines": {
3371 "node": ">= 0.4"
3372 },
3373 "funding": {
3374 "url": "https://github.com/sponsors/ljharb"
3375 }
3376 },
3337 "node_modules/call-bind-apply-helpers": {3377 "node_modules/call-bind-apply-helpers": {
3338 "version": "1.0.2",3378 "version": "1.0.2",
3339 "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",3379 "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
@@ -3484,6 +3524,12 @@
3484 "node": ">=6.0"3524 "node": ">=6.0"
3485 }3525 }
3486 },3526 },
3527 "node_modules/clean-git-ref": {
3528 "version": "2.0.1",
3529 "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz",
3530 "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==",
3531 "license": "Apache-2.0"
3532 },
3487 "node_modules/cliui": {3533 "node_modules/cliui": {
3488 "version": "8.0.1",3534 "version": "8.0.1",
3489 "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",3535 "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -4109,6 +4155,23 @@
4109 "node": ">=10"4155 "node": ">=10"
4110 }4156 }
4111 },4157 },
4158 "node_modules/define-data-property": {
4159 "version": "1.1.4",
4160 "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
4161 "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
4162 "license": "MIT",
4163 "dependencies": {
4164 "es-define-property": "^1.0.0",
4165 "es-errors": "^1.3.0",
4166 "gopd": "^1.0.1"
4167 },
4168 "engines": {
4169 "node": ">= 0.4"
4170 },
4171 "funding": {
4172 "url": "https://github.com/sponsors/ljharb"
4173 }
4174 },
4112 "node_modules/define-lazy-prop": {4175 "node_modules/define-lazy-prop": {
4113 "version": "3.0.0",4176 "version": "3.0.0",
4114 "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",4177 "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
@@ -4169,6 +4232,12 @@
4169 "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==",4232 "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==",
4170 "license": "Apache-2.0"4233 "license": "Apache-2.0"
4171 },4234 },
4235 "node_modules/diff3": {
4236 "version": "0.0.3",
4237 "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz",
4238 "integrity": "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==",
4239 "license": "MIT"
4240 },
4172 "node_modules/digest-fetch": {4241 "node_modules/digest-fetch": {
4173 "version": "1.3.0",4242 "version": "1.3.0",
4174 "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",4243 "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz",
@@ -5149,6 +5218,21 @@
5149 }5218 }
5150 }5219 }
5151 },5220 },
5221 "node_modules/for-each": {
5222 "version": "0.3.5",
5223 "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
5224 "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
5225 "license": "MIT",
5226 "dependencies": {
5227 "is-callable": "^1.2.7"
5228 },
5229 "engines": {
5230 "node": ">= 0.4"
5231 },
5232 "funding": {
5233 "url": "https://github.com/sponsors/ljharb"
5234 }
5235 },
5152 "node_modules/foreground-child": {5236 "node_modules/foreground-child": {
5153 "version": "3.1.1",5237 "version": "3.1.1",
5154 "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",5238 "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
@@ -5574,6 +5658,18 @@
5574 "node": ">=8"5658 "node": ">=8"
5575 }5659 }
5576 },5660 },
5661 "node_modules/has-property-descriptors": {
5662 "version": "1.0.2",
5663 "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
5664 "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
5665 "license": "MIT",
5666 "dependencies": {
5667 "es-define-property": "^1.0.0"
5668 },
5669 "funding": {
5670 "url": "https://github.com/sponsors/ljharb"
5671 }
5672 },
5577 "node_modules/has-symbols": {5673 "node_modules/has-symbols": {
5578 "version": "1.1.0",5674 "version": "1.1.0",
5579 "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",5675 "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
@@ -5827,7 +5923,6 @@
5827 "version": "5.2.4",5923 "version": "5.2.4",
5828 "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",5924 "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
5829 "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",5925 "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
5830 "dev": true,
5831 "license": "MIT",5926 "license": "MIT",
5832 "engines": {5927 "engines": {
5833 "node": ">= 4"5928 "node": ">= 4"
@@ -5955,6 +6050,18 @@
5955 "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",6050 "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
5956 "license": "MIT"6051 "license": "MIT"
5957 },6052 },
6053 "node_modules/is-callable": {
6054 "version": "1.2.7",
6055 "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
6056 "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
6057 "license": "MIT",
6058 "engines": {
6059 "node": ">= 0.4"
6060 },
6061 "funding": {
6062 "url": "https://github.com/sponsors/ljharb"
6063 }
6064 },
5958 "node_modules/is-docker": {6065 "node_modules/is-docker": {
5959 "version": "3.0.0",6066 "version": "3.0.0",
5960 "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",6067 "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
@@ -6057,6 +6164,21 @@
6057 "url": "https://github.com/sponsors/sindresorhus"6164 "url": "https://github.com/sponsors/sindresorhus"
6058 }6165 }
6059 },6166 },
6167 "node_modules/is-typed-array": {
6168 "version": "1.1.15",
6169 "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
6170 "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
6171 "license": "MIT",
6172 "dependencies": {
6173 "which-typed-array": "^1.1.16"
6174 },
6175 "engines": {
6176 "node": ">= 0.4"
6177 },
6178 "funding": {
6179 "url": "https://github.com/sponsors/ljharb"
6180 }
6181 },
6060 "node_modules/is-wsl": {6182 "node_modules/is-wsl": {
6061 "version": "3.1.0",6183 "version": "3.1.0",
6062 "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",6184 "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
@@ -6114,6 +6236,88 @@
6114 }6236 }
6115 }6237 }
6116 },6238 },
6239 "node_modules/isomorphic-git": {
6240 "version": "1.37.2",
6241 "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.37.2.tgz",
6242 "integrity": "sha512-HCQBBKmXIMPdHgYGstSBNp6MNmVcMQBbUqJF8xfywFmlpNseO4KKex59YlXqNxhRxmv3fUZwvNWvMyOdc1VvhA==",
6243 "license": "MIT",
6244 "dependencies": {
6245 "async-lock": "^1.4.1",
6246 "clean-git-ref": "^2.0.1",
6247 "crc-32": "^1.2.0",
6248 "diff3": "0.0.3",
6249 "ignore": "^5.1.4",
6250 "minimisted": "^2.0.0",
6251 "pako": "^1.0.10",
6252 "pify": "^4.0.1",
6253 "readable-stream": "^4.0.0",
6254 "sha.js": "^2.4.12",
6255 "simple-get": "^4.0.1"
6256 },
6257 "bin": {
6258 "isogit": "cli.cjs"
6259 },
6260 "engines": {
6261 "node": ">=14.17"
6262 }
6263 },
6264 "node_modules/isomorphic-git/node_modules/crc-32": {
6265 "version": "1.2.2",
6266 "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
6267 "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
6268 "license": "Apache-2.0",
6269 "bin": {
6270 "crc32": "bin/crc32.njs"
6271 },
6272 "engines": {
6273 "node": ">=0.8"
6274 }
6275 },
6276 "node_modules/isomorphic-git/node_modules/readable-stream": {
6277 "version": "4.7.0",
6278 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
6279 "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
6280 "license": "MIT",
6281 "dependencies": {
6282 "abort-controller": "^3.0.0",
6283 "buffer": "^6.0.3",
6284 "events": "^3.3.0",
6285 "process": "^0.11.10",
6286 "string_decoder": "^1.3.0"
6287 },
6288 "engines": {
6289 "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
6290 }
6291 },
6292 "node_modules/isomorphic-git/node_modules/safe-buffer": {
6293 "version": "5.2.1",
6294 "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
6295 "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
6296 "funding": [
6297 {
6298 "type": "github",
6299 "url": "https://github.com/sponsors/feross"
6300 },
6301 {
6302 "type": "patreon",
6303 "url": "https://www.patreon.com/feross"
6304 },
6305 {
6306 "type": "consulting",
6307 "url": "https://feross.org/support"
6308 }
6309 ],
6310 "license": "MIT"
6311 },
6312 "node_modules/isomorphic-git/node_modules/string_decoder": {
6313 "version": "1.3.0",
6314 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
6315 "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
6316 "license": "MIT",
6317 "dependencies": {
6318 "safe-buffer": "~5.2.0"
6319 }
6320 },
6117 "node_modules/jackspeak": {6321 "node_modules/jackspeak": {
6118 "version": "3.4.3",6322 "version": "3.4.3",
6119 "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",6323 "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
@@ -6611,6 +6815,15 @@
6611 "url": "https://github.com/sponsors/ljharb"6815 "url": "https://github.com/sponsors/ljharb"
6612 }6816 }
6613 },6817 },
6818 "node_modules/minimisted": {
6819 "version": "2.0.1",
6820 "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz",
6821 "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==",
6822 "license": "MIT",
6823 "dependencies": {
6824 "minimist": "^1.2.5"
6825 }
6826 },
6614 "node_modules/minipass": {6827 "node_modules/minipass": {
6615 "version": "7.1.2",6828 "version": "7.1.2",
6616 "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",6829 "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
@@ -7297,6 +7510,15 @@
7297 "url": "https://github.com/sponsors/jonschlinkert"7510 "url": "https://github.com/sponsors/jonschlinkert"
7298 }7511 }
7299 },7512 },
7513 "node_modules/pify": {
7514 "version": "4.0.1",
7515 "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
7516 "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
7517 "license": "MIT",
7518 "engines": {
7519 "node": ">=6"
7520 }
7521 },
7300 "node_modules/platform": {7522 "node_modules/platform": {
7301 "version": "1.3.6",7523 "version": "1.3.6",
7302 "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",7524 "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
@@ -7327,6 +7549,15 @@
7327 "node": ">=14.19.0"7549 "node": ">=14.19.0"
7328 }7550 }
7329 },7551 },
7552 "node_modules/possible-typed-array-names": {
7553 "version": "1.1.0",
7554 "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
7555 "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
7556 "license": "MIT",
7557 "engines": {
7558 "node": ">= 0.4"
7559 }
7560 },
7330 "node_modules/prelude-ls": {7561 "node_modules/prelude-ls": {
7331 "version": "1.2.1",7562 "version": "1.2.1",
7332 "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",7563 "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -8005,12 +8236,69 @@
8005 "node": ">= 0.8.0"8236 "node": ">= 0.8.0"
8006 }8237 }
8007 },8238 },
8239 "node_modules/set-function-length": {
8240 "version": "1.2.2",
8241 "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
8242 "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
8243 "license": "MIT",
8244 "dependencies": {
8245 "define-data-property": "^1.1.4",
8246 "es-errors": "^1.3.0",
8247 "function-bind": "^1.1.2",
8248 "get-intrinsic": "^1.2.4",
8249 "gopd": "^1.0.1",
8250 "has-property-descriptors": "^1.0.2"
8251 },
8252 "engines": {
8253 "node": ">= 0.4"
8254 }
8255 },
8008 "node_modules/setprototypeof": {8256 "node_modules/setprototypeof": {
8009 "version": "1.2.0",8257 "version": "1.2.0",
8010 "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",8258 "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
8011 "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",8259 "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
8012 "license": "ISC"8260 "license": "ISC"
8013 },8261 },
8262 "node_modules/sha.js": {
8263 "version": "2.4.12",
8264 "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
8265 "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
8266 "license": "(MIT AND BSD-3-Clause)",
8267 "dependencies": {
8268 "inherits": "^2.0.4",
8269 "safe-buffer": "^5.2.1",
8270 "to-buffer": "^1.2.0"
8271 },
8272 "bin": {
8273 "sha.js": "bin.js"
8274 },
8275 "engines": {
8276 "node": ">= 0.10"
8277 },
8278 "funding": {
8279 "url": "https://github.com/sponsors/ljharb"
8280 }
8281 },
8282 "node_modules/sha.js/node_modules/safe-buffer": {
8283 "version": "5.2.1",
8284 "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
8285 "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
8286 "funding": [
8287 {
8288 "type": "github",
8289 "url": "https://github.com/sponsors/feross"
8290 },
8291 {
8292 "type": "patreon",
8293 "url": "https://www.patreon.com/feross"
8294 },
8295 {
8296 "type": "consulting",
8297 "url": "https://feross.org/support"
8298 }
8299 ],
8300 "license": "MIT"
8301 },
8014 "node_modules/shebang-command": {8302 "node_modules/shebang-command": {
8015 "version": "2.0.0",8303 "version": "2.0.0",
8016 "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",8304 "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -8181,6 +8469,51 @@
8181 "regenerator-runtime": "^0.13.3"8469 "regenerator-runtime": "^0.13.3"
8182 }8470 }
8183 },8471 },
8472 "node_modules/simple-concat": {
8473 "version": "1.0.1",
8474 "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
8475 "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
8476 "funding": [
8477 {
8478 "type": "github",
8479 "url": "https://github.com/sponsors/feross"
8480 },
8481 {
8482 "type": "patreon",
8483 "url": "https://www.patreon.com/feross"
8484 },
8485 {
8486 "type": "consulting",
8487 "url": "https://feross.org/support"
8488 }
8489 ],
8490 "license": "MIT"
8491 },
8492 "node_modules/simple-get": {
8493 "version": "4.0.1",
8494 "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
8495 "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
8496 "funding": [
8497 {
8498 "type": "github",
8499 "url": "https://github.com/sponsors/feross"
8500 },
8501 {
8502 "type": "patreon",
8503 "url": "https://www.patreon.com/feross"
8504 },
8505 {
8506 "type": "consulting",
8507 "url": "https://feross.org/support"
8508 }
8509 ],
8510 "license": "MIT",
8511 "dependencies": {
8512 "decompress-response": "^6.0.0",
8513 "once": "^1.3.1",
8514 "simple-concat": "^1.0.0"
8515 }
8516 },
8184 "node_modules/simple-git": {8517 "node_modules/simple-git": {
8185 "version": "3.28.0",8518 "version": "3.28.0",
8186 "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz",8519 "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz",
@@ -8605,6 +8938,46 @@
8605 "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",8938 "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
8606 "license": "MIT"8939 "license": "MIT"
8607 },8940 },
8941 "node_modules/to-buffer": {
8942 "version": "1.2.2",
8943 "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
8944 "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
8945 "license": "MIT",
8946 "dependencies": {
8947 "isarray": "^2.0.5",
8948 "safe-buffer": "^5.2.1",
8949 "typed-array-buffer": "^1.0.3"
8950 },
8951 "engines": {
8952 "node": ">= 0.4"
8953 }
8954 },
8955 "node_modules/to-buffer/node_modules/isarray": {
8956 "version": "2.0.5",
8957 "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
8958 "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
8959 "license": "MIT"
8960 },
8961 "node_modules/to-buffer/node_modules/safe-buffer": {
8962 "version": "5.2.1",
8963 "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
8964 "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
8965 "funding": [
8966 {
8967 "type": "github",
8968 "url": "https://github.com/sponsors/feross"
8969 },
8970 {
8971 "type": "patreon",
8972 "url": "https://www.patreon.com/feross"
8973 },
8974 {
8975 "type": "consulting",
8976 "url": "https://feross.org/support"
8977 }
8978 ],
8979 "license": "MIT"
8980 },
8608 "node_modules/to-regex-range": {8981 "node_modules/to-regex-range": {
8609 "version": "5.0.1",8982 "version": "5.0.1",
8610 "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",8983 "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -8753,6 +9126,20 @@
8753 "node": ">= 0.6"9126 "node": ">= 0.6"
8754 }9127 }
8755 },9128 },
9129 "node_modules/typed-array-buffer": {
9130 "version": "1.0.3",
9131 "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
9132 "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
9133 "license": "MIT",
9134 "dependencies": {
9135 "call-bound": "^1.0.3",
9136 "es-errors": "^1.3.0",
9137 "is-typed-array": "^1.1.14"
9138 },
9139 "engines": {
9140 "node": ">= 0.4"
9141 }
9142 },
8756 "node_modules/typedarray": {9143 "node_modules/typedarray": {
8757 "version": "0.0.6",9144 "version": "0.0.6",
8758 "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",9145 "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -9101,6 +9488,27 @@
9101 "node": ">= 8"9488 "node": ">= 8"
9102 }9489 }
9103 },9490 },
9491 "node_modules/which-typed-array": {
9492 "version": "1.1.20",
9493 "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
9494 "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==",
9495 "license": "MIT",
9496 "dependencies": {
9497 "available-typed-arrays": "^1.0.7",
9498 "call-bind": "^1.0.8",
9499 "call-bound": "^1.0.4",
9500 "for-each": "^0.3.5",
9501 "get-proto": "^1.0.1",
9502 "gopd": "^1.2.0",
9503 "has-tostringtag": "^1.0.2"
9504 },
9505 "engines": {
9506 "node": ">= 0.4"
9507 },
9508 "funding": {
9509 "url": "https://github.com/sponsors/ljharb"
9510 }
9511 },
9104 "node_modules/wordwrap": {9512 "node_modules/wordwrap": {
9105 "version": "1.0.0",9513 "version": "1.0.0",
9106 "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",9514 "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
package.json+1 -0
@@ -61,6 +61,7 @@
61 "ip-matching": "^2.1.2",61 "ip-matching": "^2.1.2",
62 "ip-regex": "^5.0.0",62 "ip-regex": "^5.0.0",
63 "ipaddr.js": "^2.2.0",63 "ipaddr.js": "^2.2.0",
64 "isomorphic-git": "^1.36.3",
64 "is-docker": "^3.0.0",65 "is-docker": "^3.0.0",
65 "localforage": "^1.10.0",66 "localforage": "^1.10.0",
66 "lodash": "^4.17.21",67 "lodash": "^4.17.21",
plugins.js+3 -1
@@ -9,11 +9,13 @@ import process from 'node:process';
9import { fileURLToPath } from 'node:url';9import { fileURLToPath } from 'node:url';
1010
11import { default as git, CheckRepoActions } from 'simple-git';11import { default as git, CheckRepoActions } from 'simple-git';
12import { createGitClient } from './src/git/client.js';
12import { color } from './src/util.js';13import { color } from './src/util.js';
1314
14const __dirname = import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));15const __dirname = import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));
15process.chdir(__dirname);16process.chdir(__dirname);
16const pluginsPath = './plugins';17const pluginsPath = './plugins';
18const gitBackend = process.env.SILLYTAVERN_GIT_BACKEND || 'auto';
1719
18const command = process.argv[2];20const command = process.argv[2];
1921
@@ -87,7 +89,7 @@ async function installPlugin(pluginName) {
87 return console.log(color.yellow(`Directory already exists at ${pluginPath}`));89 return console.log(color.yellow(`Directory already exists at ${pluginPath}`));
88 }90 }
8991
90 await git().clone(pluginName, pluginPath, { '--depth': 1 });92 await createGitClient({ backend: gitBackend }).clone(pluginName, pluginPath, { depth: 1 });
91 console.log(`Plugin ${color.green(pluginName)} installed to ${color.cyan(pluginPath)}`);93 console.log(`Plugin ${color.green(pluginName)} installed to ${color.cyan(pluginPath)}`);
92 } catch (error) {94 } catch (error) {
93 console.error(color.red(`Failed to install plugin ${pluginName}`), error);95 console.error(color.red(`Failed to install plugin ${pluginName}`), error);
src/endpoints/extensions.js+7 -4
@@ -6,6 +6,10 @@ import sanitize from 'sanitize-filename';
6import { CheckRepoActions, default as simpleGit } from 'simple-git';6import { CheckRepoActions, default as simpleGit } from 'simple-git';
77
8import { PUBLIC_DIRECTORIES } from '../constants.js';8import { PUBLIC_DIRECTORIES } from '../constants.js';
9import { getConfigValue } from '../util.js';
10import { createGitClient } from '../git/client.js';
11
12const gitBackend = getConfigValue('git.backend', 'auto');
913
10/**14/**
11 * @type {Partial<import('simple-git').SimpleGitOptions>}15 * @type {Partial<import('simple-git').SimpleGitOptions>}
@@ -76,8 +80,7 @@ router.post('/install', async (request, response) => {
76 }80 }
7781
78 try {82 try {
79 // No timeout for cloning, as it may take a while depending on the repo size83 const git = createGitClient({ backend: gitBackend });
80 const git = simpleGit();
8184
82 // make sure the third-party directory exists85 // make sure the third-party directory exists
83 if (!fs.existsSync(path.join(request.user.directories.extensions))) {86 if (!fs.existsSync(path.join(request.user.directories.extensions))) {
@@ -102,9 +105,9 @@ router.post('/install', async (request, response) => {
102 return response.status(409).send(`Directory already exists at ${extensionPath}`);105 return response.status(409).send(`Directory already exists at ${extensionPath}`);
103 }106 }
104107
105 const cloneOptions = { '--depth': 1 };108 const cloneOptions = { depth: 1 };
106 if (branch) {109 if (branch) {
107 cloneOptions['--branch'] = branch;110 cloneOptions.branch = branch;
108 }111 }
109 await git.clone(url, extensionPath, cloneOptions);112 await git.clone(url, extensionPath, cloneOptions);
110 console.info(`Extension has been cloned to ${extensionPath} from ${url} at ${branch || '(default)'} branch`);113 console.info(`Extension has been cloned to ${extensionPath} from ${url} at ${branch || '(default)'} branch`);
src/git/client.js+138 -0
@@ -0,0 +1,138 @@
1import fs from 'node:fs';
2
3import { sync as commandExistsSync } from 'command-exists';
4import git from 'isomorphic-git';
5import http from 'isomorphic-git/http/node';
6import simpleGit from 'simple-git';
7
8/** @type {{ AUTO: 'auto', SYSTEM: 'system', BUILTIN: 'builtin' }} */
9export const GIT_BACKENDS = {
10 AUTO: 'auto',
11 SYSTEM: 'system',
12 BUILTIN: 'builtin',
13};
14
15/**
16 * @param {string | undefined | null} preferredBackend
17 * @returns {'system' | 'builtin'}
18 */
19function resolveBackend(preferredBackend) {
20 const normalized = typeof preferredBackend === 'string' ? preferredBackend.trim().toLowerCase() : GIT_BACKENDS.AUTO;
21 const backend = normalized === GIT_BACKENDS.SYSTEM
22 ? GIT_BACKENDS.SYSTEM
23 : normalized === GIT_BACKENDS.BUILTIN
24 ? GIT_BACKENDS.BUILTIN
25 : GIT_BACKENDS.AUTO;
26 const systemGitAvailable = commandExistsSync('git');
27
28 if (backend === GIT_BACKENDS.SYSTEM && !systemGitAvailable) {
29 throw new Error('System git backend is configured, but no git binary was found in PATH.');
30 }
31
32 if (backend === GIT_BACKENDS.SYSTEM || (backend === GIT_BACKENDS.AUTO && systemGitAvailable)) {
33 return GIT_BACKENDS.SYSTEM;
34 }
35
36 return GIT_BACKENDS.BUILTIN;
37}
38
39/**
40 * @typedef {object} GitCloneOptions
41 * @property {number} [depth]
42 * @property {string} [branch]
43 */
44
45const SUPPORTED_CLONE_OPTIONS = new Set(['depth', 'branch']);
46
47/**
48 * @param {GitCloneOptions} [options]
49 * @returns {{ depth?: number, branch?: string }}
50 */
51function normalizeCloneOptions(options = {}) {
52 for (const key of Object.keys(options)) {
53 if (!SUPPORTED_CLONE_OPTIONS.has(key)) {
54 throw new Error(`Unsupported clone option: ${key}`);
55 }
56 }
57 return { depth: options.depth, branch: options.branch };
58}
59
60/**
61 * @typedef {object} GitClient
62 * @property {'system' | 'builtin'} backend
63 * @property {(url: string, localPath: string, options?: GitCloneOptions) => Promise<void>} clone
64 */
65
66/**
67 * @param {{ backend?: string }} [options]
68 * @returns {GitClient}
69 */
70export function createGitClient(options = {}) {
71 const backend = resolveBackend(options.backend);
72 if (backend === GIT_BACKENDS.SYSTEM) {
73 return new SimpleGitClient();
74 }
75
76 return new IsomorphicGitClient();
77}
78
79/**
80 * @implements {GitClient}
81 */
82class SimpleGitClient {
83 constructor() {
84 this.backend = GIT_BACKENDS.SYSTEM;
85 this.git = simpleGit();
86 }
87
88 /**
89 * @param {string} url
90 * @param {string} localPath
91 * @param {GitCloneOptions} [options]
92 * @returns {Promise<void>}
93 */
94 async clone(url, localPath, options = {}) {
95 const { depth, branch } = normalizeCloneOptions(options);
96 /** @type {Record<string, any>} */
97 const cloneOptions = {};
98
99 if (depth !== undefined) {
100 cloneOptions['--depth'] = depth;
101 }
102
103 if (branch) {
104 cloneOptions['--branch'] = branch;
105 }
106
107 await this.git.clone(url, localPath, cloneOptions);
108 }
109}
110
111/**
112 * @implements {GitClient}
113 */
114class IsomorphicGitClient {
115 constructor() {
116 this.backend = GIT_BACKENDS.BUILTIN;
117 }
118
119 /**
120 * @param {string} url
121 * @param {string} localPath
122 * @param {GitCloneOptions} [options]
123 * @returns {Promise<void>}
124 */
125 async clone(url, localPath, options = {}) {
126 const { depth, branch } = normalizeCloneOptions(options);
127
128 await git.clone({
129 fs,
130 http,
131 dir: localPath,
132 url,
133 depth,
134 ref: branch,
135 singleBranch: depth !== undefined || Boolean(branch),
136 });
137 }
138}