mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Co-authored-by: Jacob MacDonald <jakemac@google.com> Co-authored-by: Adam Weidman <65992621+adamfweidman@users.noreply.github.com>
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ Note that all of these commands will only be reflected in active CLI sessions on
|
|||||||
|
|
||||||
### Installing an extension
|
### Installing an extension
|
||||||
|
|
||||||
You can install an extension using `gemini extensions install` with either a GitHub URL source or `--path=some/local/path`.
|
You can install an extension using `gemini extensions install` with either a GitHub URL or a local path`.
|
||||||
|
|
||||||
Note that we create a copy of the installed extension, so you will need to run `gemini extensions update` to pull in changes from both locally-defined extensions and those on GitHub.
|
Note that we create a copy of the installed extension, so you will need to run `gemini extensions update` to pull in changes from both locally-defined extensions and those on GitHub.
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ test('installs a local extension, verifies a command, and updates it', async ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await rig.runCommand(
|
const result = await rig.runCommand(
|
||||||
['extensions', 'install', `--path=${rig.testDir!}`],
|
['extensions', 'install', `${rig.testDir!}`],
|
||||||
{ stdin: 'y\n' },
|
{ stdin: 'y\n' },
|
||||||
);
|
);
|
||||||
expect(result).toContain('test-extension');
|
expect(result).toContain('test-extension');
|
||||||
|
|||||||
Generated
+546
-25
@@ -3820,6 +3820,16 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/archiver": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-a6wUll6k3zX6qs5KlxIggs1P1JcYJaTCx2gnlr+f0S1yd2DoaEwoIK10HmBaLnZwWneBz+JBm0dwcZu0zECBcQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/readdir-glob": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/aria-query": {
|
"node_modules/@types/aria-query": {
|
||||||
"version": "5.0.4",
|
"version": "5.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||||
@@ -4151,6 +4161,16 @@
|
|||||||
"@types/react": "^19.0.0"
|
"@types/react": "^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/readdir-glob": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/request": {
|
"node_modules/@types/request": {
|
||||||
"version": "2.48.13",
|
"version": "2.48.13",
|
||||||
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.13.tgz",
|
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.13.tgz",
|
||||||
@@ -5354,6 +5374,150 @@
|
|||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/archiver": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"archiver-utils": "^5.0.2",
|
||||||
|
"async": "^3.2.4",
|
||||||
|
"buffer-crc32": "^1.0.0",
|
||||||
|
"readable-stream": "^4.0.0",
|
||||||
|
"readdir-glob": "^1.1.2",
|
||||||
|
"tar-stream": "^3.0.0",
|
||||||
|
"zip-stream": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/archiver-utils": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"glob": "^10.0.0",
|
||||||
|
"graceful-fs": "^4.2.0",
|
||||||
|
"is-stream": "^2.0.1",
|
||||||
|
"lazystream": "^1.0.0",
|
||||||
|
"lodash": "^4.17.15",
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"readable-stream": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/archiver-utils/node_modules/buffer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/archiver-utils/node_modules/readable-stream": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"string_decoder": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/archiver/node_modules/buffer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/archiver/node_modules/buffer-crc32": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/archiver/node_modules/readable-stream": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"string_decoder": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/archiver/node_modules/tar-stream": {
|
||||||
|
"version": "3.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
|
||||||
|
"integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"b4a": "^1.6.4",
|
||||||
|
"fast-fifo": "^1.2.0",
|
||||||
|
"streamx": "^2.15.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/argparse": {
|
"node_modules/argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
@@ -5670,12 +5834,34 @@
|
|||||||
"typed-rest-client": "^1.8.4"
|
"typed-rest-client": "^1.8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/b4a": {
|
||||||
|
"version": "1.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz",
|
||||||
|
"integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react-native-b4a": "*"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-native-b4a": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/bare-events": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
@@ -6537,6 +6723,65 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/compress-commons": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"crc-32": "^1.2.0",
|
||||||
|
"crc32-stream": "^6.0.0",
|
||||||
|
"is-stream": "^2.0.1",
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"readable-stream": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/compress-commons/node_modules/buffer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/compress-commons/node_modules/readable-stream": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"string_decoder": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/concat-map": {
|
"node_modules/concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
@@ -6650,6 +6895,75 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crc-32": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"crc32": "bin/crc32.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/crc32-stream": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"crc-32": "^1.2.0",
|
||||||
|
"readable-stream": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/crc32-stream/node_modules/buffer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/crc32-stream/node_modules/readable-stream": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"string_decoder": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-env": {
|
"node_modules/cross-env": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||||
@@ -8009,6 +8323,26 @@
|
|||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/events": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/events-universal": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"bare-events": "^2.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eventsource": {
|
"node_modules/eventsource": {
|
||||||
"version": "3.0.7",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
|
||||||
@@ -8228,6 +8562,13 @@
|
|||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-fifo": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
|
||||||
|
"integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.3.3",
|
"version": "3.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||||
@@ -9558,8 +9899,7 @@
|
|||||||
"url": "https://feross.org/support"
|
"url": "https://feross.org/support"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause"
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"node_modules/ignore": {
|
"node_modules/ignore": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
@@ -10871,6 +11211,59 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lazystream": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": "^2.0.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lazystream/node_modules/isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/lazystream/node_modules/readable-stream": {
|
||||||
|
"version": "2.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||||
|
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.3",
|
||||||
|
"isarray": "~1.0.0",
|
||||||
|
"process-nextick-args": "~2.0.0",
|
||||||
|
"safe-buffer": "~5.1.1",
|
||||||
|
"string_decoder": "~1.1.1",
|
||||||
|
"util-deprecate": "~1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lazystream/node_modules/safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/lazystream/node_modules/string_decoder": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/leac": {
|
"node_modules/leac": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
|
||||||
@@ -11589,9 +11982,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minizlib": {
|
"node_modules/minizlib": {
|
||||||
"version": "3.0.2",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
|
||||||
"integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
|
"integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minipass": "^7.1.2"
|
"minipass": "^7.1.2"
|
||||||
@@ -11600,21 +11993,6 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mkdirp": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"mkdirp": "dist/cjs/src/bin.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mkdirp-classic": {
|
"node_modules/mkdirp-classic": {
|
||||||
"version": "0.5.3",
|
"version": "0.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||||
@@ -11902,6 +12280,16 @@
|
|||||||
"node": "^16.14.0 || >=18.0.0"
|
"node": "^16.14.0 || >=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/normalize-url": {
|
"node_modules/normalize-url": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz",
|
||||||
@@ -13029,6 +13417,23 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/process": {
|
||||||
|
"version": "0.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/process-nextick-args": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
@@ -13482,6 +13887,39 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/readdir-glob": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"minimatch": "^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readdir-glob/node_modules/brace-expansion": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readdir-glob/node_modules/minimatch": {
|
||||||
|
"version": "5.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||||
|
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reflect.getprototypeof": {
|
"node_modules/reflect.getprototypeof": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||||
@@ -14534,6 +14972,18 @@
|
|||||||
"integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
|
"integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/streamx": {
|
||||||
|
"version": "2.23.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz",
|
||||||
|
"integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"events-universal": "^1.0.0",
|
||||||
|
"fast-fifo": "^1.3.2",
|
||||||
|
"text-decoder": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/strict-event-emitter": {
|
"node_modules/strict-event-emitter": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
|
||||||
@@ -15077,16 +15527,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tar": {
|
"node_modules/tar": {
|
||||||
"version": "7.4.3",
|
"version": "7.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz",
|
||||||
"integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
|
"integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@isaacs/fs-minipass": "^4.0.0",
|
"@isaacs/fs-minipass": "^4.0.0",
|
||||||
"chownr": "^3.0.0",
|
"chownr": "^3.0.0",
|
||||||
"minipass": "^7.1.2",
|
"minipass": "^7.1.2",
|
||||||
"minizlib": "^3.0.1",
|
"minizlib": "^3.1.0",
|
||||||
"mkdirp": "^3.0.1",
|
|
||||||
"yallist": "^5.0.0"
|
"yallist": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -15246,6 +15695,16 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/text-decoder": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"b4a": "^1.6.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/text-hex": {
|
"node_modules/text-hex": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||||
@@ -16861,6 +17320,63 @@
|
|||||||
"integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==",
|
"integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/zip-stream": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"archiver-utils": "^5.0.0",
|
||||||
|
"compress-commons": "^6.0.2",
|
||||||
|
"readable-stream": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/zip-stream/node_modules/buffer": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/zip-stream/node_modules/readable-stream": {
|
||||||
|
"version": "4.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
|
||||||
|
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"process": "^0.11.10",
|
||||||
|
"string_decoder": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "3.25.76",
|
"version": "3.25.76",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||||
@@ -17164,6 +17680,7 @@
|
|||||||
"comment-json": "^4.2.5",
|
"comment-json": "^4.2.5",
|
||||||
"diff": "^7.0.0",
|
"diff": "^7.0.0",
|
||||||
"dotenv": "^17.1.0",
|
"dotenv": "^17.1.0",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
"fzf": "^0.5.2",
|
"fzf": "^0.5.2",
|
||||||
"glob": "^10.4.5",
|
"glob": "^10.4.5",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
@@ -17179,6 +17696,7 @@
|
|||||||
"string-width": "^7.1.0",
|
"string-width": "^7.1.0",
|
||||||
"strip-ansi": "^7.1.0",
|
"strip-ansi": "^7.1.0",
|
||||||
"strip-json-comments": "^3.1.1",
|
"strip-json-comments": "^3.1.1",
|
||||||
|
"tar": "^7.5.1",
|
||||||
"undici": "^7.10.0",
|
"undici": "^7.10.0",
|
||||||
"update-notifier": "^7.3.1",
|
"update-notifier": "^7.3.1",
|
||||||
"wrap-ansi": "9.0.2",
|
"wrap-ansi": "9.0.2",
|
||||||
@@ -17192,6 +17710,7 @@
|
|||||||
"@babel/runtime": "^7.27.6",
|
"@babel/runtime": "^7.27.6",
|
||||||
"@google/gemini-cli-test-utils": "file:../test-utils",
|
"@google/gemini-cli-test-utils": "file:../test-utils",
|
||||||
"@testing-library/react": "^16.3.0",
|
"@testing-library/react": "^16.3.0",
|
||||||
|
"@types/archiver": "^6.0.3",
|
||||||
"@types/command-exists": "^1.2.3",
|
"@types/command-exists": "^1.2.3",
|
||||||
"@types/diff": "^7.0.2",
|
"@types/diff": "^7.0.2",
|
||||||
"@types/dotenv": "^6.1.1",
|
"@types/dotenv": "^6.1.1",
|
||||||
@@ -17200,7 +17719,9 @@
|
|||||||
"@types/react-dom": "^19.1.6",
|
"@types/react-dom": "^19.1.6",
|
||||||
"@types/semver": "^7.7.0",
|
"@types/semver": "^7.7.0",
|
||||||
"@types/shell-quote": "^1.7.5",
|
"@types/shell-quote": "^1.7.5",
|
||||||
|
"@types/tar": "^6.1.13",
|
||||||
"@types/yargs": "^17.0.32",
|
"@types/yargs": "^17.0.32",
|
||||||
|
"archiver": "^7.0.1",
|
||||||
"ink-testing-library": "^4.0.0",
|
"ink-testing-library": "^4.0.0",
|
||||||
"jsdom": "^26.1.0",
|
"jsdom": "^26.1.0",
|
||||||
"pretty-format": "^30.0.2",
|
"pretty-format": "^30.0.2",
|
||||||
|
|||||||
@@ -53,7 +53,9 @@
|
|||||||
"string-width": "^7.1.0",
|
"string-width": "^7.1.0",
|
||||||
"strip-ansi": "^7.1.0",
|
"strip-ansi": "^7.1.0",
|
||||||
"strip-json-comments": "^3.1.1",
|
"strip-json-comments": "^3.1.1",
|
||||||
|
"tar": "^7.5.1",
|
||||||
"undici": "^7.10.0",
|
"undici": "^7.10.0",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
"update-notifier": "^7.3.1",
|
"update-notifier": "^7.3.1",
|
||||||
"wrap-ansi": "9.0.2",
|
"wrap-ansi": "9.0.2",
|
||||||
"yargs": "^17.7.2",
|
"yargs": "^17.7.2",
|
||||||
@@ -63,6 +65,7 @@
|
|||||||
"@babel/runtime": "^7.27.6",
|
"@babel/runtime": "^7.27.6",
|
||||||
"@google/gemini-cli-test-utils": "file:../test-utils",
|
"@google/gemini-cli-test-utils": "file:../test-utils",
|
||||||
"@testing-library/react": "^16.3.0",
|
"@testing-library/react": "^16.3.0",
|
||||||
|
"@types/archiver": "^6.0.3",
|
||||||
"@types/command-exists": "^1.2.3",
|
"@types/command-exists": "^1.2.3",
|
||||||
"@types/diff": "^7.0.2",
|
"@types/diff": "^7.0.2",
|
||||||
"@types/dotenv": "^6.1.1",
|
"@types/dotenv": "^6.1.1",
|
||||||
@@ -71,7 +74,9 @@
|
|||||||
"@types/react-dom": "^19.1.6",
|
"@types/react-dom": "^19.1.6",
|
||||||
"@types/semver": "^7.7.0",
|
"@types/semver": "^7.7.0",
|
||||||
"@types/shell-quote": "^1.7.5",
|
"@types/shell-quote": "^1.7.5",
|
||||||
|
"@types/tar": "^6.1.13",
|
||||||
"@types/yargs": "^17.0.32",
|
"@types/yargs": "^17.0.32",
|
||||||
|
"archiver": "^7.0.1",
|
||||||
"ink-testing-library": "^4.0.0",
|
"ink-testing-library": "^4.0.0",
|
||||||
"jsdom": "^26.1.0",
|
"jsdom": "^26.1.0",
|
||||||
"pretty-format": "^30.0.2",
|
"pretty-format": "^30.0.2",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import yargs from 'yargs';
|
|||||||
|
|
||||||
const mockInstallExtension = vi.hoisted(() => vi.fn());
|
const mockInstallExtension = vi.hoisted(() => vi.fn());
|
||||||
const mockRequestConsentNonInteractive = vi.hoisted(() => vi.fn());
|
const mockRequestConsentNonInteractive = vi.hoisted(() => vi.fn());
|
||||||
|
const mockStat = vi.hoisted(() => vi.fn());
|
||||||
|
|
||||||
vi.mock('../../config/extension.js', () => ({
|
vi.mock('../../config/extension.js', () => ({
|
||||||
installExtension: mockInstallExtension,
|
installExtension: mockInstallExtension,
|
||||||
@@ -20,35 +21,20 @@ vi.mock('../../utils/errors.js', () => ({
|
|||||||
getErrorMessage: vi.fn((error: Error) => error.message),
|
getErrorMessage: vi.fn((error: Error) => error.message),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
vi.mock('node:fs/promises', () => ({
|
||||||
|
stat: mockStat,
|
||||||
|
default: {
|
||||||
|
stat: mockStat,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
describe('extensions install command', () => {
|
describe('extensions install command', () => {
|
||||||
it('should fail if no source is provided', () => {
|
it('should fail if no source is provided', () => {
|
||||||
const validationParser = yargs([]).command(installCommand).fail(false);
|
const validationParser = yargs([]).command(installCommand).fail(false);
|
||||||
expect(() => validationParser.parse('install')).toThrow(
|
expect(() => validationParser.parse('install')).toThrow(
|
||||||
'Either source or --path must be provided.',
|
'Not enough non-option arguments: got 0, need at least 1',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail if both git source and local path are provided', () => {
|
|
||||||
const validationParser = yargs([])
|
|
||||||
.command(installCommand)
|
|
||||||
.fail(false)
|
|
||||||
.locale('en');
|
|
||||||
expect(() =>
|
|
||||||
validationParser.parse('install some-url --path /some/path'),
|
|
||||||
).toThrow('Arguments source and path are mutually exclusive');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail if both auto update and local path are provided', () => {
|
|
||||||
const validationParser = yargs([])
|
|
||||||
.command(installCommand)
|
|
||||||
.fail(false)
|
|
||||||
.locale('en');
|
|
||||||
expect(() =>
|
|
||||||
validationParser.parse(
|
|
||||||
'install some-url --path /some/path --auto-update',
|
|
||||||
),
|
|
||||||
).toThrow('Arguments path and auto-update are mutually exclusive');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('handleInstall', () => {
|
describe('handleInstall', () => {
|
||||||
@@ -67,6 +53,7 @@ describe('handleInstall', () => {
|
|||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
mockInstallExtension.mockClear();
|
mockInstallExtension.mockClear();
|
||||||
mockRequestConsentNonInteractive.mockClear();
|
mockRequestConsentNonInteractive.mockClear();
|
||||||
|
mockStat.mockClear();
|
||||||
vi.resetAllMocks();
|
vi.resetAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -107,13 +94,12 @@ describe('handleInstall', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('throws an error from an unknown source', async () => {
|
it('throws an error from an unknown source', async () => {
|
||||||
|
mockStat.mockRejectedValue(new Error('ENOENT: no such file or directory'));
|
||||||
await handleInstall({
|
await handleInstall({
|
||||||
source: 'test://google.com',
|
source: 'test://google.com',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
expect(consoleErrorSpy).toHaveBeenCalledWith('Install source not found.');
|
||||||
'The source "test://google.com" is not a valid URL format.',
|
|
||||||
);
|
|
||||||
expect(processSpy).toHaveBeenCalledWith(1);
|
expect(processSpy).toHaveBeenCalledWith(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -131,9 +117,9 @@ describe('handleInstall', () => {
|
|||||||
|
|
||||||
it('should install an extension from a local path', async () => {
|
it('should install an extension from a local path', async () => {
|
||||||
mockInstallExtension.mockResolvedValue('local-extension');
|
mockInstallExtension.mockResolvedValue('local-extension');
|
||||||
|
mockStat.mockResolvedValue({});
|
||||||
await handleInstall({
|
await handleInstall({
|
||||||
path: '/some/path',
|
source: '/some/path',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(consoleLogSpy).toHaveBeenCalledWith(
|
expect(consoleLogSpy).toHaveBeenCalledWith(
|
||||||
@@ -141,15 +127,6 @@ describe('handleInstall', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if no source or path is provided', async () => {
|
|
||||||
await handleInstall({});
|
|
||||||
|
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
||||||
'Either --source or --path must be provided.',
|
|
||||||
);
|
|
||||||
expect(processSpy).toHaveBeenCalledWith(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if install extension fails', async () => {
|
it('should throw an error if install extension fails', async () => {
|
||||||
mockInstallExtension.mockRejectedValue(
|
mockInstallExtension.mockRejectedValue(
|
||||||
new Error('Install extension failed'),
|
new Error('Install extension failed'),
|
||||||
|
|||||||
@@ -10,12 +10,11 @@ import {
|
|||||||
requestConsentNonInteractive,
|
requestConsentNonInteractive,
|
||||||
} from '../../config/extension.js';
|
} from '../../config/extension.js';
|
||||||
import type { ExtensionInstallMetadata } from '@google/gemini-cli-core';
|
import type { ExtensionInstallMetadata } from '@google/gemini-cli-core';
|
||||||
|
|
||||||
import { getErrorMessage } from '../../utils/errors.js';
|
import { getErrorMessage } from '../../utils/errors.js';
|
||||||
|
import { stat } from 'node:fs/promises';
|
||||||
|
|
||||||
interface InstallArgs {
|
interface InstallArgs {
|
||||||
source?: string;
|
source: string;
|
||||||
path?: string;
|
|
||||||
ref?: string;
|
ref?: string;
|
||||||
autoUpdate?: boolean;
|
autoUpdate?: boolean;
|
||||||
}
|
}
|
||||||
@@ -23,32 +22,34 @@ interface InstallArgs {
|
|||||||
export async function handleInstall(args: InstallArgs) {
|
export async function handleInstall(args: InstallArgs) {
|
||||||
try {
|
try {
|
||||||
let installMetadata: ExtensionInstallMetadata;
|
let installMetadata: ExtensionInstallMetadata;
|
||||||
if (args.source) {
|
const { source } = args;
|
||||||
const { source } = args;
|
if (
|
||||||
if (
|
source.startsWith('http://') ||
|
||||||
source.startsWith('http://') ||
|
source.startsWith('https://') ||
|
||||||
source.startsWith('https://') ||
|
source.startsWith('git@') ||
|
||||||
source.startsWith('git@') ||
|
source.startsWith('sso://')
|
||||||
source.startsWith('sso://')
|
) {
|
||||||
) {
|
|
||||||
installMetadata = {
|
|
||||||
source,
|
|
||||||
type: 'git',
|
|
||||||
ref: args.ref,
|
|
||||||
autoUpdate: args.autoUpdate,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw new Error(`The source "${source}" is not a valid URL format.`);
|
|
||||||
}
|
|
||||||
} else if (args.path) {
|
|
||||||
installMetadata = {
|
installMetadata = {
|
||||||
source: args.path,
|
source,
|
||||||
type: 'local',
|
type: 'git',
|
||||||
|
ref: args.ref,
|
||||||
autoUpdate: args.autoUpdate,
|
autoUpdate: args.autoUpdate,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// This should not be reached due to the yargs check.
|
if (args.ref || args.autoUpdate) {
|
||||||
throw new Error('Either --source or --path must be provided.');
|
throw new Error(
|
||||||
|
'--ref and --auto-update are not applicable for local extensions.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await stat(source);
|
||||||
|
installMetadata = {
|
||||||
|
source,
|
||||||
|
type: 'local',
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
throw new Error('Install source not found.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = await installExtension(
|
const name = await installExtension(
|
||||||
@@ -63,17 +64,14 @@ export async function handleInstall(args: InstallArgs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const installCommand: CommandModule = {
|
export const installCommand: CommandModule = {
|
||||||
command: 'install [<source>] [--path] [--ref] [--auto-update]',
|
command: 'install <source>',
|
||||||
describe: 'Installs an extension from a git repository URL or a local path.',
|
describe: 'Installs an extension from a git repository URL or a local path.',
|
||||||
builder: (yargs) =>
|
builder: (yargs) =>
|
||||||
yargs
|
yargs
|
||||||
.positional('source', {
|
.positional('source', {
|
||||||
describe: 'The github URL of the extension to install.',
|
describe: 'The github URL or local path of the extension to install.',
|
||||||
type: 'string',
|
|
||||||
})
|
|
||||||
.option('path', {
|
|
||||||
describe: 'Path to a local extension directory.',
|
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
demandOption: true,
|
||||||
})
|
})
|
||||||
.option('ref', {
|
.option('ref', {
|
||||||
describe: 'The git ref to install from.',
|
describe: 'The git ref to install from.',
|
||||||
@@ -83,19 +81,15 @@ export const installCommand: CommandModule = {
|
|||||||
describe: 'Enable auto-update for this extension.',
|
describe: 'Enable auto-update for this extension.',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
})
|
})
|
||||||
.conflicts('source', 'path')
|
|
||||||
.conflicts('path', 'ref')
|
|
||||||
.conflicts('path', 'auto-update')
|
|
||||||
.check((argv) => {
|
.check((argv) => {
|
||||||
if (!argv.source && !argv.path) {
|
if (!argv.source) {
|
||||||
throw new Error('Either source or --path must be provided.');
|
throw new Error('The source argument must be provided.');
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
handler: async (argv) => {
|
handler: async (argv) => {
|
||||||
await handleInstall({
|
await handleInstall({
|
||||||
source: argv['source'] as string | undefined,
|
source: argv['source'] as string,
|
||||||
path: argv['path'] as string | undefined,
|
|
||||||
ref: argv['ref'] as string | undefined,
|
ref: argv['ref'] as string | undefined,
|
||||||
autoUpdate: argv['auto-update'] as boolean | undefined,
|
autoUpdate: argv['auto-update'] as boolean | undefined,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,12 +8,18 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|||||||
import {
|
import {
|
||||||
checkForExtensionUpdate,
|
checkForExtensionUpdate,
|
||||||
cloneFromGit,
|
cloneFromGit,
|
||||||
|
extractFile,
|
||||||
findReleaseAsset,
|
findReleaseAsset,
|
||||||
parseGitHubRepoForReleases,
|
parseGitHubRepoForReleases,
|
||||||
} from './github.js';
|
} from './github.js';
|
||||||
import { simpleGit, type SimpleGit } from 'simple-git';
|
import { simpleGit, type SimpleGit } from 'simple-git';
|
||||||
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
|
import { ExtensionUpdateState } from '../../ui/state/extensions.js';
|
||||||
import type * as os from 'node:os';
|
import * as os from 'node:os';
|
||||||
|
import * as fs from 'node:fs/promises';
|
||||||
|
import * as fsSync from 'node:fs';
|
||||||
|
import * as path from 'node:path';
|
||||||
|
import * as tar from 'tar';
|
||||||
|
import * as archiver from 'archiver';
|
||||||
import type { GeminiCLIExtension } from '@google/gemini-cli-core';
|
import type { GeminiCLIExtension } from '@google/gemini-cli-core';
|
||||||
|
|
||||||
const mockPlatform = vi.hoisted(() => vi.fn());
|
const mockPlatform = vi.hoisted(() => vi.fn());
|
||||||
@@ -341,4 +347,83 @@ describe('git extension helpers', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('extractFile', () => {
|
||||||
|
let tempDir: string;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gemini-test-'));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await fs.rm(tempDir, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract a .tar.gz file', async () => {
|
||||||
|
const archivePath = path.join(tempDir, 'test.tar.gz');
|
||||||
|
const extractionDest = path.join(tempDir, 'extracted');
|
||||||
|
await fs.mkdir(extractionDest);
|
||||||
|
|
||||||
|
// Create a dummy file to be archived
|
||||||
|
const dummyFilePath = path.join(tempDir, 'test.txt');
|
||||||
|
await fs.writeFile(dummyFilePath, 'hello tar');
|
||||||
|
|
||||||
|
// Create the tar.gz file
|
||||||
|
await tar.c(
|
||||||
|
{
|
||||||
|
gzip: true,
|
||||||
|
file: archivePath,
|
||||||
|
cwd: tempDir,
|
||||||
|
},
|
||||||
|
['test.txt'],
|
||||||
|
);
|
||||||
|
|
||||||
|
await extractFile(archivePath, extractionDest);
|
||||||
|
|
||||||
|
const extractedFilePath = path.join(extractionDest, 'test.txt');
|
||||||
|
const content = await fs.readFile(extractedFilePath, 'utf-8');
|
||||||
|
expect(content).toBe('hello tar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should extract a .zip file', async () => {
|
||||||
|
const archivePath = path.join(tempDir, 'test.zip');
|
||||||
|
const extractionDest = path.join(tempDir, 'extracted');
|
||||||
|
await fs.mkdir(extractionDest);
|
||||||
|
|
||||||
|
// Create a dummy file to be archived
|
||||||
|
const dummyFilePath = path.join(tempDir, 'test.txt');
|
||||||
|
await fs.writeFile(dummyFilePath, 'hello zip');
|
||||||
|
|
||||||
|
// Create the zip file
|
||||||
|
const output = fsSync.createWriteStream(archivePath);
|
||||||
|
const archive = archiver.create('zip');
|
||||||
|
|
||||||
|
const streamFinished = new Promise((resolve, reject) => {
|
||||||
|
output.on('close', () => resolve(null));
|
||||||
|
archive.on('error', reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.pipe(output);
|
||||||
|
archive.file(dummyFilePath, { name: 'test.txt' });
|
||||||
|
await archive.finalize();
|
||||||
|
await streamFinished;
|
||||||
|
|
||||||
|
await extractFile(archivePath, extractionDest);
|
||||||
|
|
||||||
|
const extractedFilePath = path.join(extractionDest, 'test.txt');
|
||||||
|
const content = await fs.readFile(extractedFilePath, 'utf-8');
|
||||||
|
expect(content).toBe('hello zip');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error for unsupported file types', async () => {
|
||||||
|
const unsupportedFilePath = path.join(tempDir, 'test.txt');
|
||||||
|
await fs.writeFile(unsupportedFilePath, 'some content');
|
||||||
|
const extractionDest = path.join(tempDir, 'extracted');
|
||||||
|
await fs.mkdir(extractionDest);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
extractFile(unsupportedFilePath, extractionDest),
|
||||||
|
).rejects.toThrow('Unsupported file extension for extraction:');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ import * as os from 'node:os';
|
|||||||
import * as https from 'node:https';
|
import * as https from 'node:https';
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import { EXTENSIONS_CONFIG_FILENAME, loadExtension } from '../extension.js';
|
import { EXTENSIONS_CONFIG_FILENAME, loadExtension } from '../extension.js';
|
||||||
|
import * as tar from 'tar';
|
||||||
|
import extract from 'extract-zip';
|
||||||
|
|
||||||
function getGitHubToken(): string | undefined {
|
function getGitHubToken(): string | undefined {
|
||||||
return process.env['GITHUB_TOKEN'];
|
return process.env['GITHUB_TOKEN'];
|
||||||
@@ -270,7 +271,7 @@ export async function downloadFromGitHubRelease(
|
|||||||
|
|
||||||
await downloadFile(archiveUrl, downloadedAssetPath);
|
await downloadFile(archiveUrl, downloadedAssetPath);
|
||||||
|
|
||||||
extractFile(downloadedAssetPath, destination);
|
await extractFile(downloadedAssetPath, destination);
|
||||||
|
|
||||||
// For regular github releases, the repository is put inside of a top level
|
// For regular github releases, the repository is put inside of a top level
|
||||||
// directory. In this case we should see exactly two file in the destination
|
// directory. In this case we should see exactly two file in the destination
|
||||||
@@ -416,27 +417,15 @@ async function downloadFile(url: string, dest: string): Promise<void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractFile(file: string, dest: string) {
|
export async function extractFile(file: string, dest: string): Promise<void> {
|
||||||
let args: string[];
|
|
||||||
let command: 'tar' | 'unzip';
|
|
||||||
if (file.endsWith('.tar.gz')) {
|
if (file.endsWith('.tar.gz')) {
|
||||||
args = ['-xzf', file, '-C', dest];
|
await tar.x({
|
||||||
command = 'tar';
|
file,
|
||||||
|
cwd: dest,
|
||||||
|
});
|
||||||
} else if (file.endsWith('.zip')) {
|
} else if (file.endsWith('.zip')) {
|
||||||
args = [file, '-d', dest];
|
await extract(file, { dir: dest });
|
||||||
command = 'unzip';
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unsupported file extension for extraction: ${file}`);
|
throw new Error(`Unsupported file extension for extraction: ${file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = spawnSync(command, args, { stdio: 'pipe' });
|
|
||||||
|
|
||||||
if (result.status !== 0) {
|
|
||||||
if (result.error) {
|
|
||||||
throw new Error(`Failed to spawn '${command}': ${result.error.message}`);
|
|
||||||
}
|
|
||||||
throw new Error(
|
|
||||||
`'${command}' command failed with exit code ${result.status}: ${result.stderr.toString()}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ vi.mock('../../utils/processUtils.js', () => ({
|
|||||||
const mockedExit = vi.hoisted(() => vi.fn());
|
const mockedExit = vi.hoisted(() => vi.fn());
|
||||||
const mockedCwd = vi.hoisted(() => vi.fn());
|
const mockedCwd = vi.hoisted(() => vi.fn());
|
||||||
|
|
||||||
vi.mock('process', async () => {
|
vi.mock('node:process', async () => {
|
||||||
const actual = await vi.importActual('process');
|
const actual =
|
||||||
|
await vi.importActual<typeof import('node:process')>('node:process');
|
||||||
return {
|
return {
|
||||||
...actual,
|
...actual,
|
||||||
exit: mockedExit,
|
exit: mockedExit,
|
||||||
|
|||||||
@@ -11,14 +11,19 @@ import type { LoadedSettings } from '../../config/settings.js';
|
|||||||
import { FolderTrustChoice } from '../components/FolderTrustDialog.js';
|
import { FolderTrustChoice } from '../components/FolderTrustDialog.js';
|
||||||
import type { LoadedTrustedFolders } from '../../config/trustedFolders.js';
|
import type { LoadedTrustedFolders } from '../../config/trustedFolders.js';
|
||||||
import { TrustLevel } from '../../config/trustedFolders.js';
|
import { TrustLevel } from '../../config/trustedFolders.js';
|
||||||
import * as process from 'node:process';
|
|
||||||
|
|
||||||
import * as trustedFolders from '../../config/trustedFolders.js';
|
import * as trustedFolders from '../../config/trustedFolders.js';
|
||||||
|
|
||||||
vi.mock('process', () => ({
|
const mockedCwd = vi.hoisted(() => vi.fn());
|
||||||
cwd: vi.fn(),
|
|
||||||
platform: 'linux',
|
vi.mock('node:process', async () => {
|
||||||
}));
|
const actual =
|
||||||
|
await vi.importActual<typeof import('node:process')>('node:process');
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
cwd: mockedCwd,
|
||||||
|
platform: 'linux',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
describe('useFolderTrust', () => {
|
describe('useFolderTrust', () => {
|
||||||
let mockSettings: LoadedSettings;
|
let mockSettings: LoadedSettings;
|
||||||
@@ -47,7 +52,7 @@ describe('useFolderTrust', () => {
|
|||||||
.spyOn(trustedFolders, 'loadTrustedFolders')
|
.spyOn(trustedFolders, 'loadTrustedFolders')
|
||||||
.mockReturnValue(mockTrustedFolders);
|
.mockReturnValue(mockTrustedFolders);
|
||||||
isWorkspaceTrustedSpy = vi.spyOn(trustedFolders, 'isWorkspaceTrusted');
|
isWorkspaceTrustedSpy = vi.spyOn(trustedFolders, 'isWorkspaceTrusted');
|
||||||
(process.cwd as vi.Mock).mockReturnValue('/test/path');
|
mockedCwd.mockReturnValue('/test/path');
|
||||||
onTrustChange = vi.fn();
|
onTrustChange = vi.fn();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user