Paquete getopts usado para obtener parametros

- Usuario y contraseña proporcionados via configuración
 - Errores solucionados
 - Código reorganizado
This commit is contained in:
Guillermo Bonet 2022-06-20 19:52:32 +02:00
parent 054e318988
commit decbf01333
10 changed files with 814 additions and 34 deletions

102
main.js
View File

@ -5,14 +5,12 @@ const fetch = require('node-fetch');
const colors = require('colors');
const os = require('os');
const fs = require('fs');
const getopts = require('getopts');
const homeDir = os.homedir();
const configFile = `${homeDir}/.grafana-find.json`;
const error = `[ERROR]: `.bold;
const user = process.argv[2];
const findAll = process.argv[3];
console.log(
`Grafana-Find (${packageJson.description})`.yellow.bold,
`v${packageJson.version}`.cyan.bold
@ -23,23 +21,50 @@ if (!fs.existsSync(configFile)) {
process.exit(1);
}
if (!process.argv[2] || process.argv[2]===`?` || process.argv[2]===`/?` || process.argv[2]===`help` || process.argv[2]===`/help`) {
console.log(`Usage:`.gray, `grafana-find`, `<user>`.blue, `<string to search>\n`.magenta);
process.exit(1);
}
const usage = {
description: 'Utility to find strings in dashboards',
params: {
user: 'Grafana username',
version: 'Display the version number and exit',
help: 'Display this help message'
}
};
if (!process.argv[3]) {
const opts = getopts(process.argv.slice(2), {
alias: {
user: 'u',
version: 'v',
help: 'h'
},
boolean: [
'version',
'help'
]
});
if (opts.version) {
process.exit();
}
if (opts.help) {
console.log(`Usage:`.gray, `grafana-find`, `<user>`.blue, `<string to search>\n`.magenta);
process.exit();
}
if (!opts._[0]) {
console.error(`${error}The string to search for is missing\n`.red);
process.exit(1);
}
if (process.argv[4]) {
if (opts._.length > 1) {
console.error(`${error}This command doesn't allow more parameters\n`.red);
process.exit(1);
}
const findAll = opts._[0];
const config = require(configFile);
const grafanaUrl = config.grafanaUrl;
let user = config.user;
let passw = config.password;
const grafanaApi = `${grafanaUrl}/api`;
const urlOrganizations = `${grafanaUrl}/api/orgs`;
@ -55,31 +80,32 @@ let nameVariables = new Array;
const regexRawSQL = new RegExp(findAll, 'i');
async function main(){
if (!passw) {
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.stdoutMuted = true;
rl.stdoutMuted = true;
const answer = await new Promise(resolve => {
rl.question(colors.green('Enter your password: '), resolve);
rl._writeToOutput = function _writeToOutput(stringToWrite) {
if (rl.stdoutMuted)
rl.output.write("*");
else
rl.output.write(stringToWrite);
};
});
const passw = `${answer}`;
if (!answer) {
console.error(`\n${error}You need to put a password\n`.red);
process.exit(0);
const answer = await new Promise(resolve => {
rl.question(colors.green('Enter your password: '), resolve);
rl._writeToOutput = function _writeToOutput(stringToWrite) {
if (rl.stdoutMuted)
rl.output.write("*");
else
rl.output.write(stringToWrite);
};
});
passw = `${answer}`;
if (!answer) {
console.error(`\n${error}You need to put a password\n`.red);
process.exit(0);
}
rl.close();
}
rl.history = rl.history.slice(1)
rl.close();
const credentials = `Basic ` + Buffer.from(`${user}:${passw}`).toString('base64');
let response = await fetch(urlOrganizations, {
@ -106,9 +132,17 @@ async function main(){
method: "GET",
headers: {
Authorization: credentials
}
},
redirect: 'manual'
});
if (response.status === 302) {
response = await fetch(`${urlDashboards}${AllOrganizations[x].id}`, {
method: 'GET',
redirect: 'manual'
});
}
let allUID = await response.json();
for (let i in allUID) {

6
node_modules/.package-lock.json generated vendored
View File

@ -1,5 +1,6 @@
{
"name": "grafana-find",
"version": "1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
@ -11,6 +12,11 @@
"node": ">=0.1.90"
}
},
"node_modules/getopts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz",
"integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA=="
},
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",

7
node_modules/getopts/LICENSE.md generated vendored Normal file
View File

@ -0,0 +1,7 @@
Copyright © Jorge Bucaran <<https://jorgebucaran.com>>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

264
node_modules/getopts/README.md generated vendored Normal file
View File

@ -0,0 +1,264 @@
# Getopts
> Parse CLI arguments.
- Lightweight drop-in replacement for `minimist` and clones.
- Small (180 LOC), focused, no dependencies.
- Up to [6x faster](#benchmarks) than alternatives!
Break up command-line arguments into key-value pairs for easy look-up and retrieval. Built upon [utility conventions](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02) that have been used for decades, Getopts sane defaults help you write CLI tools that look and feel like the real deal.
```console
$ example --type=module -o main.js *.{js,json}
```
```js
import getopts from "getopts"
const options = getopts(process.argv.slice(2), {
alias: {
output: ["o", "f"],
type: "t",
},
})
```
The result is an object populated with all the parsed arguments.
```js
{
_: ["index.js", "package.json"],
output: "main.js",
type: "module",
o: "main.js",
f: "main.js",
t: "module",
}
```
## Installation
```console
npm install getopts
```
## Parsing rules
### Short options
A short option consists of a `-` followed by a single alphabetic character. Multiple options can be grouped together without spaces. Short options are boolean by default unless followed by an [operand](#operand) (non-option) or if adjacent to any non-alphabetic characters:
```js
getopts(["-ab", "-c"]) //=> { _: [], a:true, b:true, c:true }
```
```js
getopts(["-a", "alpha"]) //=> { _: [], a:"alpha" }
```
```js
getopts(["-abc1"]) //=> { _: [], a:true, b:true, c:1 }
```
Use [`opts.string`](#optsstring) to parse an option as a string regardless.
```js
getopts(["-kF12"], {
string: ["k"],
}) //=> { _: [], k:"F12" }
```
The first operand following an option will be used as its value. Use [`opts.boolean`](#optsboolean) to specify that an option should be parsed as a boolean regardless, causing the following argument to be treated as an operand instead.
```js
getopts(["-a", "alpha"], {
boolean: ["a"],
}) //=> { _: ["alpha"], a:true }
```
Any character listed in the ASCII table can be used as a short option if it's the first character after the dash.
```js
getopts(["-9", "-#10", "-%0.01"]) //=> { _:[], 9:true, #:10, %:0.01 }
```
### Long options
A long option consists of a `--` followed by a name and a value separated by an `=`. Long options without a value are boolean by default.
```js
getopts(["--turbo", "--warp=10"]) //=> { _: [], turbo:true, warp:10 }
```
```js
getopts(["--warp=e=mc^2"]) //=> { _: [], warp:"e=mc^2" }
```
```js
getopts(["--@", "alpha"]) //=> { _: [], @:"alpha" }
```
Negated options start with `--no-` and are always `false`.
```js
getopts(["--no-turbo"]) //=> { _: [], turbo:false }
```
### Operands
Every non-option argument is an operand. Operands are saved to the `result._` operands array.
```js
getopts(["alpha", "-w9", "bravo"]) //=> { _: ["alpha", "bravo"], w:9 }
```
```js
getopts(["--code=alpha", "bravo"]) //=> { _: ["bravo"], code:"alpha" }
```
Everything after a standalone `--` is an operand.
```js
getopts(["--alpha", "--", "--bravo", "--turbo"]) //=> { _:["--bravo", "--turbo"], alpha:true }
```
A single `-` is also treated as an operand.
```js
getopts(["--turbo", "-"]) //=> { _:["-"], turbo:true }
```
### Other
Options specified as boolean or string will be added to the result object as `false` or `""` (even if missing from the arguments array).
```js
getopts([], {
string: ["a"],
boolean: ["b"],
}) //=> { _:[], a:"", b:false }
```
Repeated options are stored as arrays with every value in order of appearance.
```js
getopts(["-x?alpha=bravo", "-x3.14", "-x"] //=> { _:[], a:["?alpha=bravo", 3.14, true] }
```
A value may contain newlines or other control characters.
```js
getopts(["--text=top\n\tbottom"]) //=> { _:[], text:"top\n\tbottom" }
```
`="false"` is converted to boolean by default.
```js
getopts(["--turbo=false"]) //=> { _:[], turbo:false }
```
## API
### `getopts(argv, opts)`
Parse command-line arguments. Returns an object mapping argument names to their values.
### `argv[]`
An array of arguments, usually [`process.argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv).
### `opts.alias`
An object of option aliases. An alias can be a string or an array of strings. Aliases let you declare substitute names for an option, e.g., the short (abbreviated) and long (canonical) variations.
```js
getopts(["-t"], {
alias: {
turbo: ["t", "T"],
},
}) //=> { _:[], t:true, T:true, turbo:true }
```
### `opts.boolean`
An array of options to parse as boolean. In the example below, `t` is parsed as a boolean, causing the following argument to be treated as an operand.
```js
getopts(["-t", "alpha"], {
boolean: ["t"],
}) //=> { _:["alpha"], t:true }
```
### `opts.string`
An array of flags to parse as strings. In the example below, `t` is parsed as a string, causing all adjacent characters to be treated as a single value and not as individual options.
```js
getopts(["-atabc"], {
string: ["t"],
}) //=> { _:[], a:true, t:"abc" }
```
### `opts.default`
An object of default values for options not present in the arguments array.
```js
getopts(["--warp=10"], {
default: {
warp: 15,
turbo: true,
},
}) //=> { _:[], warp:10, turbo:true }
```
### `opts.unknown()`
We call this function for each unknown option. Return `false` to discard the option. Unknown options are those that appear in the arguments array, but are not in `opts.string`, `opts.boolean`, `opts.default`, or `opts.alias`.
```js
getopts(["-abc"], {
unknown: (option) => "a" === option,
}) //=> { _:[], a:true }
```
### `opts.stopEarly`
A boolean property. If `true`, the operands array `_` will be populated with all the arguments after the first operand.
```js
getopts(["-w9", "alpha", "--turbo", "bravo"], {
stopEarly: true,
}) //=> { _:["alpha", "--turbo", "bravo"], w:9 }
```
This property is useful when implementing sub-commands in a CLI.
```js
import getopts from "getopts"
import { install, update, uninstall } from "./commands.js"
const options = getopts(process.argv.slice(2), {
stopEarly: true,
})
const [command, subargv] = options._
if (command === "install") {
install(subargv)
} else if (command === "update") {
update(subargv)
} else if (command === "uninstall") {
uninstall(subargv)
}
```
## Benchmarks
```console
npm --prefix bench start
```
## License
[MIT](LICENSE.md)

193
node_modules/getopts/index.cjs generated vendored Normal file
View File

@ -0,0 +1,193 @@
const EMPTYARR = []
const SHORTSPLIT = /$|[!-@[-`{-~][\s\S]*/g
const isArray = Array.isArray
const parseValue = function (any) {
if (any === "") return ""
if (any === "false") return false
const maybe = +any
return maybe * 0 === 0 ? maybe : any
}
const parseAlias = function (aliases) {
let out = {},
alias,
prev,
any
for (let key in aliases) {
any = aliases[key]
alias = out[key] = isArray(any) ? any : [any]
for (let i = 0; i < alias.length; i++) {
prev = out[alias[i]] = [key]
for (let k = 0; k < alias.length; k++) {
if (i !== k) prev.push(alias[k])
}
}
}
return out
}
const parseDefault = function (aliases, defaults) {
let out = {},
alias,
value
for (let key in defaults) {
alias = aliases[key]
value = defaults[key]
out[key] = value
if (alias === undefined) {
aliases[key] = EMPTYARR
} else {
for (let i = 0; i < alias.length; i++) {
out[alias[i]] = value
}
}
}
return out
}
const parseOptions = function (aliases, options, value) {
let out = {},
key,
alias
if (options !== undefined) {
for (let i = 0; i < options.length; i++) {
key = options[i]
alias = aliases[key]
out[key] = value
if (alias === undefined) {
aliases[key] = EMPTYARR
} else {
for (let k = 0, end = alias.length; k < end; k++) {
out[alias[k]] = value
}
}
}
}
return out
}
const write = function (out, key, value, aliases, unknown) {
let prev,
alias = aliases[key],
len = alias === undefined ? -1 : alias.length
if (len >= 0 || unknown === undefined || unknown(key)) {
prev = out[key]
if (prev === undefined) {
out[key] = value
} else {
if (isArray(prev)) {
prev.push(value)
} else {
out[key] = [prev, value]
}
}
for (let i = 0; i < len; i++) {
out[alias[i]] = out[key]
}
}
}
module.exports = function (argv, opts) {
let unknown = (opts = opts || {}).unknown,
aliases = parseAlias(opts.alias),
strings = parseOptions(aliases, opts.string, ""),
values = parseDefault(aliases, opts.default),
bools = parseOptions(aliases, opts.boolean, false),
stopEarly = opts.stopEarly,
_ = [],
out = { _ },
key,
arg,
end,
match,
value
for (let i = 0, len = argv.length; i < len; i++) {
arg = argv[i]
if (arg[0] !== "-" || arg === "-") {
if (stopEarly) {
while (i < len) {
_.push(argv[i++])
}
} else {
_.push(arg)
}
} else if (arg === "--") {
while (++i < len) {
_.push(argv[i])
}
} else if (arg[1] === "-") {
end = arg.indexOf("=", 2)
if (arg[2] === "n" && arg[3] === "o" && arg[4] === "-") {
key = arg.slice(5, end >= 0 ? end : undefined)
value = false
} else if (end >= 0) {
key = arg.slice(2, end)
value =
bools[key] !== undefined ||
(strings[key] === undefined
? parseValue(arg.slice(end + 1))
: arg.slice(end + 1))
} else {
key = arg.slice(2)
value =
bools[key] !== undefined ||
(len === i + 1 || argv[i + 1][0] === "-"
? strings[key] === undefined
? true
: ""
: strings[key] === undefined
? parseValue(argv[++i])
: argv[++i])
}
write(out, key, value, aliases, unknown)
} else {
SHORTSPLIT.lastIndex = 2
match = SHORTSPLIT.exec(arg)
end = match.index
value = match[0]
for (let k = 1; k < end; k++) {
write(
out,
(key = arg[k]),
k + 1 < end
? strings[key] === undefined ||
arg.substring(k + 1, (k = end)) + value
: value === ""
? len === i + 1 || argv[i + 1][0] === "-"
? strings[key] === undefined || ""
: bools[key] !== undefined ||
(strings[key] === undefined ? parseValue(argv[++i]) : argv[++i])
: bools[key] !== undefined ||
(strings[key] === undefined ? parseValue(value) : value),
aliases,
unknown
)
}
}
}
for (let key in values) if (out[key] === undefined) out[key] = values[key]
for (let key in bools) if (out[key] === undefined) out[key] = false
for (let key in strings) if (out[key] === undefined) out[key] = ""
return out
}

27
node_modules/getopts/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,27 @@
/**
* @param argv Arguments to parse.
* @param options Parsing options (configuration).
* @returns The parsed arguments.
*/
declare function getopts(
argv: string[],
options?: getopts.Options
): getopts.ParsedOptions
export = getopts
declare namespace getopts {
export interface ParsedOptions {
_: string[]
[key: string]: any
}
export interface Options {
alias?: { [key: string]: string | string[] }
string?: string[]
boolean?: string[]
default?: { [key: string]: any }
unknown?: (optionName: string) => boolean
stopEarly?: boolean
}
}

193
node_modules/getopts/index.js generated vendored Normal file
View File

@ -0,0 +1,193 @@
const EMPTYARR = []
const SHORTSPLIT = /$|[!-@[-`{-~][\s\S]*/g
const isArray = Array.isArray
const parseValue = function (any) {
if (any === "") return ""
if (any === "false") return false
const maybe = +any
return maybe * 0 === 0 ? maybe : any
}
const parseAlias = function (aliases) {
let out = {},
alias,
prev,
any
for (let key in aliases) {
any = aliases[key]
alias = out[key] = isArray(any) ? any : [any]
for (let i = 0; i < alias.length; i++) {
prev = out[alias[i]] = [key]
for (let k = 0; k < alias.length; k++) {
if (i !== k) prev.push(alias[k])
}
}
}
return out
}
const parseDefault = function (aliases, defaults) {
let out = {},
alias,
value
for (let key in defaults) {
alias = aliases[key]
value = defaults[key]
out[key] = value
if (alias === undefined) {
aliases[key] = EMPTYARR
} else {
for (let i = 0; i < alias.length; i++) {
out[alias[i]] = value
}
}
}
return out
}
const parseOptions = function (aliases, options, value) {
let out = {},
key,
alias
if (options !== undefined) {
for (let i = 0; i < options.length; i++) {
key = options[i]
alias = aliases[key]
out[key] = value
if (alias === undefined) {
aliases[key] = EMPTYARR
} else {
for (let k = 0, end = alias.length; k < end; k++) {
out[alias[k]] = value
}
}
}
}
return out
}
const write = function (out, key, value, aliases, unknown) {
let prev,
alias = aliases[key],
len = alias === undefined ? -1 : alias.length
if (len >= 0 || unknown === undefined || unknown(key)) {
prev = out[key]
if (prev === undefined) {
out[key] = value
} else {
if (isArray(prev)) {
prev.push(value)
} else {
out[key] = [prev, value]
}
}
for (let i = 0; i < len; i++) {
out[alias[i]] = out[key]
}
}
}
export default function (argv, opts) {
let unknown = (opts = opts || {}).unknown,
aliases = parseAlias(opts.alias),
strings = parseOptions(aliases, opts.string, ""),
values = parseDefault(aliases, opts.default),
bools = parseOptions(aliases, opts.boolean, false),
stopEarly = opts.stopEarly,
_ = [],
out = { _ },
key,
arg,
end,
match,
value
for (let i = 0, len = argv.length; i < len; i++) {
arg = argv[i]
if (arg[0] !== "-" || arg === "-") {
if (stopEarly) {
while (i < len) {
_.push(argv[i++])
}
} else {
_.push(arg)
}
} else if (arg === "--") {
while (++i < len) {
_.push(argv[i])
}
} else if (arg[1] === "-") {
end = arg.indexOf("=", 2)
if (arg[2] === "n" && arg[3] === "o" && arg[4] === "-") {
key = arg.slice(5, end >= 0 ? end : undefined)
value = false
} else if (end >= 0) {
key = arg.slice(2, end)
value =
bools[key] !== undefined ||
(strings[key] === undefined
? parseValue(arg.slice(end + 1))
: arg.slice(end + 1))
} else {
key = arg.slice(2)
value =
bools[key] !== undefined ||
(len === i + 1 || argv[i + 1][0] === "-"
? strings[key] === undefined
? true
: ""
: strings[key] === undefined
? parseValue(argv[++i])
: argv[++i])
}
write(out, key, value, aliases, unknown)
} else {
SHORTSPLIT.lastIndex = 2
match = SHORTSPLIT.exec(arg)
end = match.index
value = match[0]
for (let k = 1; k < end; k++) {
write(
out,
(key = arg[k]),
k + 1 < end
? strings[key] === undefined ||
arg.substring(k + 1, (k = end)) + value
: value === ""
? len === i + 1 || argv[i + 1][0] === "-"
? strings[key] === undefined || ""
: bools[key] !== undefined ||
(strings[key] === undefined ? parseValue(argv[++i]) : argv[++i])
: bools[key] !== undefined ||
(strings[key] === undefined ? parseValue(value) : value),
aliases,
unknown
)
}
}
}
for (let key in values) if (out[key] === undefined) out[key] = values[key]
for (let key in bools) if (out[key] === undefined) out[key] = false
for (let key in strings) if (out[key] === undefined) out[key] = ""
return out
}

41
node_modules/getopts/package.json generated vendored Normal file
View File

@ -0,0 +1,41 @@
{
"name": "getopts",
"version": "2.3.0",
"type": "module",
"main": "index.cjs",
"types": "index.d.ts",
"description": "Parse CLI arguments.",
"repository": "jorgebucaran/getopts",
"license": "MIT",
"exports": {
"./package.json": "./package.json",
".": {
"require": "./index.cjs",
"import": "./index.js"
}
},
"files": [
"*.*(c)[tj]s"
],
"author": "Jorge Bucaran",
"keywords": [
"cli",
"argv",
"flags",
"parse",
"getopts",
"minimist",
"cli-parser"
],
"scripts": {
"test": "c8 twist tests/*.js",
"build": "node -e \"fs.writeFileSync('index.cjs',fs.readFileSync('index.js','utf8').replace(/export default/,'module.exports ='),'utf8')\"",
"deploy": "npm test && git commit --all --message $tag && git tag --sign $tag --message $tag && git push && git push --tags",
"release": "tag=$npm_package_version npm run deploy && npm publish --access public",
"prepare": "npm run build"
},
"devDependencies": {
"c8": "*",
"twist": "*"
}
}

14
package-lock.json generated
View File

@ -1,12 +1,16 @@
{
"name": "grafana-find",
"version": "1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "grafana-find",
"version": "1.0",
"license": "GPL-3.0",
"dependencies": {
"colors": "^1.4.0",
"getopts": "^2.3.0",
"node-fetch": "^2.6.7",
"object-hash": "^3.0.0"
},
@ -23,6 +27,11 @@
"node": ">=0.1.90"
}
},
"node_modules/getopts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz",
"integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA=="
},
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@ -76,6 +85,11 @@
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
},
"getopts": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz",
"integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA=="
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",

View File

@ -6,6 +6,7 @@
"license": "GPL-3.0",
"dependencies": {
"colors": "^1.4.0",
"getopts": "^2.3.0",
"node-fetch": "^2.6.7",
"object-hash": "^3.0.0"
},