diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..c88a062 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf6d4a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +db.json +tmp/ +.env +ios/ +dist/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..542d3f6 --- /dev/null +++ b/README.md @@ -0,0 +1,232 @@ + + +[![Paystack Logo](https://res.cloudinary.com/drps6uoe4/image/upload/c_scale,w_200/v1584835701/Paystack-CeruleanBlue-StackBlue-HL_2_neik7g.png)](https://paystack.com) + +# Paystack CLI + + +## About + +As a developer, your most powerful tools - from basic bash commands, to version control and deployment tools - sit in your terminal. The Paystack CLI to makes it easier to set up, test, and manage your Paystack integrations right from that very same terminal. + +With the CLI, you can: + +1. Ping your preset webhook URL with sample event data +2. Tunnel Paystack events directly to your local server without installing third party software +3. Set up sample applications with fully integrated payment channels +4. Interact with Paystack API +5. *Interpret Paystack API Errors* + +## Installing the Paystack CLI + +### Install with npm + + +Paystack requires **[Node.js](https://nodejs.org/)** v16+ to run, To install with npm, run + +`$ npm install -g @paystack-oss/dev-cli` + +## Verify your installation + +Check that your installation was successful by running + +`$ paystack --version` + +The output should look like + +`> @paystack-oss/dev-cli/1.0.0-nightly.0 darwin-x64 node-v16.14.0` + +## Getting started with the Paystack CLI + +Now that you’re all setup, to access your Paystack account and execute commands, run + +`$ paystack login` + +You’ll be required to enter your credentials and choose the business you want to execute commands on its behalf. + +### Commands + +Run `$ paystack —help` to see a list of all commands you can use on the CLI. By default, all commands are run in test mode. To switch to live, append *`--domain live`* to the end of your command. + +Read on for more information on what you can do with the CLI. + +### Manage Webhooks + +Whenever actions are carried out on your Paystack account, we trigger events which your application can listen and respond to. Before now, to implement webhook routes like these, you had to: + +1. Ping your preset webhook URL with sample event data +2. Login to your Paystack Dashboard and set the webhook URL +3. Make a test payment or transfer +4. Review logs +5. Repeat + +The CLI lets you listen to real-time webhook events on your integration and reduces all these steps are reduced to running a single command — + +`$ paystack webhook listen localhost:8080/webhook` + +This command tunnels all your test webhook events to your local server running on port 8080, making it possible for you to run end-to-end tests on your Paystack integration while in development mode. + +You can also run health checks on your webhook URL by sending a sample webhook payload to your server. To do this, run: + +`$ paystack webhook ping --event transfer.success --domain test` + + Check our [documentation](https://paystack.com/docs/payments/webhooks/#supported-events) for a list of supported events. + +### Use Sample Apps + +We’ve built several sample apps showcasing different use cases and how to integrate Paystack with different programming languages. + +You can set up any of the sample apps on your local machine — To do this, run: + +`$ paystack sample sample_react ~/Work/Desktop` + +### Interact with Paystack APIs + +All Paystack public API endpoints are accessible via the Paystack CLI, and you can try out different API calls from the terminal before you start integrating. In this guide, you’ll learn how to + +1. Initialize a transaction and get a checkout URL. +2. Verify a transaction +3. Charge a saved card. + +First, we’ll call the [Initialize Transaction **API](https://paystack.com/docs/api#transaction-initialize)** to generate a checkout link. The command to do this is + +```bash + $ paystack transaction initialize --email customer@email.com --amount 10000 \ + --callback_url https://paystack.com/docs +``` + +Your output should look like this + +```bash +Authorization URL created +{ + authorization_url: 'https://checkout.paystack.com/sf69sk0l6d5iuqm', + access_code: 'sf69sk0l6d5iuqm', + reference: 'kpu5vxesc5' +} +``` + +Great! We’ve created the transaction and can grab the `authorization_url` from the terminal and open it in a browser to complete the transaction. + +Now that’s done, let’s verify the transaction by running + +`$ paystack transaction verify --reference kpu5vxesc5` + +Your output should look like this + +```bash +Verification successful +{ + id: 1693453689, + domain: 'test', + status: 'success', + reference: 'kpu5vxesc5', + amount: 10000, + metadata: '', + log: { + ... + }, + fees: 150, + authorization: { + authorization_code: 'AUTH_5uy1wm1940', + bin: '408408', + last4: '4081', + exp_month: '12', + exp_year: '2030', + channel: 'card', + card_type: 'visa ', + bank: 'TEST BANK', + country_code: 'NG', + brand: 'visa', + reusable: true, + signature: 'SIG_oIPc9Xyv8RuejFCaUi4i', + account_name: null + }, + customer: { + ... + email: 'customer@email.com', + customer_code: 'CUS_gnguwml5r732p7y', + ... + }, + plan: null, + split: {}, + order_id: null, + paidAt: '2022-03-18T14:56:20.000Z', + createdAt: '2022-03-18T14:54:51.000Z', + requested_amount: 10000, + ... +} +``` + +So far, so good! Now one more thing, we want to recurringly charge the card that was used for this transaction. To do that, we’ll need the customer’s email and authorization code from the verify transaction response. Grab those from ***customer.email*** and **authorization.authorization_code** in the JSON response respectively. + +The command to run will be: + +```bash +$ paystack transaction charge_authorization --email customer@email.com \ + +--authorization_code AUTH_5uy1wm1940 --amount 1000 +``` + +Output from this command should look like + +```bash +Charge attempted +{ + amount: 10000, + currency: 'NGN', + transaction_date: '2022-03-21T15:25:01.000Z', + status: 'success', + reference: 'h5ijyl88fau8b1l', + domain: 'test', + metadata: '', + gateway_response: 'Approved', + message: null, + channel: 'card', + ip_address: null, + log: null, + fees: 150, + authorization: { + authorization_code: 'AUTH_5uy1wm1940', + bin: '408408', + last4: '4081', + exp_month: '12', + exp_year: '2030', + channel: 'card', + card_type: 'visa ', + bank: 'TEST BANK', + country_code: 'NG', + brand: 'visa', + reusable: true, + signature: 'SIG_oIPc9Xyv8RuejFCaUi4i', + account_name: null + }, + customer: { + id: 8072602, + first_name: null, + last_name: null, + email: 'customer@email.com', + customer_code: 'CUS_gnguwml5r732p7y', + phone: null, + metadata: null, + risk_action: 'deny', + international_format_phone: null + }, + plan: null, + id: 1700095471 +} +``` + +... and boom! we’re done. + +You can test out all other public endpoints from the CLI. Request body and query parameters should be passed as flags to the command, for example, the Create Customer API requires and `email` param, and optional `phone`, `first_name` and `last_name` params, we can represent this as a command line argument in the following format: + +```bash +$ paystack customer create --email customer@email.com --first_name Jane --last_name Doe +``` + +Use our API reference to check the required parameters for any of the endpoints. + +## Uninstall the CLI + +`$ npm uninstall -g @paystack-oss/dev-cli` diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 0000000..0525cee --- /dev/null +++ b/SETUP.md @@ -0,0 +1,13 @@ +Auto generate API commands from Open API spec + +Clean UP + + check command names if properly formatted, commands that require changes start with '***' + + Check for missing parameters, search `"params": []` + + Remove BVN commands + + oclif pack tarballs --targets=linux-arm + + Notarize mac package \ No newline at end of file diff --git a/bin/dev b/bin/dev new file mode 100755 index 0000000..489509f --- /dev/null +++ b/bin/dev @@ -0,0 +1,17 @@ +#!/usr/bin/env node + +const oclif = require('@oclif/core') + +const path = require('path') +// const project = path.join(__dirname, '..', 'tsconfig.json') + +// In dev mode -> use ts-node and dev plugins +process.env.NODE_ENV = 'development' + +// require('ts-node').register({project}) + +// In dev mode, always show stack traces +oclif.settings.debug = true; + +// Start the CLI +oclif.run().then(oclif.flush).catch(oclif.Errors.handle) diff --git a/bin/dev.cmd b/bin/dev.cmd new file mode 100644 index 0000000..077b57a --- /dev/null +++ b/bin/dev.cmd @@ -0,0 +1,3 @@ +@echo off + +node "%~dp0\dev" %* \ No newline at end of file diff --git a/bin/run b/bin/run new file mode 100755 index 0000000..a7635de --- /dev/null +++ b/bin/run @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +const oclif = require('@oclif/core') + +oclif.run().then(require('@oclif/core/flush')).catch(require('@oclif/core/handle')) diff --git a/bin/run.cmd b/bin/run.cmd new file mode 100644 index 0000000..968fc30 --- /dev/null +++ b/bin/run.cmd @@ -0,0 +1,3 @@ +@echo off + +node "%~dp0\run" %* diff --git a/cli.js b/cli.js deleted file mode 100755 index f4c6032..0000000 --- a/cli.js +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env node -global.vorpal = require('vorpal')(); -vorpal.isCommandArgKeyPairNormalized = false; -const shell = require('shelljs'); -global.db = require('./lib/db') -if (!shell.which('git')) { - shell.echo('Sorry, this script requires git'); - shell.exit(1); -} - -vorpal - .delimiter('paystack $') - .show(); - - - require('./commands/webhook')(); - require('./commands/api')(); - require('./commands/auth')(); - require('./commands/samples')(); - // module.exports = {vorpal, db, shell}; - diff --git a/commands/api.js b/commands/api.js deleted file mode 100644 index fff13c4..0000000 --- a/commands/api.js +++ /dev/null @@ -1,46 +0,0 @@ -const APIs = require('../lib/paystack/apis') -const helpers = require('../lib/helpers') - -let commands = Object.keys(APIs) -const init = () => { - commands.forEach((command) => { - let section = APIs[command]; - let vorp = vorpal.command(command + ' ', helpers.getDescription(section, command)) - .validate(function (args) { - let selected_integration = db.read('selected_integration.id'); - let user = db.read('user.id') - if (!selected_integration || !user) { - helpers.errorLog("You're not signed in, please run the `login` command before you begin"); - return false; - } - }) - .action(async function (args, callback) { - let schema = JSON.parse(JSON.stringify(helpers.findSchema(command, args))) - let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, args)) - if (err) { - - if (err.response) { - helpers.errorLog(err.response.data.message) - return; - } - helpers.errorLog(err) - return; - } - helpers.successLog(result.message) - helpers.jsonLog(result.data) - }) - vorp.option('--domain ', ' '); - let added_options = ['domain']; - section.forEach((f) => { - f.params.forEach((o) => { - if (added_options.indexOf(o.parameter) < 0) { - vorp.option('--' + o.parameter + ' ', ' ') - added_options.push(o.parameter) - } - - }) - }) - }) -} - -module.exports = init \ No newline at end of file diff --git a/commands/auth.js b/commands/auth.js deleted file mode 100644 index 023ce14..0000000 --- a/commands/auth.js +++ /dev/null @@ -1,69 +0,0 @@ -const helpers = require('../lib/helpers') -const Paystack = require('../lib/Paystack') -const init = function () { - vorpal.command('login', 'Sign in with your Paystack username and password').action(async function (args, callback) { - let token = '' - let expiry = parseInt(db.read('token_expiry')) * 1000; - let now = parseFloat(Date.now().toString()) - let user; - if (expiry > now) { - - token = db.read('token'); - user = db.read('user'); - helpers.successLog("You're already logged in") - - } - else { - var email = helpers.prompt('Email address\n') - let password = helpers.prompt('Password\n', true) - var [e, response] = await helpers.promiseWrapper(Paystack.signIn(email, password)) - if (response) { - token = response.token; - user = response.user; - db.write('token', token) - db.write('user', user) - helpers.successLog('Login successful') - }else{ - helpers.errorLog('Login failed') - return; - } - - - - } - - - - if (response || (token && user)) { - - - var [err, integration] = await helpers.promiseWrapper(Paystack.selectIntegration(user.integrations, token)) - if (err) { - helpers.errorLog(err) - } - db.write('selected_integration', integration); - let user_role = db.read('selected_integration.logged_in_user_role'); - - var [err, integrationData] = await helpers.promiseWrapper(Paystack.getIntegration(integration.id, token)); - if (err) { - helpers.errorLog(err) - return - } - integrationData.logged_in_user_role = user_role; - db.write('selected_integration', integrationData); - var [err, keys] = await helpers.promiseWrapper(Paystack.getKeys(token)); - if (err) { - helpers.errorLog(err) - return - } - db.write('selected_integration.keys', keys) - - helpers.infoLog('Logged in as ' + user.email + ' - ' + integration.business_name + ' (' + integration.id + ')'); - } else { - helpers.errorLog(' - - - - - - ') - - } - }) -} - -module.exports = init \ No newline at end of file diff --git a/commands/samples.js b/commands/samples.js deleted file mode 100644 index 4fd6918..0000000 --- a/commands/samples.js +++ /dev/null @@ -1,41 +0,0 @@ - -const helpers = require('../lib/helpers') -const shell = require('shelljs'); - -if (!shell.which('git')) { - shell.echo('Sorry, this script requires git'); - shell.exit(1); -} - -let samples = require('../lib/samples') - -const init = () => { - let keys = Object.keys(samples) - vorpal.command('sample ', 'Get started quickly with a Paystack sample project. Available samples are '+ keys.toString() ) - .validate(function (args) { - let selected_integration = db.read('selected_integration.id'); - let user = db.read('user.id') - if (!selected_integration || !user) { - helpers.errorLog("You're not signed in, please run the `login` command before you begin"); - return false; - } - }).action(async (args, callback) => { - - if(keys.indexOf(args.sample) < 0){ - helpers.errorLog("No sample app available with the name "+ args.sample); - helpers.infoLog("Available samples are " + keys.toString()) - callback() - return; - } - let sample = samples[args.sample]; - - shell.cd(args.filepath) - shell.exec('git clone '+ sample.git) - shell.cd(sample.name) - shell.exec('npm install'); - shell.exec('npm start') - }) -} - - -module.exports = init \ No newline at end of file diff --git a/commands/webhook.js b/commands/webhook.js deleted file mode 100644 index 1f12a91..0000000 --- a/commands/webhook.js +++ /dev/null @@ -1,91 +0,0 @@ -const ngrok = require('ngrok'); -const helpers = require('../lib/helpers') -const Paystack = require('../lib/Paystack') - -const init = () => { - vorpal - .command('webhook [local_route]', 'runs a webhook endpoint health check and listens for incoming webhooks".') - .option('--domain ', ' ') - .option('--event ', ' ') - .validate(function (args) { - let selected_integration = db.read('selected_integration.id'); - let user = db.read('user.id') - if (!selected_integration || !user) { - helpers.errorLog("You're not signed in, please run the `login` command before you begin"); - return false; - } - }) - .action(async function (args, callback) { - if (args.command == 'listen') { - let token = '' - let expiry = parseInt(db.read('token_expiry'))*1000; - let now =parseFloat( Date.now().toString() ) - - if (expiry > now) { - - token = db.read('token') - - } else { - let password = helpers.prompt("What's your paystack password:\n>", true) - var [err, result] = await helpers.promiseWrapper(Paystack.signIn(db.read('user.email'), password)); - if (!result) { - return - } - token = result.token - } - - if (!args.local_route) { - helpers.errorLog('To listen to webhook events locally, you have to specify a local url to forward events to e.g localhost:3000/webhook') - } - let urlObject = helpers.parseURL(args.local_route) - - if (!urlObject.port) { - urlObject.port = 8080 - } - if (!urlObject.search || urlObject.search == '?') { - urlObject.search = '' - } - try{ - await ngrok.kill(); - } - catch(e){ - //log error - } - - let ngrokHost = await ngrok.connect(urlObject.port); - - - - let ngrokURL = ngrokHost + urlObject.pathname + urlObject.search; - let domain = 'test'; - if (args.options.domain == 'live') { - domain = 'live' - } - helpers.infoLog('Tunelling webhook events to ' + args.local_route) - var [err, result] = await helpers.promiseWrapper(Paystack.setWebhook(ngrokURL, token, db.read('selected_integration.id'))) - if (err) { - this.log(err); - return - } else { - this.log('Webhook events would now be received at ' + args.local_route) - } - - } - else if(args.command == 'ping'){ - var [e, response] = await helpers.promiseWrapper( Paystack.pingWebhook(args)); - helpers.infoLog('- - - - - WEBHOOK RESPONSE - - - - - -') - helpers.infoLog(response.code + ' - - ' + response.text) - if( helpers.isJson(response.data)){ - helpers.jsonLog(response.data) - }else{ - helpers.infoLog(response.data) - } - } - - callback(); - }); - - -} - -module.exports = init \ No newline at end of file diff --git a/lib/Paystack.js b/lib/Paystack.js deleted file mode 100644 index 3a1492f..0000000 --- a/lib/Paystack.js +++ /dev/null @@ -1,199 +0,0 @@ - -const axios = require('axios'); -const helpers = require('./helpers') -const crypto = require('crypto') -const webhookSamples = require('./paystack/webhooks') -function selectIntegration(integrations, token) { - return new Promise((resolve, reject) => { - console.log('Choose an integration - '); - let promptMessage = "" - - integrations.forEach((b, i) => { - promptMessage += i + 1 + ' - ' + b.business_name + ' (' + b.id + ')\n' - }) - let integration = helpers.prompt(promptMessage + '\nEnter the corresponding number - '); - - axios.post('https://api.paystack.co/user/switch_integration', { integration: integrations[parseInt(integration) - 1].id }, { headers: { 'Authorization': 'Bearer ' + token, 'jwt-auth': true } }).then((response) => { - - resolve(integrations[parseInt(integration) - 1]) - }).catch((err) => { - console.error(err.response.data) - reject(err) - }) - - }) - -} - -async function refreshIntegration(){ - - let user_role = db.read('selected_integration.logged_in_user_role'); - let integration = db.read('selected_integration') - let token = '' - let expiry = parseInt(db.read('token_expiry'))*1000; - let now =parseFloat( Date.now().toString() ) - - if (expiry > now) { - - token = db.read('token') - return true; - } else { - let password = helpers.prompt("What's your password: ("+ db.read('user.email') +') '+"\n>", true) - var [err, result] = await helpers.promiseWrapper(signIn(db.read('user.email'), password)); - if (!result) { - return false - } - token = result.token - } - var [err, integrationData] = await helpers.promiseWrapper(getIntegration(integration.id, token)); - if (err) { - helpers.errorLog(err) - return false - } - integrationData.logged_in_user_role = user_role; - db.write('selected_integration', integrationData); - var [err, keys] = await helpers.promiseWrapper(getKeys(token)); - if (err) { - helpers.errorLog(err) - return false - } - db.write('selected_integration.keys', keys) - -} - -function setWebhook(url, token, integration, domain = 'test') { - return new Promise((resolve, reject) => { - let data = {}; - data[domain + '_webhook_endpoint'] = url; - data['integration'] = integration - let headers = { - 'Authorization': 'Bearer ' + token, - 'jwt-auth': true - } - axios.put('https://api.paystack.co/integration/webhooks', data, { headers }).then((resp) => { - resolve(resp.data.message) - }).catch((err) => { - console.log(err.response.data) - reject(err) - }) - }) -} - -function getKeys(token) { - return new Promise((resolve, reject) => { - axios.get("https://api.paystack.co/integration/keys", { headers: { 'Authorization': 'Bearer ' + token, 'jwt-auth': true } }).then((response) => { - - resolve(response.data.data) - }).catch((err) => { - reject(err.response.data.message); - }); - }) -} - -function pingWebhook(args) { - return new Promise(async (resolve, reject) => { - let canProceed; - try{ - canProceed = await refreshIntegration(); - }catch(e){ - console.error(e) - } - if(!canProceed){ - helpers.errorLog('- - - - - - - - Unable to ping webhook URL - - - - - - - -') - return - } - let domain = 'test'; - if (args.options.domain) { - domain = args.options.domain - } - let event = 'charge.success'; - if (args.options.event) { - event = args.options.event; - } - let eventObject = webhookSamples[event]; - if (eventObject) { - let key = db.query('selected_integration.keys', { domain, 'type': 'secret' }).key; - var hash = crypto.createHmac('sha512', key).update(JSON.stringify(eventObject)).digest('hex'); - let uri = db.read('selected_integration.' + domain + '_webhook_endpoint'); - helpers.infoLog('- - - - - - - - - - - - - - - - - - - - - - - - - - - - '); - helpers.infoLog(`Sending sample ${event} event payload to ${uri}`); - axios.post(uri, eventObject, - { - headers: { - 'x-paystack-signature': hash - } - }, - - ).then((response) => { - resolve({ - code: response.status, - text: response.statusText, - data: response.data - }) - }).catch((e) => { - resolve({ - code: e.response.status, - text: e.response.statusText, - data: e.response.data - }) - }) - } else { - helpers.errorLog('Invalid event type - ' + event) - reject() - } - }) - -} - -function getIntegration(id, token) { - console.log('getting integration'); - return new Promise((resolve, reject) => { - axios.get('https://api.paystack.co/integration/' + id, - { - headers: { - 'Authorization': 'Bearer ' + token, - 'jwt-auth': true - } - }).then((response) => { - resolve(response.data.data) - }).catch((e) => { - console.error(e) - reject(e.response.data.message) - }) - }) -} - - -function signIn(email, password) { - return new Promise((resolve, reject) => { - let expiry = parseInt(db.read('token_expiry')); - let now = parseFloat(Date.now().toString()) - if (expiry > now) { - resolve({ - token: db.read('token'), - user: db.read('user'), - }) - return; - } - helpers.infoLog('Logging in'); - axios({ - url: 'https://api.paystack.co/login', - method: 'POST', - data: { email, password } - }).then((response) => { - - db.write('token', response.data.data.token) - db.write('token_expiry', response.data.data.expiry) - db.write('user', response.data.data.user) - resolve(response.data.data) - }).catch((e) => { - helpers.errorLog(e.response.data.message || 'Unable to sign in, please try again in a few minutes'); - reject('LOGIN ERROR: ' + e.response.data.message) - }) - - }) -} - -module.exports = { - signIn, getKeys, setWebhook, selectIntegration, getIntegration, pingWebhook -} \ No newline at end of file diff --git a/lib/Paystack/apis.js b/lib/Paystack/apis.js deleted file mode 100644 index eb83b45..0000000 --- a/lib/Paystack/apis.js +++ /dev/null @@ -1,2066 +0,0 @@ -#!/usr/bin/env node -module.exports = { - "subaccount": [ - { - "api": "update", - "endpoint": "https://api.paystack.co/subaccount", - "method": "PUT", - "params": [], - "description": null - }, - { - "api": "fetch", - "endpoint": "https://api.paystack.co/subaccount/{ID}", - "method": "GET", - "params": [], - "description": null - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/subaccount", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve" - }, - { - "api": "create", - "endpoint": "https://api.paystack.co/subaccount", - "method": "POST", - "params": [ - { - "parameter": "business_name", - "required": true, - "type": "String" - }, - { - "parameter": "settlement_bank", - "required": true, - "type": "String" - }, - { - "parameter": "account_number", - "required": true, - "type": "String" - }, - { - "parameter": "percentage_charge", - "required": true, - "type": "String" - }, - { - "parameter": "primary_contact_email", - "required": false, - "type": "String" - }, - { - "parameter": "primary_contact_name", - "required": false, - "type": "String" - }, - { - "parameter": "primary_contact_phone", - "required": false, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - }, - { - "parameter": "settlement_schedule", - "required": false, - "type": "String" - }, - { - "parameter": "eceive payments for the created subaccount by providing their code when doing a transaction. More details here: [Split Payments Overview](https://developers.paystack.co/v1.0/docs/splitpaymentsoverview", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **business_name** (_required_) - Name of business for subaccount\n- **settlement_bank** (_required_) - Name of Bank (see list of accepted names by calling [List Banks](https://developers.paystack.co/v1.0/docs/list-banks)\n- **account_number** (_required_) - NUBAN Bank Account Number\n- **percentage_charge** (_required_) - What is the default percentage charged when receiving on behalf of this subaccount?\n- **primary_contact_email** - A contact email for the subaccount\n- **primary_contact_name** - A name for the contact person for this subaccount\n- **primary_contact_phone** - A phone number to call for this subaccount\n- **metadata** - Stringified JSON object\n- **settlement_schedule** - Any of `auto`, `weekly`, `monthly`, `manual`. Auto means payout is T+1 and manual means payout to the subaccount should only be made when requested.\n\nReceive payments for the created subaccount by providing their code when doing a transaction. More details here: [Split Payments Overview](https://developers.paystack.co/v1.0/docs/split-payments-overview)" - } - ], - "page": [ - { - "api": "update", - "endpoint": "https://api.paystack.co/page/", - "method": "PUT", - "params": [ - { - "parameter": "name", - "required": false, - "type": "String" - }, - { - "parameter": "description", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - }, - { - "parameter": "active", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **name** - Name of page\n- **description** - Short description of page\n- **amount** - Amount to be charged in kobo. Will override the amount for existing subscriptions.\n- **active** - Set to false to deactivate page url." - }, - { - "api": "fetch", - "endpoint": "https://api.paystack.co/page/id_or_plan_code", - "method": "GET", - "params": [], - "description": null - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/page", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - }, - { - "parameter": "interval", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **interval** - Filter list by plans with specified interval\n- **amount** - Filter list by plans with specified amount (in kobo)" - }, - { - "api": "check", - "endpoint": "https://api.paystack.co/page/check_slug_availability/slug", - "method": "GET", - "params": [ - { - "parameter": "slug", - "required": true, - "type": "String" - } - ], - "description": "**Path Params**\n- **slug** (_required_) - URL slug to be confirmed" - }, - { - "api": "create", - "endpoint": "https://api.paystack.co/page", - "method": "POST", - "params": [ - { - "parameter": "name", - "required": true, - "type": "String" - }, - { - "parameter": "description", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - }, - { - "parameter": "slug", - "required": false, - "type": "String" - }, - { - "parameter": "redirect_url", - "required": false, - "type": "String" - }, - { - "parameter": "send_invoices", - "required": false, - "type": "String" - }, - { - "parameter": "custom_fields", - "required": false, - "type": "String" - }, - - { - "parameter": "end pages created to your customers by giving out a link in this format https://paystack.com/pay/:slug. For instance, a valid link for the page above would be https://paystack.com/pay/5nApBwZkv", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **name** (_required_) - Name of page\n- **description** - Short description of page\n- **amount** - Default amount you want to accept using this page. If none is set, customer is free to provide any amount of their choice. The latter scenario is useful for accepting donations\n- **slug** - URL slug you would like to be associated with this page. Page will be accessible at https://paystack.com/pay/[slug]\n- **redirect_url** - If you would like Paystack to redirect someplace upon successful payment, specify the URL here.\n- **send_invoices** - Set to false if you don't want invoices to be sent to your customers\n- **custom_fields** - If you would like to accept custom fields, specify them here. See sample code for details.\n\nSend pages created to your customers by giving out a link in this format https://paystack.com/pay/:slug. For instance, a valid link for the page above would be https://paystack.com/pay/5nApBwZkvY" - } - ], - "transfer": [ - { - "api": "list", - "endpoint": "https://api.paystack.co/transfer", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve" - }, - { - "api": "finalize", - "endpoint": "https://api.paystack.co/transfer/finalize_transfer", - "method": "POST", - "params": [ - { - "parameter": "transfer_code", - "required": true, - "type": "String" - }, - { - "parameter": "otp", - "required": true, - "type": "String" - } - ], - "description": "**Body Params**\n- **transfer_code** (_required_) - Transfer code\n- **otp** (_required_) - OTP sent to business phone to verify transfer." - }, - { - "api": "initiate", - "endpoint": "https://api.paystack.co/transfer", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "source", - "required": true, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "reason", - "required": false, - "type": "String" - }, - { - "parameter": "recipient", - "required": true, - "type": "String" - }, - { - "parameter": "reference", - "required": false, - "type": "String" - } - ], - "description": "Status of transfer object returned will be ‘pending’ if OTP is disabled. In the event that an OTP is required, status will read ‘otp’.\n\n**Body Params**\n- **source** (_required_) - Where should we transfer from? Only balance for now\n- **amount** - Amount to transfer in kobo\n- **currency** - NGN\n- **reason**\n- **recipient** (_required_) - Code for transfer recipient\n- **reference** - If specified, the field should be a unique identifier (in lowercase) for the object. Only `-` `,` `_` and alphanumeric characters allowed." - }, - { - "api": "verify", - "endpoint": "https://api.paystack.co/transfer/{reference}", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "reference", - "required": true, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve" - }, - { - "api": "disable", - "endpoint": "https://api.paystack.co/transfer/disable_otp", - "method": "POST", - "params": [ - - { - "parameter": "n the event that you want to be able to complete transfers programmatically without use of OTPs, this endpoint helps disable that….with an OTP. No arguments required. An OTP is sent to you on your business phone", - "required": true, - "type": "String" - } - ], - "description": "In the event that you want to be able to complete transfers programmatically without use of OTPs, this endpoint helps disable that….with an OTP. No arguments required. You will get an OTP.\n\nIn the event that you want to be able to complete transfers programmatically without use of OTPs, this endpoint helps disable that….with an OTP. No arguments required. An OTP is sent to you on your business phone." - }, - { - "api": "enable", - "endpoint": "https://api.paystack.co/transfer/enable_otp", - "method": "POST", - "params": [], - "description": "In the event that a customer wants to stop being able to complete transfers programmatically, this endpoint helps turn OTP requirement back on. No arguments required." - }, - { - "api": "initiate", - "endpoint": "https://api.paystack.co/transfer/bulk", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "(no name)", - "required": false, - "type": "String" - }, - - { - "parameter": "tatus of transfer object returned will be ‘pending’ if OTP is disabled. In the event that an OTP is required, status will read ‘otp’", - "required": true, - "type": "String" - } - ], - "description": "You need to disable the Transfers OTP requirement to use this endpoint.\n\n**Body Params**\n- **(no name)**\n\nStatus of transfer object returned will be ‘pending’ if OTP is disabled. In the event that an OTP is required, status will read ‘otp’." - }, - { - "api": "finalize", - "endpoint": "https://api.paystack.co/transfer/disable_otp_finalize", - "method": "POST", - "params": [ - { - "parameter": "otp", - "required": true, - "type": "String" - }, - - ], - "description": "**Body Params**\n- **otp** (_required_) - OTP sent to business phone to verify disabling OTP requirement\n\n" - }, - { - "api": "fetch", - "endpoint": "https://api.paystack.co/transfer/id", - "method": "GET", - "params": [ - { - "parameter": "id_or_code", - "required": true, - "type": "String" - } - ], - "description": "**Path Params**\n- **id_or_code** (_required_) - An ID or code for the transfer whose details you want to retrieve." - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/transfer/id_or_code", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - } - ], - "description": "This lists all bulk charge batches created by the integration. Statuses can be `active`, `paused`, or `complete`.\n\n**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve" - }, - { - "api": "resend", - "endpoint": "https://api.paystack.co/transfer/resend_otp", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "transfer_code", - "required": true, - "type": "String" - }, - { - "parameter": "reason", - "required": true, - "type": "String" - } - ], - "description": "Creates a new recipient. An duplicate account number will lead to the retrieval of the existing record.\n\n**Body Params**\n- **transfer_code** (_required_) - Transfer code\n- **reason** (_required_) - either `resend_otp` or `transfer`" - } - ], - "paymentrequest": [ - { - "api": "create", - "endpoint": "https://api.paystack.co/paymentrequest", - "method": "POST", - "params": [ - { - "parameter": "customer", - "required": true, - "type": "String" - }, - { - "parameter": "due_date", - "required": true, - "type": "String" - }, - { - "parameter": "amount", - "required": true, - "type": "Number" - }, - { - "parameter": "description", - "required": false, - "type": "String" - }, - { - "parameter": "line_items", - "required": false, - "type": "String" - }, - { - "parameter": "tax", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "send_notification", - "required": false, - "type": "String" - }, - { - "parameter": "draft", - "required": false, - "type": "String" - }, - { - "parameter": "send_notification", - "required": false, - "type": "String" - }, - { - "parameter": "has_invoice", - "required": false, - "type": "String" - }, - { - "parameter": "invoice_number", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **customer** (_required_) - Customer ID or code\n- **due_date** (_required_) - ISO 8601 representation of request due date\n- **amount** (_required_) - Invoice amount. Only useful if line items and tax values are ignored. endpoint will throw a friendly warning if neither is available.\n- **description**\n- **line_items** - Array of line items in the format `[{\"name\":\"item 1\", \"amount\":2000}]`\n- **tax** - Array of taxes to be charged in the format `[{\"name\":\"VAT\", \"amount\":2000}]`\n- **currency** - Defaults to Naira\n- **send_notification** - Indicates whether Paystack sends an email notification to customer. Defaults to `true`.\n- **draft** - Indicate if request should be saved as draft. Defaults to `false` and overrides send_notification.\n- **send_notification** - Indicates whether Paystack sends an email notification to customer. Defaults to `true`.\n- **has_invoice** - Set to `true` to create a draft invoice (adds an auto incrementing invoice number if none is provided) even if there are no `line_items` or `tax` passed.\n- **invoice_number** - Numeric value of invoice. Invoice will start from 1 and auto increment from there. This field is to help override whatever value Paystack decides. Auto increment for subsequent invoices continue from this point." - }, - { - "api": "finalize", - "endpoint": "https://api.paystack.co/paymentrequest/finalize/ID_OR_CODE", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "send_notification", - "required": false, - "type": "String" - } - ], - "description": "Publishes invoice that is draft by sending customer the invoice via email\n\n**Body Params**\n- **send_notification** - Indicates whether Paystack sends an email notification to customer. Defaults to `true`" - }, - { - "api": "send", - "endpoint": "https://api.paystack.co/paymentrequest/notify/ID_OR_CODE", - "method": "POST", - "params": [ - { - "parameter": "id", - "required": false, - "type": "String" - } - ], - "description": "**Path Params**\n- **id** - Invoice code for which you want to send a notification for" - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/paymentrequest", - "method": "GET", - "params": [ - { - "parameter": "customer", - "required": false, - "type": "String" - }, - { - "parameter": "status", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "paid", - "required": false, - "type": "String" - }, - { - "parameter": "include_archive", - "required": false, - "type": "String" - }, - { - "parameter": "payment_request", - "required": false, - "type": "String" - } - ], - "description": "**Query Params**\n- **customer** - Specify an ID for the customer whose requests you want to retrieve\n- **status** - Filter requests by status ('failed', 'success', 'abandoned')\n- **currency** - Filter requests sent in a particular currency.\n- **paid** - Filter requests that have been paid for \n- **include_archive** - Includes archived requests in the response\n- **payment_request** - Filter specific invoice by passing invoice code" - }, - { - "api": "view", - "endpoint": "https://api.paystack.co/paymentrequest/REQUEST_ID_OR_CODE", - "method": "GET", - "params": [ - { - "parameter": "id", - "required": true, - "type": "String" - } - ], - "description": "**Path Params**\n- **id** _(required)_ - An ID for the Invoice" - }, - { - "api": "invoice", - "endpoint": "https://api.paystack.co/paymentrequest/totals", - "method": "GET", - "params": [], - "description": null - }, - { - "api": "update", - "endpoint": "https://api.paystack.co/paymentrequest/ID_OR_CODE", - "method": "PUT", - "params": [ - { - "parameter": "description", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - }, - { - "parameter": "line_item", - "required": false, - "type": "String" - }, - { - "parameter": "tax", - "required": false, - "type": "String" - }, - { - "parameter": "due_date", - "required": false, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - }, - { - "parameter": "send_notification", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "customer", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **description**\n- **amount**\n- **line_item**\n- **tax**\n- **due_date**\n- **metadata**\n- **send_notification**\n- **currency** - only works in draft mode\n- **customer** - only works in draft mode" - }, - { - "api": "verify", - "endpoint": "https://api.paystack.co/paymentrequest/verify/{ID}", - "method": "GET", - "params": [ - { - "parameter": "ID", - "required": false, - "type": "String" - }, - - { - "parameter": "ote that a key is added called `pending_amount` when you fetch an invoice. This is because when paying for an invoice, you can choose to pay part but not all. Whenever a successful transaction is made, the key updates to reveal what’s left of the invoice to pay", - "required": false, - "type": "String" - } - ], - "description": "**Path Params**\n- **ID** - The invoice code for the Payment Request to be verified\n\nNote that a key is added called `pending_amount` when you fetch an invoice. This is because when paying for an invoice, you can choose to pay part but not all. Whenever a successful transaction is made, the key updates to reveal what’s left of the invoice to pay." - } - ], - "transferrecipient": [ - { - "api": "create", - "endpoint": "https://api.paystack.co/transferrecipient", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "type", - "required": true, - "type": "String" - }, - { - "parameter": "name", - "required": true, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - }, - { - "parameter": "bank_code", - "required": true, - "type": "String" - }, - { - "parameter": "account_number", - "required": true, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "description", - "required": false, - "type": "String" - } - ], - "description": "Creates a new recipient. An duplicate account number will lead to the retrieval of the existing record.\n\n**Body Params**\n- **type** (_required_) - Recipient Type (Only nuban at this time)\n- **name** (_required_) - A name for the recipient\n- **metadata** - Store additional information about your recipient in a structured format. JSON\n- **bank_code** (_required_) - Required if type is nuban. You can find a list of bank codes at [api.paystack.co/bank](https://api.paystack.co/bank)\n- **account_number** (_required_) - Required if type is `nuban`\n- **currency** - Currency for the account receiving the transfer.\n- **description**" - }, - { - "api": "delete", - "endpoint": "https://api.paystack.co/transferrecipient", - "method": "DELETE", - "params": [], - "description": null - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/transferrecipient", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve" - }, - { - "api": "update", - "endpoint": "{recipient_code_or_id}", - "method": "PUT", - "params": [], - "description": null - } - ], - "subscription": [ - { - "api": "disable", - "endpoint": "https://api.paystack.co/subscription/disable", - "method": "POST", - "params": [ - { - "parameter": "code", - "required": true, - "type": "String" - }, - { - "parameter": "token", - "required": true, - "type": "String" - } - ], - "description": "**Body Params**\n- **code** (_required_) - Subscription code\n- **token** (_required_) - Email token" - }, - { - "api": "fetch", - "endpoint": ":id_or_subscription_code", - "method": "GET", - "params": [], - "description": null - }, - { - "api": "create", - "endpoint": "https://api.paystack.co/subscription", - "method": "POST", - "params": [ - { - "parameter": "customer", - "required": true, - "type": "String" - }, - { - "parameter": "plan", - "required": true, - "type": "String" - }, - { - "parameter": "authorization", - "required": false, - "type": "String" - }, - { - "parameter": "start_date", - "required": false, - "type": "String" - }, - - { - "parameter": "ote the `email_token` attribute for the subscription object. We create one on each subscription so customers can cancel their subscriptions from within the invoices sent to their mailboxes. Since they are not authorized, the email tokens are what we use to authenticate the requests over the API", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **customer** (_required_) - Customer's email address or customer code\n- **plan** (_required_) - Plan code\n- **authorization** - If customer has multiple authorizations, you can set the desired authorization you wish to use for this subscription here. If this is not supplied, the customer's most recent authorization would be used\n- **start_date** - Set the date for the first debit. (ISO 8601 format)\n\nNote the `email_token` attribute for the subscription object. We create one on each subscription so customers can cancel their subscriptions from within the invoices sent to their mailboxes. Since they are not authorized, the email tokens are what we use to authenticate the requests over the API." - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/subscription", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - }, - { - "parameter": "customer", - "required": false, - "type": "String" - }, - { - "parameter": "plan", - "required": false, - "type": "String" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **customer** - Filter by Customer ID\n- **plan** - Filter by Plan ID" - }, - { - "api": "enable", - "endpoint": "https://api.paystack.co/subscription/enable", - "method": "POST", - "params": [ - { - "parameter": "code", - "required": true, - "type": "String" - }, - { - "parameter": "token", - "required": true, - "type": "String" - } - ], - "description": "**Body Params**\n- **code** (_required_) - Subscription code\n- **token** (_required_) - Email token" - } - ], - "bulkcharge": [ - { - "api": "fetch", - "endpoint": "https://api.paystack.co/bulkcharge/id_or_code", - "method": "GET", - "params": [ - - { - "parameter": "Path Params", - "required": false, - "type": "String" - }, - { - "parameter": "id_or_code", - "required": true, - "type": "String" - } - ], - "description": "This endpoint retrieves a specific batch code. It also returns useful information on its progress by way of the `total_charges` and `pending_charges` attributes.\n\n**Path Params**\n- **id_or_code** (_required_) - An ID or code for the transfer whose details you want to retrieve." - }, - { - "api": "fetch", - "endpoint": "https://api.paystack.co/bulkcharge/id_or_code/charges", - "method": "GET", - "params": [ - - { - "parameter": "Path Params", - "required": false, - "type": "String" - }, - { - "parameter": "id_or_code", - "required": true, - "type": "String" - }, - - { - "parameter": "status", - "required": false, - "type": "String" - }, - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - } - ], - "description": "This endpoint retrieves the charges associated with a specified batch code. Pagination parameters are available. You can also filter by status. Charge statuses can be `pending`, `success` or `failed`.\n\n**Path Params**\n- **id_or_code** (_required_) - An ID or code for the batch whose charges you want to retrieve.\n\n**Query Params**\n- **status** - `pending`, `success` or `failed`\n- **perPage**\n- **page**\n" - }, - { - "api": "initiate", - "endpoint": "https://api.paystack.co/bulkcharge", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "(no_name)", - "required": false, - "type": "String" - } - ], - "description": "Send an array of objects with authorization codes and amount in kobo so we can process transactions as a batch.\n\n**Body Params**\n- **(no_name)**" - }, - { - "api": "resume", - "endpoint": "https://api.paystack.co/bulkcharge/resume/batch_code", - "method": "GET", - "params": [ - - { - "parameter": "Path Params", - "required": false, - "type": "String" - }, - { - "parameter": "batch_code", - "required": true, - "type": "String" - } - ], - "description": "Use this endpoint to pause processing a batch\n\n**Path Params**\n- **batch_code** (_required_)" - }, - { - "api": "pause", - "endpoint": "https://api.paystack.co/bulkcharge/pause/batch_code", - "method": "GET", - "params": [ - - { - "parameter": "Path Params", - "required": false, - "type": "String" - }, - { - "parameter": "batch_code", - "required": true, - "type": "String" - } - ], - "description": "Use this endpoint to pause processing a batch\n\n**Path Params**\n- **batch_code** (_required_)" - } - ], - "bank": [ - { - "api": "list", - "endpoint": "https://api.paystack.co/bank", - "method": "GET", - "params": [], - "description": null - }, - { - "api": "resolve", - "endpoint": "?account_number=ACCOUNT_NUMBER&bank_code=BANK_CODE", - "method": "GET", - "params": [ - { - "parameter": "account_number", - "required": false, - "type": "String" - }, - { - "parameter": "bank_code", - "required": false, - "type": "String" - } - ], - "description": "**Path Params**\n- **account_number** - Account Number\n- **bank_code** - Bank Code" - }, - { - "api": "resolve", - "endpoint": "{BVN}", - "method": "GET", - "params": [ - { - "parameter": "bvn", - "required": true, - "type": "String" - } - ], - "description": "**Path Params**\n- **bvn** (_required_) - 11 digit BVN" - }, - { - "api": "match", - "endpoint": "{ACCOUNT_NUMBER}&bank_code={BANK_CODE}&bvn={BVN}", - "method": "GET", - "params": [ - - { - "parameter": "Path Params", - "required": false, - "type": "String" - }, - { - "parameter": "*account_number* _(required)_ Bank account numbe", - "required": true, - "type": "String" - }, - { - "parameter": "*bank_code* _(required)_ Bank code from [List Bank endpoint](https://api.paystack.co/bank", - "required": true, - "type": "String" - }, - { - "parameter": "*bvn* _(required)_ 11 digit BV", - "required": true, - "type": "String" - } - ], - "description": "The Match BVN endpoint checks if the account number for a bank belongs to a user's BVN\n\n**Path Params**\n- *account_number* _(required)_ - Bank account number\n- *bank_code* _(required)_ - Bank code from [List Bank endpoint](https://api.paystack.co/bank)\n- *bvn* _(required)_ - 11 digit BVN" - } - ], - "charge": [ - { - "api": "submit", - "endpoint": "https://api.paystack.co/charge/submit_otp", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "otp", - "required": true, - "type": "String" - }, - { - "parameter": "reference", - "required": true, - "type": "String" - } - ], - "description": "Submit OTP to complete a charge\n\n**Body Params**\n- **otp** (_required_) - OTP submitted by user\n- **reference** (_required_) - reference for ongoing transaction" - }, - { - "api": "submit", - "endpoint": "https://api.paystack.co/charge/submit_pin", - "method": "POST", - "params": [ - { - "parameter": "pin", - "required": true, - "type": "String" - }, - { - "parameter": "reference", - "required": true, - "type": "String" - } - ], - "description": "**Body Params**\n- **pin** (_required_) - PIN submitted by user\n- **reference** (_required_) - reference for transaction that requested pin" - }, - { - "api": "submit", - "endpoint": "https://api.paystack.co/charge/submit_birthday", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "birthday", - "required": true, - "type": "String" - }, - { - "parameter": "reference", - "required": true, - "type": "String" - } - ], - "description": "Submit Birthday when requested\n\n**Body Params**\n- **birthday** (_required_) - Birthday number submitted by user\n- **reference** (_required_) - reference for ongoing transaction" - }, - { - "api": "tokenize", - "endpoint": "https://api.paystack.co/charge/tokenize", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "email", - "required": true, - "type": "String" - }, - { - "parameter": "card", - "required": true, - "type": "String" - }, - { - "parameter": "card.number", - "required": true, - "type": "String" - }, - { - "parameter": "card.cvv", - "required": true, - "type": "String" - }, - { - "parameter": "card.expiry_month", - "required": true, - "type": "String" - }, - { - "parameter": "card.expiry_year", - "required": true, - "type": "String" - } - ], - "description": "Send an array of objects with authorization codes and amount in kobo so we can process transactions as a batch.\n\n**Body Params**\n- **email** (_required_) - Customer's email address\n- **card** (_required_) - Card to tokenize\n- **card.number** (_required_) - Card to tokenize\n- **card.cvv** (_required_) - Card security code\n- **card.expiry_month** (_required_) - Expiry month of card\n- **card.expiry_year** (_required_) - Expiry year of card\n" - }, - { - "api": "check", - "endpoint": "https://api.paystack.co/charge/reference", - "method": "GET", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "reference", - "required": true, - "type": "String" - } - ], - "description": "When you get \"pending\" as a charge status, wait 30 seconds or more, then make a check to see if its status has changed. Don't call too early as you may get a lot more pending than you should.\n\n**Body Params**\n- **reference** (_required_) - The reference to check" - }, - { - "api": "charge", - "endpoint": "https://api.paystack.co/charge", - "method": "POST", - "params": [ - { - "parameter": "imple guide to charging cards directly https://developers.paystack.co/docs/chargingfromyourbacken", - "required": false, - "type": "String" - }, - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "email", - "required": true, - "type": "String" - }, - { - "parameter": "amount", - "required": true, - "type": "Number" - }, - { - "parameter": "card", - "required": true, - "type": "String" - }, - { - "parameter": "card.number", - "required": true, - "type": "String" - }, - { - "parameter": "card.cvv", - "required": true, - "type": "String" - }, - { - "parameter": "card.expiry_month", - "required": true, - "type": "String" - }, - { - "parameter": "card.expiry_year", - "required": true, - "type": "String" - }, - { - "parameter": "bank", - "required": false, - "type": "String" - }, - { - "parameter": "bank.code", - "required": true, - "type": "String" - }, - { - "parameter": "bank.account_number", - "required": true, - "type": "String" - }, - { - "parameter": "authorization_code", - "required": false, - "type": "String" - }, - { - "parameter": "pin", - "required": false, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - } - ], - "description": "Send card details or bank details or authorization code to start a charge.\nSimple guide to charging cards directly https://developers.paystack.co/docs/charging-from-your-backend\n\n**Body Params**\n- **email** (_required_) - Customer's email address\n- **amount** (_required_) - Amount in kobo\n- **card** (_required_) - Card number\n- **card.number** (_required_) - Card to tokenize\n- **card.cvv** (_required_) - Card security code\n- **card.expiry_month** (_required_) - Expiry month of card\n- **card.expiry_year** (_required_) - Expiry year of card\n- **bank** - Bank account to charge (don't send if charging an authorization code or card)\n- **bank.code** (_required_) - A code for the [bank](https://developers.paystack.co/v1.0/ref/banks) (check banks for the banks supported). Only the ones for which paywithbank is true will work.\n- **bank.account_number** (_required_) - 10 digit nuban for the account to charge\n- **authorization_code** - An authorization code to charge (don't send if charging a card or bank account)\n- **pin** - 4-digit PIN (send with a non-reusable authorization code)\n- **metadata** - A JSON object" - }, - { - "api": "submit", - "endpoint": "https://api.paystack.co/charge/submit_phone", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "phone", - "required": true, - "type": "String" - }, - { - "parameter": "reference", - "required": true, - "type": "String" - } - ], - "description": "Submit Phone when requested\n\n**Body Params**\n- **phone** (_required_) - Phone number submitted by user\n- **reference** (_required_) - reference for ongoing transaction" - } - ], - "transaction": [ - { - "api": "verify", - "endpoint": "https://api.paystack.co/transaction/verify/{reference}", - "method": "GET", - "params": [ - { - "parameter": "reference", - "required": true, - "type": "String" - } - ], - "description": "**Path Params**\n- **reference** (_required_)" - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/transaction", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - }, - { - "parameter": "customer", - "required": false, - "type": "String" - }, - { - "parameter": "status", - "required": false, - "type": "String" - }, - { - "parameter": "from", - "required": false, - "type": "String" - }, - { - "parameter": "to", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **customer** - Specify an ID for the customer whose transactions you want to retrieve\n- **status** - Filter transactions by status ('failed', 'success', 'abandoned')\n- **from** - A timestamp from which to start listing transaction e.g. 2016-09-24T00:00:05.000Z, 2016-09-21\n- **to** - A timestamp at which to stop listing transaction e.g. 2016-09-24T00:00:05.000Z, 2016-09-21\n- **amount** - Filter transactions by amount. Specify the amount in kobo." - }, - { - "api": "view", - "endpoint": ":id_or_reference", - "method": "GET", - "params": [], - "description": null - }, - { - "api": "charge", - "endpoint": "https://api.paystack.co/transaction/charge_authorization", - "method": "POST", - "params": [ - { - "parameter": "reference", - "required": false, - "type": "String" - }, - { - "parameter": "authorization_code", - "required": true, - "type": "String" - }, - { - "parameter": "amount", - "required": true, - "type": "Number" - }, - { - "parameter": "plan", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "email", - "required": true, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - }, - { - "parameter": "subaccount", - "required": false, - "type": "String" - }, - { - "parameter": "transaction_charge", - "required": false, - "type": "String" - }, - { - "parameter": "bearer", - "required": false, - "type": "String" - }, - { - "parameter": "invoice_limit", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **reference** - Unique transaction reference. Only `-` `,` `.` `,` `=` and alphanumeric characters allowed. System will generate one if none is provided\n- **authorization_code** - (_required_) Valid authorization code to charge\n- **amount** - (_required_) Amount in kobo\n- **plan** - If transaction is to create a subscription to a predefined plan, provide plan code here\n- **currency** - Currency in which amount should be charged\n- ** email** (_required_) - Customer's email address\n- **metadata** - Add a `custom_fields` attribute which has an array of objects if you would like the fields to be added to your transaction when displayed on the dashboard.\n- **subaccount** - The code for the subaccount that owns the payment.\n- **transaction_charge** - A flat fee to charge the subaccount for this transaction, in kobo. This overrides the split percentage set when the subaccount was created. Ideally, you will need to use this if you are splitting in flat rates (since subaccount creation only allows for percentage split).\n- **bearer** - Who bears Paystack charges? `account` or `subaccount`?\n- **invoice_limit** - Number of invoices to raise during the subscription. Overrides `invoice_limit` set on plan." - }, - { - "api": "export", - "endpoint": "https://api.paystack.co/transaction/export", - "method": "GET", - "params": [ - { - "parameter": "from", - "required": false, - "type": "String" - }, - { - "parameter": "to", - "required": false, - "type": "String" - }, - { - "parameter": "settled", - "required": false, - "type": "String" - }, - { - "parameter": "payment_page", - "required": false, - "type": "String" - }, - { - "parameter": "customer", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "settlement", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - }, - { - "parameter": "status", - "required": false, - "type": "String" - } - ], - "description": "**Query Params**\n- **from** - Lower bound of date range. Leave undefined to export transactions from day one.\n- **to** - Upper bound of date range. Leave undefined to export transactions till date.\n- **settled** - Set to `true` to export only settled transactions. `false` for pending transactions. Leave undefined to export all transactions\n- **payment_page** - Specify a payment page's id to export only transactions conducted on said page\n- **customer** - Specify customer id.\n- **currency** - Currency in which you are charging the customer in.\n- **settlement** - An ID for the settlement whose transactions we should export\n- **amount** - Amount for transactions to export\n- **status** - Status for transactions to export" - }, - { - "api": "check", - "endpoint": "https://api.paystack.co/transaction/check_authorization", - "method": "POST", - "params": [ - - { - "parameter": "authorization_code", - "required": true, - "type": "String" - }, - { - "parameter": "amount", - "required": true, - "type": "Number" - }, - { - "parameter": "email", - "required": true, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - } - ], - "description": "All mastercard and visa authorizations can be checked with this endpoint to know if they have funds for the payment you seek.\n\n**Body Params**\n- **authorization_code** (_required_) - Authorization code for mastercard or VISA authorization belonging to email.\n- **amount** (_required_) - Amount in kobo\n- **email** (_required_) - Customer's email address\n- **currency** - A currency for the amount we want to check\n\nIn test mode, we will return insufficient funds for an amount greater than or equal 500,000 naira." - }, - { - "api": "transaction", - "endpoint": "https://api.paystack.co/transaction/totals", - "method": "GET", - "params": [ - { - "parameter": "from", - "required": false, - "type": "String" - }, - { - "parameter": "to", - "required": false, - "type": "String" - } - ], - "description": "Total amount received on your account\n\n**Query Params**\n- **from** - Lower bound of date range. Leave undefined to show totals from day one.\n- **to** - Upper bound of date range. Leave undefined to show totals till date." - }, - { - "api": "initialize", - "endpoint": "https://api.paystack.co/transaction/initialize", - "method": "POST", - "params": [ - { - "parameter": "email", - "required": true, - "type": "String" - }, - { - "parameter": "amount", - "required": true, - "type": "Number" - }, - { - "parameter": "reference", - "required": false, - "type": "String" - }, - { - "parameter": "callback_url", - "required": false, - "type": "String" - }, - { - "parameter": "plan", - "required": false, - "type": "String" - }, - { - "parameter": "invoice_limit", - "required": false, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - }, - { - "parameter": "subaccount", - "required": false, - "type": "String" - }, - { - "parameter": "transaction_charge", - "required": false, - "type": "String" - }, - { - "parameter": "bearer", - "required": false, - "type": "String" - }, - { - "parameter": "channels", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **email** (_required_) - Customer's email address\n- **amount** (_required_) - Amount in kobo\n- **reference** - Generate a reference or leave this param blank for Paystack to generate one for you\n- **callback_url** - Overrides the callback URL set on Paystack dashboard.\n- **plan** - If transaction is to create a subscription to a predefined plan, provide plan code here. This would invalidate the value provided in `amount`\n- **invoice_limit** - Number of times to charge customer during subscription to plan\n- **metadata** - Stringified JSON object. Add a `custom_fields` attribute which has an array of objects if you would like the fields to be added to your transaction when displayed on the dashboard.\n- **subaccount** - The code for the subaccount that owns the payment.\n- **transaction_charge** - A flat fee to charge the subaccount for this transaction, in kobo. This overrides the split percentage set when the subaccount was created. Ideally, you will need to use this if you are splitting in flat rates (since subaccount creation only allows for percentage split).\n- **bearer** - Who bears Paystack charges? `account` or `subaccount` (defaults to `account`).\n- **channels** - Send us 'card' or 'bank' or 'card','bank' as an array to specify what options to show the user paying" - }, - { - "api": "fetch", - "endpoint": "https://api.paystack.co/transaction/id", - "method": "GET", - "params": [ - { - "parameter": "id", - "required": true, - "type": "String" - } - ], - "description": "**Path Params**\n- **id** (_required_) - An ID for the transaction to fetch" - } - ], - "plan": [ - { - "api": "update", - "endpoint": ":id_or_plan_code", - "method": "PUT", - "params": [ - { - "parameter": "name", - "required": false, - "type": "String" - }, - { - "parameter": "description", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - }, - { - "parameter": "interval", - "required": false, - "type": "String" - }, - { - "parameter": "send_invoices", - "required": false, - "type": "String" - }, - { - "parameter": "send_sms", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "invoice_limit", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **name** - Name of plan\n- **description** - Short description of plan\n- **amount** - Amount to be charged in kobo. Will override the amount for existing subscriptions.\n- **interval** - Interval in words. Valid intervals are `hourly`, `daily`, `weekly`, `monthly`, `annually`.\n- **send_invoices** - Set to false if you don't want invoices to be sent to your customers.\n- **send_sms** - Set to false if you don't want text messages to be sent to your customers\n- **currency** - Currency in which amount is set\n- **invoice_limit** - Number of invoices to raise during subscription to this plan. Will not override `invoice_limit` set on active subscriptions." - }, - { - "api": "create", - "endpoint": "https://api.paystack.co/plan", - "method": "POST", - "params": [ - { - "parameter": "name", - "required": true, - "type": "String" - }, - { - "parameter": "description", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": true, - "type": "Number" - }, - { - "parameter": "interval", - "required": true, - "type": "String" - }, - { - "parameter": "send_invoices", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "invoice_limit", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **name** (_required_) - Name of plan\n- **description** - Short description of plan\n- **amount** (_required_) - Amount to be charged in kobo\n- **interval** (_required_) - Interval in words. Valid intervals are `hourly`, `daily`, `weekly`, `monthly`, `annually`.\n- **send_invoices** - Set to false if you don't want invoices to be sent to your customers\n- **currency** - Currency in which amount is set\n- **invoice_limit** - Number of invoices to raise during subscription to this plan. Can be overridden by specifying an `invoice_limit` while subscribing." - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/plan", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - }, - { - "parameter": "interval", - "required": false, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **interval** - Filter list by plans with specified interval\n- **amount** - Filter list by plans with specified amount (in kobo)" - }, - { - "api": "fetch", - "endpoint": "https://api.paystack.co/plan/id_or_plan_code", - "method": "GET", - "params": [], - "description": null - } - ], - "customer": [ - { - "api": "update", - "endpoint": "https://api.paystack.co/customer/:ID_OR_CUSTOMER_CODE", - "method": "PUT", - "params": [ - { - "parameter": "first_name", - "required": false, - "type": "String" - }, - { - "parameter": "last_name", - "required": false, - "type": "String" - }, - { - "parameter": "phone", - "required": false, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **first_name** - Customer's first name\n- **last_name** - Customer's last name\n- **phone** - Customer's phone number\n- **metadata** - A set of key/value pairs that you can attach to the customer. It can be used to store additional information in a structured format." - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/customer", - "method": "GET", - "params": [ - { - "parameter": "perPage", - "required": false, - "type": "String" - }, - { - "parameter": "page", - "required": false, - "type": "Number" - } - ], - "description": "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve" - }, - { - "api": "create", - "endpoint": "https://api.paystack.co/customer", - "method": "POST", - "params": [ - { - "parameter": "email", - "required": true, - "type": "String" - }, - { - "parameter": "first_name", - "required": false, - "type": "String" - }, - { - "parameter": "last_name", - "required": false, - "type": "String" - }, - { - "parameter": "phone", - "required": false, - "type": "String" - }, - { - "parameter": "metadata", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **email** (_required_) - Customer's email address\n- **first_name** - Customer's first name\n- **last_name** - Customer's last name\n- **phone** - Customer's phone number\n- **metadata** - A set of key/value pairs that you can attach to the customer. It can be used to store additional information in a structured format." - }, - { - "api": "fetch", - "endpoint": ":id_or_customer_code", - "method": "GET", - "params": [ - { - "parameter": "exclude_transactions", - "required": false, - "type": "String" - } - ], - "description": "**Query Params**\n- **exclude_transactions** - By default, fetching a customer returns all their transactions. Set this to true to disable this behaviour." - }, - { - "api": "white/blacklist", - "endpoint": "https://api.paystack.co/customer/set_risk_action", - "method": "POST", - "params": [ - { - "parameter": "customer", - "required": false, - "type": "String" - }, - { - "parameter": "risk_action", - "required": false, - "type": "String" - } - ], - "description": "**Body Params**\n- **customer** - Customer's ID, code, or email address\n- **risk_action** - One of the possible risk actions. `allow` to whitelist. `deny` to blacklist." - }, - { - "api": "deactivate", - "endpoint": "https://api.paystack.co/customer/deactivate_authorization", - "method": "POST", - "params": [ - - { - "parameter": "authorization_code", - "required": true, - "type": "String" - }, - ], - "description": "For when the card needs to be forgotten...\n\n**Body Params**\n- **authorization_code** (_required_) - Authorization code to be deactivated\n\n" - } - ], - "refund": [ - { - "api": "create", - "endpoint": "https://api.paystack.co/refund", - "method": "POST", - "params": [ - - { - "parameter": "Body Params", - "required": false, - "type": "String" - }, - { - "parameter": "transaction", - "required": true, - "type": "String" - }, - { - "parameter": "amount", - "required": false, - "type": "Number" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - }, - { - "parameter": "customer_note", - "required": false, - "type": "String" - }, - { - "parameter": "merchant_note", - "required": false, - "type": "String" - } - ], - "description": "This creates a refund which is then processed by the Paystack team\n\n**Body Params**\n- **transaction** _(required)_: Identifier for transaction to be refunded\n- **amount** _(optional)_: How much in kobo to be refunded to the customer. Amount is optional(defaults to original transaction amount) and cannot be more than the original transaction amount.\n- **currency**: Three-letter ISO currency\n- **customer_note** _(optional)_: customer reason\n- **merchant_note** _(optional)_: merchant reason" - }, - { - "api": "fetch", - "endpoint": ":id", - "method": "GET", - "params": [ - { - "parameter": "id", - "required": false, - "type": "String" - } - ], - "description": "**Path Params**\n- **id** - ID of the transaction to be refunded" - }, - { - "api": "fetch", - "endpoint": ":id", - "method": "GET", - "params": [ - { - "parameter": "id", - "required": false, - "type": "String" - } - ], - "description": "**Path Params**\n- **id** - ID of the transaction to be refunded" - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/refund", - "method": "GET", - "params": [ - - { - "parameter": "transaction", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - } - ], - "description": "**Query Parameters**\n\n- **transaction**\n- **currency**" - }, - { - "api": "list", - "endpoint": "https://api.paystack.co/refund", - "method": "GET", - "params": [ - - { - "parameter": "transaction", - "required": false, - "type": "String" - }, - { - "parameter": "currency", - "required": false, - "type": "String" - } - ], - "description": "**Query Parameters**\n\n- **transaction**\n- **currency**" - } - ], - "integration": [ - { - "api": "update", - "endpoint": "https://api.paystack.co/integration/payment_session_timeout", - "method": "PUT", - "params": [ - { - "parameter": "timeout", - "required": false, - "type": "String" - } - ], - "description": "**Query Params**\n- **timeout** - Time before stopping session (in seconds). Set to 0 to cancel session timeouts" - }, - { - "api": "fetch", - "endpoint": "https://api.paystack.co/integration/payment_session_timeout", - "method": "GET", - "params": [], - "description": null - } - ], - "balance": [ - { - "api": "check", - "endpoint": "https://api.paystack.co/balance", - "method": "GET", - "params": [], - "description": "You can only transfer from what you have" - }, - { - "api": "balance", - "endpoint": "https://api.paystack.co/balance/ledger", - "method": "GET", - "params": [], - "description": "Returns all activity carried out from and to the Paystack Balance" - } - ], - "settlement": [ - { - "api": "fetch", - "endpoint": "https://api.paystack.co/settlement", - "method": "GET", - "params": [ - { - "parameter": "from", - "required": false, - "type": "String" - }, - { - "parameter": "to", - "required": false, - "type": "String" - }, - { - "parameter": "subaccount", - "required": false, - "type": "String" - } - ], - "description": "Settlements made to your bank accounts and the bank accounts for your subaccounts\n\n**Query Params**\n- **from** - Lower bound of date range. Leave undefined to export settlement from day one.\n- **to** - Upper bound of date range. Leave undefined to export settlements till date.\n- **subaccount** - Provide a subaccount code to export only settlements for that subaccount. Set to `none` to export only transactions for the account." - } - ], - "decision": [ - { - "api": "resolve", - "endpoint": "{BIN)", - "method": "GET", - "params": [ - { - "parameter": "bin", - "required": true, - "type": "String" - } - ], - "description": "**Path Params**\n- **bin** (_required_) - First 6 characters of card" - } - ], - "invoice": [ - { - "api": "archive", - "endpoint": ":id_or_code", - "method": "POST", - "params": [], - "description": "Used to archive an invoice. Invoice will no longer be fetched on list or returned on verify." - } - ], - "verifications": [ - { - "api": "resolve", - "endpoint": "https://api.paystack.co/verifications", - "method": "POST", - "params": [ - - { - "parameter": "Body Parameters", - "required": false, - "type": "String" - }, - { - "parameter": "verification_type", - "required": true, - "type": "String" - }, - { - "parameter": "phone", - "required": true, - "type": "String" - }, - { - "parameter": "callback_url", - "required": false, - "type": "String" - } - ], - "description": "Using the Truecaller API you can verify the authenticity of a customer. It returns the customer's name, phone number, email, social media handles and organization as available on their Truecaller profile.\n\n**Body Parameters**\n- **verification_type** _(required)_\n- **phone** _(required)_ - Customer phone number starting with country code (without the + prefix)\n- **callback_url** - Link on server to receive the truecaller details" - } - ] -} \ No newline at end of file diff --git a/lib/db.js b/lib/db.js deleted file mode 100644 index 449d969..0000000 --- a/lib/db.js +++ /dev/null @@ -1,29 +0,0 @@ -const rl = require('readline'); - -const low = require('lowdb') -const FileSync = require('lowdb/adapters/FileSync') - -const adapter = new FileSync('db.json') -const db = low(adapter) - -db.defaults({ token: '', user: {}, selected_integration: {} }).write(); - - - -module.exports = { - write: function (key, value) { - db.set(key, value).write(); - }, - read: function (key) { - return db.get(key).value(); - }, - addToList: function (key, value) { - db.get(key) - .push(value) - .write() - }, - query: function (key, query) { - return db.get(key) - .find(query).value() - } -} \ No newline at end of file diff --git a/lib/generateAPICommands.js b/lib/generateAPICommands.js new file mode 100644 index 0000000..be1c0cc --- /dev/null +++ b/lib/generateAPICommands.js @@ -0,0 +1,94 @@ +const APIs = require('./src/lib/paystack/apis') +const fs = require('fs'); + +function toTitleCase(str) { + return str.replace( + /\w\S*/g, + function (txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + } + ); +} +let commandKeys = Object.keys(APIs) +let declaredCommands = []; +commandKeys.forEach(key => { + let API = APIs[key] + let script = ` +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/apis') +const db = require('../lib/db') +let key = '${key}'; +let API = APIs[key]; +class ${toTitleCase(key)}Command extends Command { + + + async run() { + const {args, flags} = await this.parse(${toTitleCase(key)}Command) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the \` paystack login \` command before you begin") + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(\`ValidationError: Invalid endpoint '${key}'\`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +${toTitleCase(key)}Command.description = helpers.getDescription(API, key) + +${toTitleCase(key)}Command.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.string() + break + case 'Number': + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.boolean() + break + default: + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) +}) +${toTitleCase(key)}Command.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = ${toTitleCase(key)}Command; +` + fs.writeFile(`./src/commands/${key}.js`, script, () => { + declaredCommands.push(key) + }) +}) + + diff --git a/lib/generateAPICommands2.js b/lib/generateAPICommands2.js new file mode 100644 index 0000000..c1f2c7d --- /dev/null +++ b/lib/generateAPICommands2.js @@ -0,0 +1,115 @@ +let APIs = require('./src/lib/paystack/APIs.json') +// APIs = JSON.parse(APIs); +const fs = require('fs'); + +function toTitleCase(str) { + return str.replace( + /\w\S*/g, + function (txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + } + ); +} +let commandKeys = Object.keys(APIs) +let declaredCommands = []; +commandKeys.forEach(key => { + let API = APIs[key] + let script = ` +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = '${key}'; +let API = APIs[key]; +class ${toTitleCase(key)}Command extends Command { + + + async run() { + const {args, flags} = await this.parse(${toTitleCase(key)}Command) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the \` paystack login \` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(\`ValidationError: Invalid endpoint '${key}'\`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +${toTitleCase(key)}Command.description = helpers.getDescription(API, key) + +${toTitleCase(key)}Command.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.string() + break + case 'Number': + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.boolean() + break + default: + ${toTitleCase(key)}Command.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + ${toTitleCase(key)}Command.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +${toTitleCase(key)}Command.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = ${toTitleCase(key)}Command; +` + fs.writeFile(`./src/commands/${key}.js`, script, () => { + declaredCommands.push(key) + }) +}) + + diff --git a/lib/helpers.js b/lib/helpers.js deleted file mode 100644 index e87c895..0000000 --- a/lib/helpers.js +++ /dev/null @@ -1,120 +0,0 @@ -const readlineSync = require('readline-sync'); -const chalk = require('chalk'); -const url = require('url'); -const APIs = require('./paystack/apis') -const axios = require('axios') -function prompt(question, mute = false) { - return readlineSync.question(question, { hideEchoBack: mute }) -} -const promiseWrapper = promise => ( - promise - .then(data => ([null, data])) - .catch(error => ([error])) -); - -function jsonLog(json) { - let keys = Object.keys(json); - - keys.forEach((k) => { - if(isJson(json[k]) || json[k] == null){ - return - } - infoLog(`${k} - - - -- - -- - - - - - - - - - - - ${json[k]}`) - }) -} -function successLog(error) { - const eLog = chalk.green(error) - console.log(eLog) -} -function errorLog(error) { - const eLog = chalk.red(error) - console.log(eLog) -} -function isJson(val) { - - return val instanceof Array || val instanceof Object ? true : false; - - -} - -function loader() { - let progress = require('progressbar').create().step('. .') - return new Promise((resolve, reject) => { - [ - () => progress.setTotal(3), - () => progress.addTick(), - () => progress.addTick(), - () => progress.addTick(), - () => progress.finish() // remove and destroy the progress bar - ].forEach(function (step, index) { - setTimeout(step, index * 1000) - - }) - resolve('hello'); - }) -} -function infoLog(error) { - const eLog = chalk.blue(error) - console.log(eLog) -} -function parseURL(uri) { - if (!uri.startsWith('http')) uri = 'http://' + uri - return url.parse(uri) - -} -function findSchema(command, args) { - let schema; - APIs[command].forEach((f) => { - if (f.api == args.command) { - schema = f; - } - }) - return schema; -} - -async function executeSchema(schema, args) { - let domain = 'test'; - if (args.options.domain) { - domain = args.options.domain - } - let key = db.query('selected_integration.keys', { domain, 'type': 'secret' }).key; - let instance = axios.create({ - baseURL: 'https://api.paystack.co', - timeout: 3000, - headers: { 'Authorization': 'Bearer ' + key } - }); - return new Promise((resolve, reject) => { - let query, data; - if (schema.method == 'GET') query = args.options; - if (schema.method == 'POST') data = args.options; - if (schema.endpoint.indexOf('{')) { - let path = schema.endpoint.slice(schema.endpoint.indexOf('{') + 1, schema.endpoint.indexOf('}')) - - schema.endpoint = schema.endpoint.replace('{' + path + '}', args.options[path]); - - } - instance({ - url: schema.endpoint, - method: schema.method, - query, - data - }).then((resp) => { - resolve(resp.data) - }).catch((err) => { - reject(err.response.data.message) - }) - }) -} - -function getDescription(section, title) { - let desc = '' - section.forEach((f) => { - desc = desc + ', ' + f.api - }) - desc = desc + ' ' + title; - desc = desc.slice(1); - return desc; -} - - -module.exports = { prompt, promiseWrapper, successLog, jsonLog , errorLog, infoLog, isJson, loader, parseURL, findSchema, executeSchema, getDescription} \ No newline at end of file diff --git a/lib/postmanToAPI.js b/lib/postmanToAPI.js new file mode 100644 index 0000000..37e2973 --- /dev/null +++ b/lib/postmanToAPI.js @@ -0,0 +1,177 @@ +const fs = require('fs'); +const collection = require('./Paystack.postman_collection'); +const baseUrl = "https://api.paystack.co"; +let parsedAPIs = {} +collection.item.forEach((APIObject) => { + + let command_name = APIObject.name.toLowerCase(); + command_name = command_name.replace(/ /g, ''); + if (command_name.includes('integration/')) { + command_name = command_name.replace('integration/', '') + } + parsedAPIs[command_name] = []; + if (!isAPIObject(APIObject)) { + + APIObject.item.forEach((subObject) => { + let subcommand_name = subObject.name.toLowerCase(); + subcommand_name = subcommand_name.replace(/ /g, ''); + if (!isAPIObject(subObject)) { + subObject.item.forEach((_subObject) => { + subcommand_name = _subObject.name.toLowerCase(); + subcommand_name = subcommand_name.replace(/ /g, ''); + if (isAPIObject(_subObject)) { + let formattedAPI = createAPIObject(_subObject, command_name); + parsedAPIs[command_name].push(formattedAPI); + } else { + // console.log('Naah', _subObject) + } + }) + } else { + //add to API collection + let formattedAPI = createAPIObject(subObject, command_name); + parsedAPIs[command_name].push(formattedAPI); + // console.log(Object.keys(subObject)) + } + }) + } + else { + //add to API collection + let formattedAPI = createAPIObject(APIObject, command_name); + parsedAPIs[command_name].push(formattedAPI); + // console.log(formattedAPI); + // console.log(Object.keys(APIObject)) + } + +}) + +fs.writeFile(`./APIs.json`, JSON.stringify(parsedAPIs), () => { + console.log("done") +}) + +function isAPIObject(obj) { + if (obj.item) { + return false; + } + if (obj.request && obj.response) { + return true; + } +} +function createAPIObject(schema, parent) { + + // console.log(schema); + let API = { + baseUrl: "https://api.paystack.co", + path: "/transaction/initialize", + method: "POST", + params: [{ + parameter: "email", + required: true, + type: "String", + description: "Lorem ipsum" + }], + api: "initialize", + parent: "transaction" + } + try { + API.baseUrl = "https://api.paystack.co/"; + API.path = schema.request.url.path.join('/'); + API.method = schema.request.method; + API.parent = parent; + API.api = ''; + + //Format command name + let name = schema.name.toLowerCase(); + if (name.includes(parent + 's')) { + API.api = name.replace(parent + 's', ''); + } else if (name.includes(parent)) { + API.api = name.replace(parent, ''); + } else { + if (noOfWords(name) === 2) { + name = name.replace(' ', '_'); + API.api = name; + } else { + let words = name.split(' '); + let lastTwo = words[words.length - 2] + words[words.length - 1]; + if (lastTwo == parent) { + API.api = words[0]; + } else if (lastTwo == parent + 's') { + API.api = words[0]; + } + else { + API.api = "****" + name + } + + } + } + API.api = API.api.replace(' ', ' '); + API.api = API.api.trim(); + if (noOfWords(API.api) > 1) { + API.api = API.api.replace(/ /g, '_'); + API.api = "****" + API.api + } + + + //Get parameters + API.params = []; + if (API.method == "GET") { + let query = schema.request.url.query; + if (query) { + + query.forEach((param) => { + let _p = { + parameter: param.key, + description: param.description, + required: false + } + API.params.push(_p) + }) + } else { + console.log(API.parent + ' - ' + API.name, "Shoout!") + } + } else if (API.method == "POST" || API.method == "PUT") { + // console.log(Object.keys(schema.request)) + if (schema.request.body) { + + + let body = schema.request.body.urlencoded; + if (body) { + body.forEach((param) => { + let _p = { + parameter: param.key, + description: param.description, + required: false + } + if (_p.description.toLowerCase().includes('required')) { + _p.required = true; + } + API.params.push(_p) + }) + } else { + console.log(API.parent + ' - ' + API.name, "Shoout!!") + } + } else { + console.log(API.parent + ' - ' + API.name, "why not"); + } + } + + + //GET variables + if(schema.request.url.variable){ + API.variables = schema.request.url.variable + } + } catch (err) { + console.error(err) + } + + return API; +} + +function noOfWords(str) { + return str.split(' ').length; +} + + +/* +Highlight - New phone, new merch and stuff, Tomilola's birthday weekend. We have BPOs now! +Lowlight - Fuel, I'm tired, but I don't feel like I did plenty work +*/ \ No newline at end of file diff --git a/lib/samples.js b/lib/samples.js deleted file mode 100644 index fa26be0..0000000 --- a/lib/samples.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - sample_vue:{ - name:'sample-vue', - description: 'A sample vue application for accepting donations using Paystack', - git: 'https://github.com/PaystackOSS/sample-vue', - init_commands:['npm install', 'npm run serve'] - }, - sample_react:{ - name:'sample-react', - description: 'A sample vue application for accepting donnations using Paystack', - git: 'https://github.com/PaystackOSS/sample-react.git', - init_commands:['yarn install', 'yarn start'] - }, - gift_store:{ - name: 'sample-gift-store', - description: 'Lorem ipsum dolor sit amet', - git: 'https://github.com/PaystackOSS/sample-gift-store', - init_commands:['npm install', 'npm run serve'] - }, - sneaker_store:{ - name:'Kix', - description:'A sample sneakers store with Paystack checkout', - git:'https://git@github.com:PaystackOSS/sample-kix.git', - init_commands:['npm install', 'npm run serve'] - } -} \ No newline at end of file diff --git a/logger b/logger deleted file mode 100755 index 03166e6..0000000 --- a/logger +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -console.log("I am a logger") \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5c9af37 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9456 @@ +{ + "name": "@paystack-oss/dev-cli", + "version": "1.0.0-nightly.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@paystack-oss/dev-cli", + "version": "1.0.0-nightly.0", + "license": "MIT", + "dependencies": { + "@oclif/command": "^1.8.0", + "@oclif/config": "^1.17.0", + "@oclif/core": "^1", + "@oclif/plugin-autocomplete": "^0.3.0", + "@oclif/plugin-help": "^5", + "@oclif/plugin-not-found": "^2.3.1", + "@oclif/plugin-plugins": "^2.0.1", + "@oclif/plugin-update": "^3.0.0", + "@oclif/plugin-version": "^1", + "7zip-min": "^1.4.2", + "axios": "^0.21.1", + "https-proxy-agent": "^5.0.1", + "lowdb": "^1.0.0", + "ngrok": "^3.4.0", + "open": "^8.4.0", + "pjson": "^1.0.9", + "platform": "^1.3.6", + "pusher-js": "^7.0.3", + "readline": "^1.3.0", + "readline-sync": "^1.4.10", + "shelljs": "^0.8.4" + }, + "bin": { + "paystack": "bin/run" + }, + "devDependencies": { + "@oclif/dev-cli": "^1.26.0", + "eslint": "^8.9.0", + "eslint-config-oclif": "^3.1.0", + "globby": "^10.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.17.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.4.tgz", + "integrity": "sha512-R9x5r4t4+hBqZTmioSnkrW+I6NmbojwjGT8p4G2Gw1thWbXIHGDnmGdLdFw0/7ljucdIrNRp7Npgb4CyBYzzJg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.3", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", + "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.1", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", + "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@oclif/color": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@oclif/color/-/color-1.0.1.tgz", + "integrity": "sha512-qjYr+izgWdIVOroiBKqTzQgc1r5Wd9QB1J7yGM2EeelqhBARiiVLRZL45vhV4zdyTRdDkZS0EBzFwQap+nliLA==", + "dependencies": { + "ansi-styles": "^4.2.1", + "chalk": "^4.1.0", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "tslib": "^2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/color/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@oclif/command": { + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.16.tgz", + "integrity": "sha512-rmVKYEsKzurfRU0xJz+iHelbi1LGlihIWZ7Qvmb/CBz1EkhL7nOkW4SVXmG2dA5Ce0si2gr88i6q4eBOMRNJ1w==", + "dependencies": { + "@oclif/config": "^1.18.2", + "@oclif/errors": "^1.3.5", + "@oclif/help": "^1.0.1", + "@oclif/parser": "^3.8.6", + "debug": "^4.1.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@oclif/config": "^1" + } + }, + "node_modules/@oclif/config": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.3.tgz", + "integrity": "sha512-sBpko86IrTscc39EvHUhL+c++81BVTsIZ3ETu/vG+cCdi0N6vb2DoahR67A9FI2CGnxRRHjnTfa3m6LulwNATA==", + "dependencies": { + "@oclif/errors": "^1.3.5", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/config/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@oclif/config/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@oclif/core": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.3.4.tgz", + "integrity": "sha512-IqwfP1qHJ7V6LXxyCBBX12T0vNvrcK9Mlxv0xyt+snhslwThBXJY09umWcQJhWe+vxA8Y/mihB1bUkfURd2P2A==", + "dependencies": { + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^3.0.2", + "ansi-escapes": "^4.3.0", + "ansi-styles": "^4.2.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.10.0", + "debug": "^4.3.3", + "ejs": "^3.1.6", + "fs-extra": "^9.1.0", + "get-package-type": "^0.1.0", + "globby": "^11.0.4", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.13.1", + "lodash": "^4.17.21", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.4", + "password-prompt": "^1.1.2", + "semver": "^7.3.5", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "tslib": "^2.3.1", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/core/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@oclif/core/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@oclif/core/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@oclif/core/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@oclif/core/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@oclif/core/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@oclif/dev-cli": { + "version": "1.26.10", + "resolved": "https://registry.npmjs.org/@oclif/dev-cli/-/dev-cli-1.26.10.tgz", + "integrity": "sha512-dJ+II9rVXckzFvG+82PbfphMTnoqiHvsuAAbcHrLdZWPBnFAiDKhNYE0iHnA/knAC4VGXhogsrAJ3ERT5d5r2g==", + "dev": true, + "dependencies": { + "@oclif/command": "^1.8.15", + "@oclif/config": "^1.18.2", + "@oclif/errors": "^1.3.5", + "@oclif/plugin-help": "3.2.18", + "cli-ux": "5.6.7", + "debug": "^4.1.1", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^8.1", + "github-slugger": "^1.2.1", + "lodash": "^4.17.11", + "normalize-package-data": "^3.0.0", + "qqjs": "^0.3.10", + "tslib": "^2.0.3" + }, + "bin": { + "oclif-dev": "bin/run" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/@oclif/dev-cli/node_modules/@oclif/config": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", + "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", + "dev": true, + "dependencies": { + "@oclif/errors": "^1.3.3", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/dev-cli/node_modules/@oclif/plugin-help": { + "version": "3.2.18", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.2.18.tgz", + "integrity": "sha512-5n5Pkz4L0duknIvFwx2Ko9Xda3miT6RZP8bgaaK3Q/9fzVBrhi4bOM0u05/OThI6V+3NsSdxYS2o1NLcXToWDg==", + "dev": true, + "dependencies": { + "@oclif/command": "^1.8.14", + "@oclif/config": "1.18.2", + "@oclif/errors": "1.3.5", + "@oclif/help": "^1.0.0", + "chalk": "^4.1.2", + "indent-string": "^4.0.0", + "lodash": "^4.17.21", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/dev-cli/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@oclif/dev-cli/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@oclif/dev-cli/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@oclif/dev-cli/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@oclif/dev-cli/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@oclif/dev-cli/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@oclif/errors": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.5.tgz", + "integrity": "sha512-OivucXPH/eLLlOT7FkCMoZXiaVYf8I/w1eTAM1+gKzfhALwWTusxEx7wBmW0uzvkSg/9ovWLycPaBgJbM3LOCQ==", + "dependencies": { + "clean-stack": "^3.0.0", + "fs-extra": "^8.1", + "indent-string": "^4.0.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/errors/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@oclif/errors/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@oclif/errors/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@oclif/errors/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@oclif/help": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@oclif/help/-/help-1.0.1.tgz", + "integrity": "sha512-8rsl4RHL5+vBUAKBL6PFI3mj58hjPCp2VYyXD4TAa7IMStikFfOH2gtWmqLzIlxAED2EpD0dfYwo9JJxYsH7Aw==", + "dependencies": { + "@oclif/config": "1.18.2", + "@oclif/errors": "1.3.5", + "chalk": "^4.1.2", + "indent-string": "^4.0.0", + "lodash": "^4.17.21", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/help/node_modules/@oclif/config": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", + "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", + "dependencies": { + "@oclif/errors": "^1.3.3", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/help/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@oclif/help/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@oclif/help/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@oclif/linewrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", + "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==" + }, + "node_modules/@oclif/parser": { + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.6.tgz", + "integrity": "sha512-tXb0NKgSgNxmf6baN6naK+CCwOueaFk93FG9u202U7mTBHUKsioOUlw1SG/iPi9aJM3WE4pHLXmty59pci0OEw==", + "dependencies": { + "@oclif/errors": "^1.2.2", + "@oclif/linewrap": "^1.0.0", + "chalk": "^4.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/plugin-autocomplete": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@oclif/plugin-autocomplete/-/plugin-autocomplete-0.3.0.tgz", + "integrity": "sha512-gCuIUCswvoU1BxDDvHSUGxW8rFagiacle8jHqE49+WnuniXD/N8NmJvnzmlNyc8qLE192CnKK+qYyAF+vaFQBg==", + "dependencies": { + "@oclif/command": "^1.5.13", + "@oclif/config": "^1.13.0", + "chalk": "^4.1.0", + "cli-ux": "^5.2.1", + "debug": "^4.0.0", + "fs-extra": "^9.0.1", + "moment": "^2.22.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@oclif/plugin-help": { + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.1.11.tgz", + "integrity": "sha512-rWw1tIldlv54zMG804kHmftkaS007IMUkSclLX5sWtAyTrKM0HE730HmIg6ucbeFBrj0pXeDO1mXG/RZAC98tw==", + "dependencies": { + "@oclif/core": "^1.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-not-found": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-2.3.1.tgz", + "integrity": "sha512-AeNBw+zSkRpePmpXO8xlL072VF2/R2yK3qsVs/JF26Yw1w77TWuRTdFR+hFotJtFCJ4QYqhNtKSjdryCO9AXsA==", + "dependencies": { + "@oclif/color": "^1.0.0", + "@oclif/core": "^1.2.1", + "fast-levenshtein": "^3.0.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-not-found/node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/@oclif/plugin-plugins": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@oclif/plugin-plugins/-/plugin-plugins-2.1.0.tgz", + "integrity": "sha512-Bgt+QpTlX7+Q0HkVgtbUGYQlo/hyzNBAaXH5l16ou9Ji5wfi5T+niV5AzQ14R7JF8ZDOTbUOU/NRBJ2bzLCaZQ==", + "dependencies": { + "@oclif/color": "^1.0.1", + "@oclif/core": "^1.2.0", + "chalk": "^4.1.2", + "debug": "^4.1.0", + "fs-extra": "^9.0", + "http-call": "^5.2.2", + "load-json-file": "^5.3.0", + "npm-run-path": "^4.0.1", + "semver": "^7.3.2", + "tslib": "^2.0.0", + "yarn": "^1.22.17" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-update": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@oclif/plugin-update/-/plugin-update-3.0.0.tgz", + "integrity": "sha512-uWYTPxea4cDoOgDYxPhOisJCcoJHbbXFSM69iB9VkenAMerUjjq1VrlwWAIzLc45ciWk13uef4nBLy2S0ADtOg==", + "dependencies": { + "@oclif/color": "^1.0.0", + "@oclif/core": "^1.3.0", + "cross-spawn": "^7.0.3", + "debug": "^4.3.1", + "filesize": "^6.1.0", + "fs-extra": "^9.0.1", + "http-call": "^5.3.0", + "inquirer": "^8.2.0", + "lodash.throttle": "^4.1.1", + "log-chopper": "^1.0.2", + "semver": "^7.3.5", + "tar-fs": "^2.1.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/plugin-version": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oclif/plugin-version/-/plugin-version-1.0.4.tgz", + "integrity": "sha512-V9TZQKV4Ql7q0YnLyiebu9RTVvafkgGKM17eqDWyxHF0+qhsze661zcobJBXXRc51ObXUtHUFXamtHoxImO7Tg==", + "dependencies": { + "@oclif/core": "^1.1.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@oclif/screen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.2.tgz", + "integrity": "sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.2", + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "8.10.66", + "license": "MIT" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/request": { + "version": "2.48.7", + "license": "MIT", + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.1", + "license": "MIT" + }, + "node_modules/7zip-bin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", + "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==" + }, + "node_modules/7zip-min": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/7zip-min/-/7zip-min-1.4.2.tgz", + "integrity": "sha512-tCoI7vkhCpJoJSi3iTVmcyMEhkGHY/evKMnw1GL+ynrcWQtzRPJZlxHAV8wt3iAV+yV5d39fYglEpe1zMWLZbQ==", + "dependencies": { + "7zip-bin": "^5.1.1" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "license": "MIT" + }, + "node_modules/axios": { + "version": "0.21.4", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "license": "Apache-2.0" + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "license": "MIT/X11", + "dependencies": { + "traverse": ">=0.3.0 <0.4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "dependencies": { + "escape-string-regexp": "4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-progress": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.10.0.tgz", + "integrity": "sha512-kLORQrhYCAtUPLZxqsAt2YJGOvRdt34+O6jl5cQGb7iF3dM55FQZlTR+rQyIK9JUcO9bBMwZsTlND+3dmFU2Cw==", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-ux": { + "version": "5.6.7", + "resolved": "https://registry.npmjs.org/cli-ux/-/cli-ux-5.6.7.tgz", + "integrity": "sha512-dsKAurMNyFDnO6X1TiiRNiVbL90XReLKcvIq4H777NMqXGBxBws23ag8ubCJE97vVZEgWG2eSUhsyLf63Jv8+g==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dependencies": { + "@oclif/command": "^1.8.15", + "@oclif/errors": "^1.3.5", + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^1.0.4", + "ansi-escapes": "^4.3.0", + "ansi-styles": "^4.2.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.0", + "clean-stack": "^3.0.0", + "cli-progress": "^3.4.0", + "extract-stack": "^2.0.0", + "fs-extra": "^8.1", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.13.1", + "lodash": "^4.17.21", + "natural-orderby": "^2.0.1", + "object-treeify": "^1.1.4", + "password-prompt": "^1.1.2", + "semver": "^7.3.2", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "supports-color": "^8.1.0", + "supports-hyperlinks": "^2.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/cli-ux/node_modules/@oclif/screen": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz", + "integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/cli-ux/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-ux/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/cli-ux/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/cli-ux/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/cli-ux/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-ux/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", + "dev": true + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/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 + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-zip": { + "version": "0.3.3", + "license": "MIT", + "dependencies": { + "binary": "^0.3.0", + "graceful-fs": "^4.1.3", + "mkpath": "^0.1.0", + "nopt": "^3.0.1", + "q": "^1.1.2", + "readable-stream": "^1.1.8", + "touch": "0.0.3" + }, + "bin": { + "decompress-zip": "bin/decompress-zip" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "dependencies": { + "jake": "^10.6.1" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", + "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.1.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-oclif": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-3.1.2.tgz", + "integrity": "sha512-66i2mWHb4luJHqJSUO5o9bTYQyH4yuItEikBghUixQB1tFpe/j3mKoRMncxGm2LDGcVIbgK7iLXWO9Ta7buIpg==", + "deprecated": "Version 3.1.2 has been deprecated, it should have been a major version change. Please use 3.1.0 or 4.0.0 instead.", + "dev": true, + "dependencies": { + "eslint-config-xo-space": "^0.27.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-unicorn": "^36.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/@babel/eslint-parser": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", + "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", + "dev": true, + "dependencies": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/@babel/eslint-parser/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-config-oclif/node_modules/@babel/eslint-parser/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-config-oclif/node_modules/eslint-config-xo": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.35.0.tgz", + "integrity": "sha512-+WyZTLWUJlvExFrBU/Ldw8AB/S0d3x+26JQdBWbcqig2ZaWh0zinYcHok+ET4IoPaEcRRf3FE9kjItNVjBwnAg==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "1.0.10" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + }, + "peerDependencies": { + "eslint": ">=7.20.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/eslint-config-xo-space": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo-space/-/eslint-config-xo-space-0.27.0.tgz", + "integrity": "sha512-b8UjW+nQyOkhiANVpIptqlKPyE7XRyQ40uQ1NoBhzVfu95gxfZGrpliq8ZHBpaOF2wCLZaexTSjg7Rvm99vj4A==", + "dev": true, + "dependencies": { + "eslint-config-xo": "^0.35.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + }, + "peerDependencies": { + "eslint": ">=7.20.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/eslint-plugin-mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/eslint-plugin-unicorn": { + "version": "36.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-36.0.0.tgz", + "integrity": "sha512-xxN2vSctGWnDW6aLElm/LKIwcrmk6mdiEcW55Uv5krcrVcIFSWMmEgc/hwpemYfZacKZ5npFERGNz4aThsp1AA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.9", + "ci-info": "^3.2.0", + "clean-regexp": "^1.0.0", + "eslint-template-visitor": "^2.3.2", + "eslint-utils": "^3.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.23", + "safe-regex": "^2.1.1", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=7.32.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-oclif/node_modules/eslint-template-visitor/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-node/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "dev": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/extract-stack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/extract-stack/-/extract-stack-2.0.0.tgz", + "integrity": "sha512-AEo4zm+TenK7zQorGK1f9mJ8L14hnTDi2ZQPR+Mub1NX8zimka1mXpV5LpH8x9HoUmFSHZCfLHqWvp0Y4FxxzQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/filesize": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.4.0.tgz", + "integrity": "sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/github-slugger": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz", + "integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.0", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "license": "ISC" + }, + "node_modules/har-schema": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-call": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/http-call/-/http-call-5.3.0.tgz", + "integrity": "sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w==", + "dependencies": { + "content-type": "^1.0.4", + "debug": "^4.1.1", + "is-retry-allowed": "^1.1.0", + "is-stream": "^2.0.0", + "parse-json": "^4.0.0", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", + "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.2.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inquirer/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "node_modules/is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-core-module": { + "version": "2.8.0", + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "license": "MIT" + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isstream": { + "version": "0.1.2", + "license": "MIT" + }, + "node_modules/jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dependencies": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, + "node_modules/log-chopper": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-chopper/-/log-chopper-1.0.2.tgz", + "integrity": "sha512-tEWS6Fb+Xv0yLChJ6saA1DP3H1yPL0PfiIN7SDJ+U/CyP+fD4G/dhKfow+P5UuJWi6BdE4mUcPkJclGXCWxDrg==", + "dependencies": { + "byline": "5.x" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lowdb": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.3", + "is-promise": "^2.1.0", + "lodash": "4", + "pify": "^3.0.0", + "steno": "^0.4.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.50.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.33", + "license": "MIT", + "dependencies": { + "mime-db": "1.50.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "license": "MIT" + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/mkpath": { + "version": "0.1.0", + "license": "MIT" + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multimap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", + "engines": { + "node": "*" + } + }, + "node_modules/ngrok": { + "version": "3.4.1", + "hasInstallScript": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/node": "^8.10.50", + "@types/request": "^2.48.2", + "decompress-zip": "^0.3.2", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "uuid": "^3.3.2" + }, + "bin": { + "ngrok": "bin/ngrok" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node_modules/node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, + "node_modules/nopt": { + "version": "3.0.6", + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/password-prompt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", + "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", + "dependencies": { + "ansi-escapes": "^3.1.0", + "cross-spawn": "^6.0.5" + } + }, + "node_modules/password-prompt/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/password-prompt/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "engines": { + "node": ">=4" + } + }, + "node_modules/password-prompt/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/password-prompt/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/password-prompt/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/password-prompt/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pjson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/pjson/-/pjson-1.0.9.tgz", + "integrity": "sha512-4hRJH3YzkUpOlShRzhyxAmThSNnAaIlWZCAb27hd0pVUAXNUAHAO7XZbsPPvsCYwBFEScTmCCL6DGE8NyZ8BdQ==" + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pusher-js": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-7.0.6.tgz", + "integrity": "sha512-I44FTlF2OfGNg/4xcxmFq/JqFzJswoQWtWCPq+DkCh31MFg3Qkm3bNFvTXU+c5KR19TyBZ9SYlYq2rrpJZzbIA==", + "dependencies": { + "tweetnacl": "^1.0.3" + } + }, + "node_modules/pusher-js/node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/q": { + "version": "1.5.1", + "license": "MIT", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qqjs": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/qqjs/-/qqjs-0.3.11.tgz", + "integrity": "sha512-pB2X5AduTl78J+xRSxQiEmga1jQV0j43jOPs/MTgTLApGFEOn6NgdE2dEjp7nvDtjkIOZbvFIojAiYUx6ep3zg==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "debug": "^4.1.1", + "execa": "^0.10.0", + "fs-extra": "^6.0.1", + "get-stream": "^5.1.0", + "glob": "^7.1.2", + "globby": "^10.0.1", + "http-call": "^5.1.2", + "load-json-file": "^6.2.0", + "pkg-dir": "^4.2.0", + "tar-fs": "^2.0.0", + "tmp": "^0.1.0", + "write-json-file": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/qqjs/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/qqjs/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/qqjs/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/qqjs/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/qqjs/node_modules/fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/qqjs/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/qqjs/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/qqjs/node_modules/load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qqjs/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qqjs/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/qqjs/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/qqjs/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/qqjs/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ramda": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=" + }, + "node_modules/readline-sync": { + "version": "1.4.10", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/request": { + "version": "2.88.2", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "license": "ISC", + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "license": "ISC", + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/resolve": { + "version": "1.20.0", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "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" + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", + "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/sshpk": { + "version": "1.16.1", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "license": "ISC", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/steno": { + "version": "0.4.4", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.3" + } + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "dependencies": { + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "0.0.3", + "license": "ISC", + "dependencies": { + "nopt": "~1.0.10" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch/node_modules/nopt": { + "version": "1.0.10", + "license": "MIT", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "license": "MIT/X11" + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "license": "Unlicense" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/uuid": { + "version": "3.4.0", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/write-json-file": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz", + "integrity": "sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==", + "dev": true, + "dependencies": { + "detect-indent": "^6.0.0", + "graceful-fs": "^4.1.15", + "is-plain-obj": "^2.0.0", + "make-dir": "^3.0.0", + "sort-keys": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8.3" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yarn": { + "version": "1.22.17", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.17.tgz", + "integrity": "sha512-H0p241BXaH0UN9IeH//RT82tl5PfNraVpSpEoW+ET7lmopNC61eZ+A+IDvU8FM6Go5vx162SncDL8J1ZjRBriQ==", + "hasInstallScript": true, + "bin": { + "yarn": "bin/yarn.js", + "yarnpkg": "bin/yarn.js" + }, + "engines": { + "node": ">=4.0.0" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", + "dev": true + }, + "@babel/core": { + "version": "7.17.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.4.tgz", + "integrity": "sha512-R9x5r4t4+hBqZTmioSnkrW+I6NmbojwjGT8p4G2Gw1thWbXIHGDnmGdLdFw0/7ljucdIrNRp7Npgb4CyBYzzJg==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.3", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", + "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" + } + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", + "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", + "dev": true + }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", + "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.1", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", + "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@oclif/color": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@oclif/color/-/color-1.0.1.tgz", + "integrity": "sha512-qjYr+izgWdIVOroiBKqTzQgc1r5Wd9QB1J7yGM2EeelqhBARiiVLRZL45vhV4zdyTRdDkZS0EBzFwQap+nliLA==", + "requires": { + "ansi-styles": "^4.2.1", + "chalk": "^4.1.0", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "tslib": "^2" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@oclif/command": { + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.16.tgz", + "integrity": "sha512-rmVKYEsKzurfRU0xJz+iHelbi1LGlihIWZ7Qvmb/CBz1EkhL7nOkW4SVXmG2dA5Ce0si2gr88i6q4eBOMRNJ1w==", + "requires": { + "@oclif/config": "^1.18.2", + "@oclif/errors": "^1.3.5", + "@oclif/help": "^1.0.1", + "@oclif/parser": "^3.8.6", + "debug": "^4.1.1", + "semver": "^7.3.2" + } + }, + "@oclif/config": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.3.tgz", + "integrity": "sha512-sBpko86IrTscc39EvHUhL+c++81BVTsIZ3ETu/vG+cCdi0N6vb2DoahR67A9FI2CGnxRRHjnTfa3m6LulwNATA==", + "requires": { + "@oclif/errors": "^1.3.5", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.3.1" + }, + "dependencies": { + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + } + } + }, + "@oclif/core": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-1.3.4.tgz", + "integrity": "sha512-IqwfP1qHJ7V6LXxyCBBX12T0vNvrcK9Mlxv0xyt+snhslwThBXJY09umWcQJhWe+vxA8Y/mihB1bUkfURd2P2A==", + "requires": { + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^3.0.2", + "ansi-escapes": "^4.3.0", + "ansi-styles": "^4.2.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.10.0", + "debug": "^4.3.3", + "ejs": "^3.1.6", + "fs-extra": "^9.1.0", + "get-package-type": "^0.1.0", + "globby": "^11.0.4", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.13.1", + "lodash": "^4.17.21", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.4", + "password-prompt": "^1.1.2", + "semver": "^7.3.5", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "tslib": "^2.3.1", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "@oclif/dev-cli": { + "version": "1.26.10", + "resolved": "https://registry.npmjs.org/@oclif/dev-cli/-/dev-cli-1.26.10.tgz", + "integrity": "sha512-dJ+II9rVXckzFvG+82PbfphMTnoqiHvsuAAbcHrLdZWPBnFAiDKhNYE0iHnA/knAC4VGXhogsrAJ3ERT5d5r2g==", + "dev": true, + "requires": { + "@oclif/command": "^1.8.15", + "@oclif/config": "^1.18.2", + "@oclif/errors": "^1.3.5", + "@oclif/plugin-help": "3.2.18", + "cli-ux": "5.6.7", + "debug": "^4.1.1", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^8.1", + "github-slugger": "^1.2.1", + "lodash": "^4.17.11", + "normalize-package-data": "^3.0.0", + "qqjs": "^0.3.10", + "tslib": "^2.0.3" + }, + "dependencies": { + "@oclif/config": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", + "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", + "dev": true, + "requires": { + "@oclif/errors": "^1.3.3", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.0.0" + } + }, + "@oclif/plugin-help": { + "version": "3.2.18", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.2.18.tgz", + "integrity": "sha512-5n5Pkz4L0duknIvFwx2Ko9Xda3miT6RZP8bgaaK3Q/9fzVBrhi4bOM0u05/OThI6V+3NsSdxYS2o1NLcXToWDg==", + "dev": true, + "requires": { + "@oclif/command": "^1.8.14", + "@oclif/config": "1.18.2", + "@oclif/errors": "1.3.5", + "@oclif/help": "^1.0.0", + "chalk": "^4.1.2", + "indent-string": "^4.0.0", + "lodash": "^4.17.21", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "@oclif/errors": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.3.5.tgz", + "integrity": "sha512-OivucXPH/eLLlOT7FkCMoZXiaVYf8I/w1eTAM1+gKzfhALwWTusxEx7wBmW0uzvkSg/9ovWLycPaBgJbM3LOCQ==", + "requires": { + "clean-stack": "^3.0.0", + "fs-extra": "^8.1", + "indent-string": "^4.0.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "@oclif/help": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@oclif/help/-/help-1.0.1.tgz", + "integrity": "sha512-8rsl4RHL5+vBUAKBL6PFI3mj58hjPCp2VYyXD4TAa7IMStikFfOH2gtWmqLzIlxAED2EpD0dfYwo9JJxYsH7Aw==", + "requires": { + "@oclif/config": "1.18.2", + "@oclif/errors": "1.3.5", + "chalk": "^4.1.2", + "indent-string": "^4.0.0", + "lodash": "^4.17.21", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "@oclif/config": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.18.2.tgz", + "integrity": "sha512-cE3qfHWv8hGRCP31j7fIS7BfCflm/BNZ2HNqHexH+fDrdF2f1D5S8VmXWLC77ffv3oDvWyvE9AZeR0RfmHCCaA==", + "requires": { + "@oclif/errors": "^1.3.3", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-wsl": "^2.1.1", + "tslib": "^2.0.0" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "@oclif/linewrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", + "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==" + }, + "@oclif/parser": { + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.6.tgz", + "integrity": "sha512-tXb0NKgSgNxmf6baN6naK+CCwOueaFk93FG9u202U7mTBHUKsioOUlw1SG/iPi9aJM3WE4pHLXmty59pci0OEw==", + "requires": { + "@oclif/errors": "^1.2.2", + "@oclif/linewrap": "^1.0.0", + "chalk": "^4.1.0", + "tslib": "^2.0.0" + } + }, + "@oclif/plugin-autocomplete": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@oclif/plugin-autocomplete/-/plugin-autocomplete-0.3.0.tgz", + "integrity": "sha512-gCuIUCswvoU1BxDDvHSUGxW8rFagiacle8jHqE49+WnuniXD/N8NmJvnzmlNyc8qLE192CnKK+qYyAF+vaFQBg==", + "requires": { + "@oclif/command": "^1.5.13", + "@oclif/config": "^1.13.0", + "chalk": "^4.1.0", + "cli-ux": "^5.2.1", + "debug": "^4.0.0", + "fs-extra": "^9.0.1", + "moment": "^2.22.1" + } + }, + "@oclif/plugin-help": { + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-5.1.11.tgz", + "integrity": "sha512-rWw1tIldlv54zMG804kHmftkaS007IMUkSclLX5sWtAyTrKM0HE730HmIg6ucbeFBrj0pXeDO1mXG/RZAC98tw==", + "requires": { + "@oclif/core": "^1.2.0" + } + }, + "@oclif/plugin-not-found": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-2.3.1.tgz", + "integrity": "sha512-AeNBw+zSkRpePmpXO8xlL072VF2/R2yK3qsVs/JF26Yw1w77TWuRTdFR+hFotJtFCJ4QYqhNtKSjdryCO9AXsA==", + "requires": { + "@oclif/color": "^1.0.0", + "@oclif/core": "^1.2.1", + "fast-levenshtein": "^3.0.0", + "lodash": "^4.17.21" + }, + "dependencies": { + "fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "requires": { + "fastest-levenshtein": "^1.0.7" + } + } + } + }, + "@oclif/plugin-plugins": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@oclif/plugin-plugins/-/plugin-plugins-2.1.0.tgz", + "integrity": "sha512-Bgt+QpTlX7+Q0HkVgtbUGYQlo/hyzNBAaXH5l16ou9Ji5wfi5T+niV5AzQ14R7JF8ZDOTbUOU/NRBJ2bzLCaZQ==", + "requires": { + "@oclif/color": "^1.0.1", + "@oclif/core": "^1.2.0", + "chalk": "^4.1.2", + "debug": "^4.1.0", + "fs-extra": "^9.0", + "http-call": "^5.2.2", + "load-json-file": "^5.3.0", + "npm-run-path": "^4.0.1", + "semver": "^7.3.2", + "tslib": "^2.0.0", + "yarn": "^1.22.17" + } + }, + "@oclif/plugin-update": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@oclif/plugin-update/-/plugin-update-3.0.0.tgz", + "integrity": "sha512-uWYTPxea4cDoOgDYxPhOisJCcoJHbbXFSM69iB9VkenAMerUjjq1VrlwWAIzLc45ciWk13uef4nBLy2S0ADtOg==", + "requires": { + "@oclif/color": "^1.0.0", + "@oclif/core": "^1.3.0", + "cross-spawn": "^7.0.3", + "debug": "^4.3.1", + "filesize": "^6.1.0", + "fs-extra": "^9.0.1", + "http-call": "^5.3.0", + "inquirer": "^8.2.0", + "lodash.throttle": "^4.1.1", + "log-chopper": "^1.0.2", + "semver": "^7.3.5", + "tar-fs": "^2.1.1" + } + }, + "@oclif/plugin-version": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oclif/plugin-version/-/plugin-version-1.0.4.tgz", + "integrity": "sha512-V9TZQKV4Ql7q0YnLyiebu9RTVvafkgGKM17eqDWyxHF0+qhsze661zcobJBXXRc51ObXUtHUFXamtHoxImO7Tg==", + "requires": { + "@oclif/core": "^1.1.1" + } + }, + "@oclif/screen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-3.0.2.tgz", + "integrity": "sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==" + }, + "@types/caseless": { + "version": "0.12.2" + }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/node": { + "version": "8.10.66" + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "@types/request": { + "version": "2.48.7", + "requires": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "@types/tough-cookie": { + "version": "4.0.1" + }, + "7zip-bin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", + "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==" + }, + "7zip-min": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/7zip-min/-/7zip-min-1.4.2.tgz", + "integrity": "sha512-tCoI7vkhCpJoJSi3iTVmcyMEhkGHY/evKMnw1GL+ynrcWQtzRPJZlxHAV8wt3iAV+yV5d39fYglEpe1zMWLZbQ==", + "requires": { + "7zip-bin": "^5.1.1" + } + }, + "abbrev": { + "version": "1.1.1" + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "ajv": { + "version": "6.12.6", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "requires": { + "color-convert": "^2.0.1" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "asn1": { + "version": "0.2.4", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0" + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "asynckit": { + "version": "0.4.0" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "aws-sign2": { + "version": "0.7.0" + }, + "aws4": { + "version": "1.11.0" + }, + "axios": { + "version": "0.21.4", + "requires": { + "follow-redirects": "^1.14.0" + } + }, + "balanced-match": { + "version": "1.0.2" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "binary": { + "version": "0.3.0", + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffers": { + "version": "0.1.1" + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=" + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", + "dev": true + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "caseless": { + "version": "0.12.0" + }, + "chainsaw": { + "version": "0.1.0", + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "requires": { + "escape-string-regexp": "4.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + } + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-progress": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.10.0.tgz", + "integrity": "sha512-kLORQrhYCAtUPLZxqsAt2YJGOvRdt34+O6jl5cQGb7iF3dM55FQZlTR+rQyIK9JUcO9bBMwZsTlND+3dmFU2Cw==", + "requires": { + "string-width": "^4.2.0" + } + }, + "cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==" + }, + "cli-ux": { + "version": "5.6.7", + "resolved": "https://registry.npmjs.org/cli-ux/-/cli-ux-5.6.7.tgz", + "integrity": "sha512-dsKAurMNyFDnO6X1TiiRNiVbL90XReLKcvIq4H777NMqXGBxBws23ag8ubCJE97vVZEgWG2eSUhsyLf63Jv8+g==", + "requires": { + "@oclif/command": "^1.8.15", + "@oclif/errors": "^1.3.5", + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^1.0.4", + "ansi-escapes": "^4.3.0", + "ansi-styles": "^4.2.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.0", + "clean-stack": "^3.0.0", + "cli-progress": "^3.4.0", + "extract-stack": "^2.0.0", + "fs-extra": "^8.1", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.13.1", + "lodash": "^4.17.21", + "natural-orderby": "^2.0.1", + "object-treeify": "^1.1.4", + "password-prompt": "^1.1.2", + "semver": "^7.3.2", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "supports-color": "^8.1.0", + "supports-hyperlinks": "^2.1.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "@oclif/screen": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz", + "integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==" + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "color-convert": { + "version": "2.0.1", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4" + }, + "combined-stream": { + "version": "1.0.8", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1" + }, + "confusing-browser-globals": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "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 + } + } + }, + "core-util-is": { + "version": "1.0.3" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "decompress-zip": { + "version": "0.3.3", + "requires": { + "binary": "^0.3.0", + "graceful-fs": "^4.1.3", + "mkpath": "^0.1.0", + "nopt": "^3.0.1", + "q": "^1.1.2", + "readable-stream": "^1.1.8", + "touch": "0.0.3" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + } + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" + }, + "delayed-stream": { + "version": "1.0.0" + }, + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ejs": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", + "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", + "requires": { + "jake": "^10.6.1" + } + }, + "electron-to-chromium": { + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5" + }, + "eslint": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", + "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.1.0", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-config-oclif": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-3.1.2.tgz", + "integrity": "sha512-66i2mWHb4luJHqJSUO5o9bTYQyH4yuItEikBghUixQB1tFpe/j3mKoRMncxGm2LDGcVIbgK7iLXWO9Ta7buIpg==", + "dev": true, + "requires": { + "eslint-config-xo-space": "^0.27.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-unicorn": "^36.0.0" + }, + "dependencies": { + "@babel/eslint-parser": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", + "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", + "dev": true, + "requires": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-config-xo": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.35.0.tgz", + "integrity": "sha512-+WyZTLWUJlvExFrBU/Ldw8AB/S0d3x+26JQdBWbcqig2ZaWh0zinYcHok+ET4IoPaEcRRf3FE9kjItNVjBwnAg==", + "dev": true, + "requires": { + "confusing-browser-globals": "1.0.10" + } + }, + "eslint-config-xo-space": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo-space/-/eslint-config-xo-space-0.27.0.tgz", + "integrity": "sha512-b8UjW+nQyOkhiANVpIptqlKPyE7XRyQ40uQ1NoBhzVfu95gxfZGrpliq8ZHBpaOF2wCLZaexTSjg7Rvm99vj4A==", + "dev": true, + "requires": { + "eslint-config-xo": "^0.35.0" + } + }, + "eslint-plugin-mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz", + "integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==", + "dev": true, + "requires": { + "eslint-utils": "^3.0.0", + "ramda": "^0.27.1" + } + }, + "eslint-plugin-unicorn": { + "version": "36.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-36.0.0.tgz", + "integrity": "sha512-xxN2vSctGWnDW6aLElm/LKIwcrmk6mdiEcW55Uv5krcrVcIFSWMmEgc/hwpemYfZacKZ5npFERGNz4aThsp1AA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "ci-info": "^3.2.0", + "clean-regexp": "^1.0.0", + "eslint-template-visitor": "^2.3.2", + "eslint-utils": "^3.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.23", + "safe-regex": "^2.1.1", + "semver": "^7.3.5" + } + }, + "eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "requires": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + } + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "dev": true, + "requires": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "extend": { + "version": "3.0.2" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "extract-stack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/extract-stack/-/extract-stack-2.0.0.tgz", + "integrity": "sha512-AEo4zm+TenK7zQorGK1f9mJ8L14hnTDi2ZQPR+Mub1NX8zimka1mXpV5LpH8x9HoUmFSHZCfLHqWvp0Y4FxxzQ==" + }, + "extsprintf": { + "version": "1.3.0" + }, + "fast-deep-equal": { + "version": "3.1.3" + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==" + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "filesize": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.4.0.tgz", + "integrity": "sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "requires": { + "micromatch": "^4.0.2" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "follow-redirects": { + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" + }, + "forever-agent": { + "version": "0.6.1" + }, + "form-data": { + "version": "2.5.1", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0" + }, + "function-bind": { + "version": "1.1.1" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "getpass": { + "version": "0.1.7", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "github-slugger": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz", + "integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.8" + }, + "har-schema": { + "version": "2.0.0" + }, + "har-validator": { + "version": "5.1.5", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0" + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "http-call": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/http-call/-/http-call-5.3.0.tgz", + "integrity": "sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w==", + "requires": { + "content-type": "^1.0.4", + "debug": "^4.1.1", + "is-retry-allowed": "^1.1.0", + "is-stream": "^2.0.0", + "parse-json": "^4.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "http-signature": { + "version": "1.2.0", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "inflight": { + "version": "1.0.6", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4" + }, + "inquirer": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", + "integrity": "sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.2.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + } + } + }, + "interpret": { + "version": "1.4.0" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "requires": { + "builtin-modules": "^3.0.0" + } + }, + "is-core-module": { + "version": "2.8.0", + "requires": { + "has": "^1.0.3" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-promise": { + "version": "2.2.2" + }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-typedarray": { + "version": "1.0.0" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "0.0.1" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isstream": { + "version": "0.1.2" + }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.4.1" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1" + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, + "log-chopper": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-chopper/-/log-chopper-1.0.2.tgz", + "integrity": "sha512-tEWS6Fb+Xv0yLChJ6saA1DP3H1yPL0PfiIN7SDJ+U/CyP+fD4G/dhKfow+P5UuJWi6BdE4mUcPkJclGXCWxDrg==", + "requires": { + "byline": "5.x" + } + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lowdb": { + "version": "1.0.0", + "requires": { + "graceful-fs": "^4.1.3", + "is-promise": "^2.1.0", + "lodash": "4", + "pify": "^3.0.0", + "steno": "^0.4.1" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime-db": { + "version": "1.50.0" + }, + "mime-types": { + "version": "2.1.33", + "requires": { + "mime-db": "1.50.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.0.4", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "mkpath": { + "version": "0.1.0" + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multimap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==" + }, + "ngrok": { + "version": "3.4.1", + "requires": { + "@types/node": "^8.10.50", + "@types/request": "^2.48.2", + "decompress-zip": "^0.3.2", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "uuid": "^3.3.2" + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "oauth-sign": { + "version": "0.9.0" + }, + "object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==" + }, + "once": { + "version": "1.4.0", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "password-prompt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", + "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", + "requires": { + "ansi-escapes": "^3.1.0", + "cross-spawn": "^6.0.5" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "performance-now": { + "version": "2.1.0" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pify": { + "version": "3.0.0" + }, + "pjson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/pjson/-/pjson-1.0.9.tgz", + "integrity": "sha512-4hRJH3YzkUpOlShRzhyxAmThSNnAaIlWZCAb27hd0pVUAXNUAHAO7XZbsPPvsCYwBFEScTmCCL6DGE8NyZ8BdQ==" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "psl": { + "version": "1.8.0" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1" + }, + "pusher-js": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-7.0.6.tgz", + "integrity": "sha512-I44FTlF2OfGNg/4xcxmFq/JqFzJswoQWtWCPq+DkCh31MFg3Qkm3bNFvTXU+c5KR19TyBZ9SYlYq2rrpJZzbIA==", + "requires": { + "tweetnacl": "^1.0.3" + }, + "dependencies": { + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + } + } + }, + "q": { + "version": "1.5.1" + }, + "qqjs": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/qqjs/-/qqjs-0.3.11.tgz", + "integrity": "sha512-pB2X5AduTl78J+xRSxQiEmga1jQV0j43jOPs/MTgTLApGFEOn6NgdE2dEjp7nvDtjkIOZbvFIojAiYUx6ep3zg==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "debug": "^4.1.1", + "execa": "^0.10.0", + "fs-extra": "^6.0.1", + "get-stream": "^5.1.0", + "glob": "^7.1.2", + "globby": "^10.0.1", + "http-call": "^5.1.2", + "load-json-file": "^6.2.0", + "pkg-dir": "^4.2.0", + "tar-fs": "^2.0.0", + "tmp": "^0.1.0", + "write-json-file": "^4.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } + } + }, + "qs": { + "version": "6.5.2" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "ramda": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz", + "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "readable-stream": { + "version": "1.1.14", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw=" + }, + "readline-sync": { + "version": "1.4.10" + }, + "rechoir": { + "version": "0.6.2", + "requires": { + "resolve": "^1.1.6" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "requires": { + "esprima": "~4.0.0" + } + }, + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "request": { + "version": "2.88.2", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "resolve": { + "version": "1.20.0", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1" + }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, + "safer-buffer": { + "version": "2.1.2" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "sort-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.2.0.tgz", + "integrity": "sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==", + "dev": true, + "requires": { + "is-plain-obj": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stealthy-require": { + "version": "1.1.1" + }, + "steno": { + "version": "0.4.4", + "requires": { + "graceful-fs": "^4.1.3" + } + }, + "string_decoder": { + "version": "0.10.31" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "requires": { + "rimraf": "^2.6.3" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "0.0.3", + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "requires": { + "abbrev": "1" + } + } + } + }, + "tough-cookie": { + "version": "2.5.0", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "traverse": { + "version": "0.3.9" + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "tunnel-agent": { + "version": "0.6.0", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "uri-js": { + "version": "4.4.1", + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2" + } + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "requires": { + "string-width": "^4.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "write-json-file": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz", + "integrity": "sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==", + "dev": true, + "requires": { + "detect-indent": "^6.0.0", + "graceful-fs": "^4.1.15", + "is-plain-obj": "^2.0.0", + "make-dir": "^3.0.0", + "sort-keys": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yarn": { + "version": "1.22.17", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.17.tgz", + "integrity": "sha512-H0p241BXaH0UN9IeH//RT82tl5PfNraVpSpEoW+ET7lmopNC61eZ+A+IDvU8FM6Go5vx162SncDL8J1ZjRBriQ==" + } + } +} diff --git a/package.json b/package.json index b5d7faf..fdfbd8d 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,91 @@ { "name": "@paystack-oss/dev-cli", - "version": "0.0.3", - "private": false, - "preferGlobal": true, - "scripts": { - "start": "node cli.js" - }, + "description": "Set up, test, and manage your Paystack integration directly from the terminal.", + "version": "1.0.0-nightly.0", + "author": "Lukman Bello @lukman-paystack", "bin": { - "paystack": "./cli.js" + "paystack": "./bin/run" }, + "bugs": "https://github.com/PaystackOSS/paystack-cli/issues", "dependencies": { - "axios": "^0.19.2", - "chalk": "^3.0.0", - "debug": "~2.6.9", + "@oclif/command": "^1.8.0", + "@oclif/config": "^1.17.0", + "@oclif/core": "^1", + "@oclif/plugin-autocomplete": "^0.3.0", + "@oclif/plugin-help": "^5", + "@oclif/plugin-not-found": "^2.3.1", + "@oclif/plugin-plugins": "^2.0.1", + "@oclif/plugin-update": "^3.0.0", + "@oclif/plugin-version": "^1", + "7zip-min": "^1.4.2", + "axios": "^0.21.1", + "https-proxy-agent": "^5.0.1", "lowdb": "^1.0.0", - "ngrok": "^3.2.7", - "progressbar": "^1.3.0", + "ngrok": "^3.4.0", + "open": "^8.4.0", + "pjson": "^1.0.9", + "platform": "^1.3.6", + "pusher-js": "^7.0.3", + "readline": "^1.3.0", "readline-sync": "^1.4.10", - "shelljs": "^0.8.3", - "url": "^0.11.0", - "vorpal": "^1.12.0" + "shelljs": "^0.8.4" + }, + "devDependencies": { + "@oclif/dev-cli": "^1.26.0", + "eslint": "^8.9.0", + "eslint-config-oclif": "^3.1.0", + "globby": "^10.0.2" + }, + "engines": { + "node": ">=8.0.0" + }, + "files": [ + "/bin", + "/npm-shrinkwrap.json", + "/oclif.manifest.json", + "/src" + ], + "homepage": "https://github.com/PaystackOSS/paystack-cli", + "keywords": [ + "paystack", + "oclif" + ], + "license": "MIT", + "main": "src/index.js", + "oclif": { + "macos": { + "identifier": "com.paystack.cli", + "sign": "Developer ID Installer: Paystack Payments Limited (A2JLN3TYKB)" + }, + "update": { + "s3": { + "host": "https://public-paystack-cli.s3.eu-west-1.amazonaws.com", + "bucket": "public-paystack-cli" + } + }, + "commands": "./src/commands", + "topicSeparator": " ", + "additionalHelpFlags": [ + "-h" + ], + "additionalVersionFlags": [ + "-v" + ], + "bin": "paystack", + "plugins": [ + "@oclif/plugin-help", + "@oclif/plugin-update", + "@oclif/plugin-not-found", + "@oclif/plugin-autocomplete", + "@oclif/plugin-version" + ] + }, + "repository": "PaystackOSS/paystack-cli", + "scripts": { + "postpack": "rm -f oclif.manifest.json", + "posttest": "eslint .", + "prepack": "oclif-dev manifest && oclif-dev readme", + "test": "echo NO TESTS", + "version": "oclif-dev readme && git add README.md" } } diff --git a/public/index.html b/public/index.html deleted file mode 100644 index ab1ad8a..0000000 --- a/public/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - Express - - - - -

Express

-

Welcome to Express

- - - diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css deleted file mode 100644 index 9453385..0000000 --- a/public/stylesheets/style.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; -} - -a { - color: #00B7FF; -} diff --git a/readme.md b/readme.md index 09b83e2..ab6105e 100644 --- a/readme.md +++ b/readme.md @@ -1,130 +1,232 @@ -# dev-cli + [![Paystack Logo](https://res.cloudinary.com/drps6uoe4/image/upload/c_scale,w_200/v1584835701/Paystack-CeruleanBlue-StackBlue-HL_2_neik7g.png)](https://paystack.com) -The Paystack CLI helps you build, test, and manage your Paystack integration right from the terminal. +# Paystack CLI -With the Paystack CLI, you can: -Securely test webhooks without relying on third-party tunneling software -Trigger webhook events to easily test your integration -Create, retrieve, update, and delete API objects -Clone real life sample applications with fully integrated payment channels. +## About +As a developer, your most powerful tools - from basic bash commands, to version control and deployment tools - sit in your terminal. The Paystack CLI to makes it easier to set up, test, and manage your Paystack integrations right from that very same terminal. -And of course the Paystack CLI is open source with a [public repository](https://github.com/lukman-paystack/paystack-cli) - on GitHub. Contributions, features, sample apps from developers are encouraged. +With the CLI, you can: -## Installation +1. Ping your preset webhook URL with sample event data +2. Tunnel Paystack events directly to your local server without installing third party software +3. Set up sample applications with fully integrated payment channels +4. Interact with Paystack API +5. *Interpret Paystack API Errors* -Paystack requires [Node.js](https://nodejs.org/) v8+ to run. +## Installing the Paystack CLI -Install the dependencies and devDependencies and start the instance. +### Install with npm -```sh -$ npm install -g @paystack-oss/dev-cli -$ paystack-cli -$ login -``` +Paystack requires **[Node.js](https://nodejs.org/)** v16+ to run, To install with npm, run -## Get started +`$ npm install -g @paystack-oss/dev-cli` -### API +## Verify your installation -Paystack CLI allows you to make API calls to the Paystack API right from the terminal, for example to initialize a transaction, run +Check that your installation was successful by running -```sh -$ transaction initialize --amount 1000 --email customer@email.com -``` -The terminal's output would look like this +`$ paystack --version` -```sh -authorization_url - - - -- - -- - - - - - - - - - - - https://checkout.paystack.com/9wvzhxlk66uylzp -access_code - - - -- - -- - - - - - - - - - - - 9wvzhxlk66uylzp -reference - - - -- - -- - - - - - - - - - - - se8b1ty80b -``` +The output should look like -#### Another example +`> @paystack-oss/dev-cli/1.0.0-nightly.0 darwin-x64 node-v16.14.0` -```sh -$ transaction verify --reference T394541625653843 --domain live -``` +## Getting started with the Paystack CLI -#### output -```sh -id - - - -- - -- - - - - - - - - - - - 521587687 -domain - - - -- - -- - - - - - - - - - - - live -status - - - -- - -- - - - - - - - - - - - success -reference - - - -- - -- - - - - - - - - - - - T394541625653843 -amount - - - -- - -- - - - - - - - - - - - 100000 -gateway_response - - - -- - -- - - - - - - - - - - - Approved -paid_at - - - -- - -- - - - - - - - - - - - 2020-02-27T17:28:14.000Z -created_at - - - -- - -- - - - - - - - - - - - 2020-02-27T17:27:31.000Z -channel - - - -- - -- - - - - - - - - - - - card -currency - - - -- - -- - - - - - - - - - - - NGN -ip_address - - - -- - -- - - - - - - - - - - - 102.67.15.8 -fees - - - -- - -- - - - - - - - - - - - 1500 -plan - - - -- - -- - - - - - - - - - - - PLN_q34mm97ac7pnqj1 -paidAt - - - -- - -- - - - - - - - - - - - 2020-02-27T17:28:14.000Z -createdAt - - - -- - -- - - - - - - - - - - - 2020-02-27T17:27:31.000Z -requested_amount - - - -- - -- - - - - - - - - - - - 100000 -transaction_date - - - -- - -- - - - - - - - - - - - 2020-02-27T17:27:31.000Z +Now that you’re all setup, to access your Paystack account and execute commands, run -``` +`$ paystack login` +You’ll be required to enter your credentials and choose the business you want to execute commands on its behalf. -### Webhook -You can tunnel Paystack webhook events directly to your localhost without any third party software directly from your terminal +### Commands -``` - $ webhook listen localhost:8995/pay/pstk-webhook?country=ng -``` +Run `$ paystack —help` to see a list of all commands you can use on the CLI. By default, all commands are run in test mode. To switch to live, append *`--domain live`* to the end of your command. -#### output +Read on for more information on what you can do with the CLI. -```sh -> Tunelling webhook events to localhost:8995/pay/pstk-webhook?country=ng -> Webhook events would now be received at localhost:8995/pay/pstk-webhook?country=ng -``` -NOTE - This command is only avalaible in test mode, and by using this command, the CLI would automatically make changes to the Test Webhook URL set on your Paystack dashboard. +### Manage Webhooks -You can also run an health check on your live/test webhook endpoint from your terminal +Whenever actions are carried out on your Paystack account, we trigger events which your application can listen and respond to. Before now, to implement webhook routes like these, you had to: -```sh -$ webhook ping --domain live -``` +1. Ping your preset webhook URL with sample event data +2. Login to your Paystack Dashboard and set the webhook URL +3. Make a test payment or transfer +4. Review logs +5. Repeat + +The CLI lets you listen to real-time webhook events on your integration and reduces all these steps are reduced to running a single command — + +`$ paystack webhook listen localhost:8080/webhook` + +This command tunnels all your test webhook events to your local server running on port 8080, making it possible for you to run end-to-end tests on your Paystack integration while in development mode. + +You can also run health checks on your webhook URL by sending a sample webhook payload to your server. To do this, run: -#### output -```sh -- - - - - - - - - - - - - - - - - - -- -- - - - - - - -Sending sample charge.success event payload to https://paycash.pstk.xyz/pay/pstk-webhook?country=ng -401 - - Unauthorized -Unauthorized +`$ paystack webhook ping --event transfer.success --domain test` + Check our [documentation](https://paystack.com/docs/payments/webhooks/#supported-events) for a list of supported events. + +### Use Sample Apps + +We’ve built several sample apps showcasing different use cases and how to integrate Paystack with different programming languages. + +You can set up any of the sample apps on your local machine — To do this, run: + +`$ paystack sample sample_react ~/Work/Desktop` + +### Interact with Paystack APIs + +All Paystack public API endpoints are accessible via the Paystack CLI, and you can try out different API calls from the terminal before you start integrating. In this guide, you’ll learn how to + +1. Initialize a transaction and get a checkout URL. +2. Verify a transaction +3. Charge a saved card. + +First, we’ll call the [Initialize Transaction **API](https://paystack.com/docs/api#transaction-initialize)** to generate a checkout link. The command to do this is + +```bash + $ paystack transaction initialize --email customer@email.com --amount 10000 \ + --callback_url https://paystack.com/docs ``` +Your output should look like this -### Sample Apps -We have built different sample apps and embedded them in the CLI, you can setup a sample project in your terminal by running +```bash +Authorization URL created +{ + authorization_url: 'https://checkout.paystack.com/sf69sk0l6d5iuqm', + access_code: 'sf69sk0l6d5iuqm', + reference: 'kpu5vxesc5' +} +``` -```sh -$ sample sample-react "~/Desktop/Work" +Great! We’ve created the transaction and can grab the `authorization_url` from the terminal and open it in a browser to complete the transaction. + +Now that’s done, let’s verify the transaction by running + +`$ paystack transaction verify --reference kpu5vxesc5` + +Your output should look like this + +```bash +Verification successful +{ + id: 1693453689, + domain: 'test', + status: 'success', + reference: 'kpu5vxesc5', + amount: 10000, + metadata: '', + log: { + ... + }, + fees: 150, + authorization: { + authorization_code: 'AUTH_5uy1wm1940', + bin: '408408', + last4: '4081', + exp_month: '12', + exp_year: '2030', + channel: 'card', + card_type: 'visa ', + bank: 'TEST BANK', + country_code: 'NG', + brand: 'visa', + reusable: true, + signature: 'SIG_oIPc9Xyv8RuejFCaUi4i', + account_name: null + }, + customer: { + ... + email: 'customer@email.com', + customer_code: 'CUS_gnguwml5r732p7y', + ... + }, + plan: null, + split: {}, + order_id: null, + paidAt: '2022-03-18T14:56:20.000Z', + createdAt: '2022-03-18T14:54:51.000Z', + requested_amount: 10000, + ... +} ``` -### Development +So far, so good! Now one more thing, we want to recurringly charge the card that was used for this transaction. To do that, we’ll need the customer’s email and authorization code from the verify transaction response. Grab those from ***customer.email*** and **authorization.authorization_code** in the JSON response respectively. -Want to contribute? Great! +The command to run will be: +```bash +$ paystack transaction charge_authorization --email customer@email.com \ -By default, all commands are run in test mode, to switch to live, append the flag *"--domain live"* at the end of your command +--authorization_code AUTH_5uy1wm1940 --amount 1000 +``` +Output from this command should look like + +```bash +Charge attempted +{ + amount: 10000, + currency: 'NGN', + transaction_date: '2022-03-21T15:25:01.000Z', + status: 'success', + reference: 'h5ijyl88fau8b1l', + domain: 'test', + metadata: '', + gateway_response: 'Approved', + message: null, + channel: 'card', + ip_address: null, + log: null, + fees: 150, + authorization: { + authorization_code: 'AUTH_5uy1wm1940', + bin: '408408', + last4: '4081', + exp_month: '12', + exp_year: '2030', + channel: 'card', + card_type: 'visa ', + bank: 'TEST BANK', + country_code: 'NG', + brand: 'visa', + reusable: true, + signature: 'SIG_oIPc9Xyv8RuejFCaUi4i', + account_name: null + }, + customer: { + id: 8072602, + first_name: null, + last_name: null, + email: 'customer@email.com', + customer_code: 'CUS_gnguwml5r732p7y', + phone: null, + metadata: null, + risk_action: 'deny', + international_format_phone: null + }, + plan: null, + id: 1700095471 +} +``` +... and boom! we’re done. +You can test out all other public endpoints from the CLI. Request body and query parameters should be passed as flags to the command, for example, the Create Customer API requires and `email` param, and optional `phone`, `first_name` and `last_name` params, we can represent this as a command line argument in the following format: -License ----- +```bash +$ paystack customer create --email customer@email.com --first_name Jane --last_name Doe +``` -MIT +Use our API reference to check the required parameters for any of the endpoints. +## Uninstall the CLI +`$ npm uninstall -g @paystack-oss/dev-cli` \ No newline at end of file diff --git a/release/homebrew.js b/release/homebrew.js new file mode 100644 index 0000000..95e392f --- /dev/null +++ b/release/homebrew.js @@ -0,0 +1,157 @@ +#!/usr/bin/env node + +const fs = require('fs') +const execa = require('execa') +const https = require('https') +const path = require('path') +const rm = require('rimraf') +const mkdirp = require('mkdirp') +const { promisify } = require('util') +const { pipeline } = require('stream') +const crypto = require('crypto') + +const NODE_JS_BASE = 'https://nodejs.org/download/release' +const CLI_DIR = path.join(__dirname, '..', '..', 'packages', 'cli') +const DIST_DIR = path.join(CLI_DIR, 'dist') +const PJSON = require(path.join(CLI_DIR, 'package.json')) +const NODE_VERSION = PJSON.oclif.update.node.version +const SHORT_VERSION = PJSON.version + +async function getText (url) { + return new Promise((resolve, reject) => { + https.get(url, (res) => { + let buffer = [] + + res.on('data', (buf) => { + buffer.push(buf) + }) + + res.on('close', () => { + resolve(Buffer.concat(buffer).toString('utf-8')) + }) + }).on('error', reject) + }) +} + +async function getDownloadInfoForNodeVersion (version) { + // https://nodejs.org/download/release/v12.21.0/SHASUMS256.txt + const url = `${NODE_JS_BASE}/v${version}/SHASUMS256.txt` + const shasums = await getText(url) + const shasumLine = shasums.split('\n').find((line) => { + return line.includes(`node-v${version}-darwin-x64.tar.xz`) + }) + + if (!shasumLine) { + throw new Error(`could not find matching shasum for ${version}`) + } + + const [shasum, filename] = shasumLine.trim().split(/\s+/) + return { + url: `${NODE_JS_BASE}/v${version}/${filename}`, + sha256: shasum + } +} + +if (!process.env.CIRCLE_TAG) { + console.log('Not on stable release; skipping releasing homebrew') + process.exit(0) +} + +async function calculateSHA256 (fileName) { + const hash = crypto.createHash('sha256') + hash.setEncoding('hex') + await promisify(pipeline)(fs.createReadStream(fileName), hash) + return hash.read() +} + +const ROOT = path.join(__dirname, 'homebrew') +const TEMPLATES = path.join(ROOT, 'templates') + +const CLI_ASSETS_URL = process.env.CLI_ASSETS_URL || 'https://cli-assets.heroku.com' + +async function updateHerokuFormula (brewDir) { + const templatePath = path.join(TEMPLATES, 'heroku.rb') + const template = fs.readFileSync(templatePath).toString('utf-8') + + const pathToDist = path.join(DIST_DIR, `heroku-v${SHORT_VERSION}`, `heroku-v${SHORT_VERSION}.tar.xz`) + const sha256 = await calculateSHA256(pathToDist) + const url = `${CLI_ASSETS_URL}/heroku-v${SHORT_VERSION}/heroku-v${SHORT_VERSION}.tar.xz` + + const templateReplaced = + template + .replace('__CLI_DOWNLOAD_URL__', url) + .replace('__CLI_SHA256__', sha256) + .replace('__NODE_VERSION__', NODE_VERSION) + + fs.writeFileSync(path.join(brewDir, 'Formula', 'heroku.rb'), templateReplaced) +} + +async function updateHerokuNodeFormula (brewDir) { + const formulaPath = path.join(brewDir, 'Formula', 'heroku-node.rb') + + console.log(`updating heroku-node Formula in ${formulaPath}`) + console.log(`getting SHA and URL for Node.js version ${NODE_VERSION}`) + + const { url, sha256 } = await getDownloadInfoForNodeVersion(NODE_VERSION) + + console.log(`done getting SHA for Node.js version ${NODE_VERSION}: ${sha256}`) + console.log(`done getting URL for Node.js version ${NODE_VERSION}: ${url}`) + + const templatePath = path.join(TEMPLATES, 'heroku-node.rb') + const template = fs.readFileSync(templatePath).toString('utf-8') + + const templateReplaced = + template + .replace('__NODE_BIN_URL__', url) + .replace('__NODE_SHA256__', sha256) + .replace('__NODE_VERSION__', NODE_VERSION) + + fs.writeFileSync(formulaPath, templateReplaced) + console.log(`done updating heroku-node Formula in ${formulaPath}`) +} + +async function setupGit () { + const githubSetupPath = path.join(__dirname, '..', 'utils', '_github_setup') + await execa(githubSetupPath) +} + +async function updateHomebrew () { + const tmp = path.join(__dirname, 'tmp') + const homebrewDir = path.join(tmp, 'homebrew-brew') + mkdirp.sync(tmp) + rm.sync(homebrewDir) + + await setupGit() + + console.log(`cloning https://github.com/heroku/homebrew-brew to ${homebrewDir}`) + await execa('git', + [ + 'clone', + 'git@github.com:heroku/homebrew-brew.git', + homebrewDir + ] + ) + console.log(`done cloning heroku/homebrew-brew to ${homebrewDir}`) + + console.log('updating local git...') + await updateHerokuNodeFormula(homebrewDir) + await updateHerokuFormula(homebrewDir) + + // run in git in cloned heroku/homebrew-brew git directory + const git = async (args, opts = {}) => { + await execa('git', ['-C', homebrewDir, ...args], opts) + } + + await git(['add', 'Formula']) + await git(['config', '--local', 'core.pager', 'cat']) + await git(['diff', '--cached'], { stdio: 'inherit' }) + await git(['commit', '-m', `heroku v${SHORT_VERSION}`]) + if (process.env.SKIP_GIT_PUSH === undefined) { + await git(['push', 'origin', 'master']) + } +} + +updateHomebrew().catch((err) => { + console.error(`error running scripts/release/homebrew.js`, err) + process.exit(1) +}) \ No newline at end of file diff --git a/release/paystack.rb b/release/paystack.rb new file mode 100644 index 0000000..3af5f68 --- /dev/null +++ b/release/paystack.rb @@ -0,0 +1,33 @@ +# Documentation: https://docs.brew.sh/Formula-Cookbook +# https://rubydoc.brew.sh/Formula +# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST! +class PaystackV100Nightly0B83d862DarwinX < Formula + desc "" + homepage "" + url "https://public-paystack-cli.s3.eu-west-1.amazonaws.com/versions/1.0.0-nightly.0/b83d862/paystack-v1.0.0-nightly.0-b83d862-darwin-x64.tar.gz" + sha256 "b32e4ee30ce9525f6eb4ccfa0b6dc2b2d607ed0e390c7378f365d8c009e965d2" + license "" + + # depends_on "cmake" => :build + + def install + # ENV.deparallelize # if your formula fails when building in parallel + # Remove unrecognized options if warned by configure + # https://rubydoc.brew.sh/Formula.html#std_configure_args-instance_method + system "./configure", *std_configure_args, "--disable-silent-rules" + # system "cmake", "-S", ".", "-B", "build", *std_cmake_args + end + + test do + # `test do` will create, run in and delete a temporary directory. + # + # This test will fail and we won't accept that! For Homebrew/homebrew-core + # this will need to be a test that verifies the functionality of the + # software. Run the test with `brew test paystack-v1.0.0-nightly.0-b83d862-darwin-x`. Options passed + # to `brew install` such as `--HEAD` also need to be provided to `brew test`. + # + # The installed folder is not in the path, so use the entire path to any + # executables being tested: `system "#{bin}/program", "do", "something"`. + system "false" + end + end \ No newline at end of file diff --git a/release/release.md b/release/release.md new file mode 100644 index 0000000..b604554 --- /dev/null +++ b/release/release.md @@ -0,0 +1,8 @@ +Formula name [paystack]: +Warning: Version cannot be determined from URL. +You'll need to add an explicit 'version' to the formula. +Please run `brew audit --new paystack` before submitting, thanks. +Editing /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/paystack.rb +Warning: Using vim because no editor was set in the environment. +This may change in the future, so we recommend setting EDITOR, +or HOMEBREW_EDITOR to your preferred text editor. \ No newline at end of file diff --git a/src/commands/.DS_Store b/src/commands/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/src/commands/.DS_Store differ diff --git a/src/commands/avs.js b/src/commands/avs.js new file mode 100644 index 0000000..438fe00 --- /dev/null +++ b/src/commands/avs.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'avs'; +let API = APIs[key]; +class AvsCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(AvsCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'avs'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +AvsCommand.description = helpers.getDescription(API, key) + +AvsCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + AvsCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + AvsCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + AvsCommand.flags[param.parameter] = Flags.boolean() + break + default: + AvsCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + AvsCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +AvsCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = AvsCommand; diff --git a/src/commands/balance.js b/src/commands/balance.js new file mode 100644 index 0000000..648a7fa --- /dev/null +++ b/src/commands/balance.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'balance'; +let API = APIs[key]; +class BalanceCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(BalanceCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'balance'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +BalanceCommand.description = helpers.getDescription(API, key) + +BalanceCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + BalanceCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + BalanceCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + BalanceCommand.flags[param.parameter] = Flags.boolean() + break + default: + BalanceCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + BalanceCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +BalanceCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = BalanceCommand; diff --git a/src/commands/bank.js b/src/commands/bank.js new file mode 100644 index 0000000..786dacb --- /dev/null +++ b/src/commands/bank.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'bank'; +let API = APIs[key]; +class BankCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(BankCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'bank'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +BankCommand.description = helpers.getDescription(API, key) + +BankCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + BankCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + BankCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + BankCommand.flags[param.parameter] = Flags.boolean() + break + default: + BankCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + BankCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +BankCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = BankCommand; diff --git a/src/commands/bulkcharge.js b/src/commands/bulkcharge.js new file mode 100644 index 0000000..d7c7e50 --- /dev/null +++ b/src/commands/bulkcharge.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'bulkcharge'; +let API = APIs[key]; +class BulkchargeCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(BulkchargeCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'bulkcharge'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +BulkchargeCommand.description = helpers.getDescription(API, key) + +BulkchargeCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + BulkchargeCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + BulkchargeCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + BulkchargeCommand.flags[param.parameter] = Flags.boolean() + break + default: + BulkchargeCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + BulkchargeCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +BulkchargeCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = BulkchargeCommand; diff --git a/src/commands/card.js b/src/commands/card.js new file mode 100644 index 0000000..ec1e890 --- /dev/null +++ b/src/commands/card.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'card'; +let API = APIs[key]; +class CardCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(CardCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'card'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +CardCommand.description = helpers.getDescription(API, key) + +CardCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + CardCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + CardCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + CardCommand.flags[param.parameter] = Flags.boolean() + break + default: + CardCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + CardCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +CardCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = CardCommand; diff --git a/src/commands/charge.js b/src/commands/charge.js new file mode 100644 index 0000000..f29669d --- /dev/null +++ b/src/commands/charge.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'charge'; +let API = APIs[key]; +class ChargeCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(ChargeCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'charge'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +ChargeCommand.description = helpers.getDescription(API, key) + +ChargeCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + ChargeCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + ChargeCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + ChargeCommand.flags[param.parameter] = Flags.boolean() + break + default: + ChargeCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + ChargeCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +ChargeCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = ChargeCommand; diff --git a/src/commands/country.js b/src/commands/country.js new file mode 100644 index 0000000..d384a07 --- /dev/null +++ b/src/commands/country.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'country'; +let API = APIs[key]; +class CountryCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(CountryCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'country'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +CountryCommand.description = helpers.getDescription(API, key) + +CountryCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + CountryCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + CountryCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + CountryCommand.flags[param.parameter] = Flags.boolean() + break + default: + CountryCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + CountryCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +CountryCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = CountryCommand; diff --git a/src/commands/customer.js b/src/commands/customer.js new file mode 100644 index 0000000..1f4bf3b --- /dev/null +++ b/src/commands/customer.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'customer'; +let API = APIs[key]; +class CustomerCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(CustomerCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'customer'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +CustomerCommand.description = helpers.getDescription(API, key) + +CustomerCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + CustomerCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + CustomerCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + CustomerCommand.flags[param.parameter] = Flags.boolean() + break + default: + CustomerCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + CustomerCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +CustomerCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = CustomerCommand; diff --git a/src/commands/dedicatedaccount.js b/src/commands/dedicatedaccount.js new file mode 100644 index 0000000..95f1669 --- /dev/null +++ b/src/commands/dedicatedaccount.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'dedicatedaccount'; +let API = APIs[key]; +class DedicatedaccountCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(DedicatedaccountCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'dedicatedaccount'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +DedicatedaccountCommand.description = helpers.getDescription(API, key) + +DedicatedaccountCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + DedicatedaccountCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + DedicatedaccountCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + DedicatedaccountCommand.flags[param.parameter] = Flags.boolean() + break + default: + DedicatedaccountCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + DedicatedaccountCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +DedicatedaccountCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = DedicatedaccountCommand; diff --git a/src/commands/dispute.js b/src/commands/dispute.js new file mode 100644 index 0000000..bff57a8 --- /dev/null +++ b/src/commands/dispute.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'dispute'; +let API = APIs[key]; +class DisputeCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(DisputeCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'dispute'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +DisputeCommand.description = helpers.getDescription(API, key) + +DisputeCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + DisputeCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + DisputeCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + DisputeCommand.flags[param.parameter] = Flags.boolean() + break + default: + DisputeCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + DisputeCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +DisputeCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = DisputeCommand; diff --git a/src/commands/identity.js b/src/commands/identity.js new file mode 100644 index 0000000..53e3a09 --- /dev/null +++ b/src/commands/identity.js @@ -0,0 +1,74 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/apis') +const db = require('../lib/db') +let key = 'identity'; +let API = APIs[key]; +class IdentityCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(IdentityCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'identity'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +IdentityCommand.description = helpers.getDescription(API, key) + +IdentityCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + IdentityCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + IdentityCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + IdentityCommand.flags[param.parameter] = Flags.boolean() + break + default: + IdentityCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) +}) +IdentityCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = IdentityCommand; + + diff --git a/src/commands/integration.js b/src/commands/integration.js new file mode 100644 index 0000000..3dd18f9 --- /dev/null +++ b/src/commands/integration.js @@ -0,0 +1,74 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/apis') +const db = require('../lib/db') +let key = 'integration'; +let API = APIs[key]; +class IntegrationCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(IntegrationCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'integration'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +IntegrationCommand.description = helpers.getDescription(API, key) + +IntegrationCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + IntegrationCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + IntegrationCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + IntegrationCommand.flags[param.parameter] = Flags.boolean() + break + default: + IntegrationCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) +}) +IntegrationCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = IntegrationCommand; + + diff --git a/src/commands/invoice.js b/src/commands/invoice.js new file mode 100644 index 0000000..9c8619d --- /dev/null +++ b/src/commands/invoice.js @@ -0,0 +1,74 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/apis') +const db = require('../lib/db') +let key = 'invoice'; +let API = APIs[key]; +class InvoiceCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(InvoiceCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'invoice'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +InvoiceCommand.description = helpers.getDescription(API, key) + +InvoiceCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + InvoiceCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + InvoiceCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + InvoiceCommand.flags[param.parameter] = Flags.boolean() + break + default: + InvoiceCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) +}) +InvoiceCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = InvoiceCommand; + + diff --git a/src/commands/login.js b/src/commands/login.js new file mode 100644 index 0000000..e18876a --- /dev/null +++ b/src/commands/login.js @@ -0,0 +1,80 @@ +/* eslint-disable no-redeclare */ +/* eslint-disable camelcase */ +/** global db **/ +const {Command} = require('@oclif/core') +const db = require('../lib/db') +const shell = require('shelljs') +if (!shell.which('git')) { + shell.echo('Sorry, this script requires git') + shell.exit(1) +} +const helpers = require('../lib/helpers') +const Paystack = require('../lib/paystack') + +class LoginClass extends Command { + async run() { + let token = '' + let e + let response + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + let user + if (expiry > now) { + token = db.read('token') + user = db.read('user') + helpers.successLog("You're already logged in") + } else { + var email = helpers.prompt('Email address\n') + let password = helpers.prompt('Password\n', true); + [e, response] = await helpers.promiseWrapper(Paystack.signIn(email, password)) + if (e) { + this.error(e) + } + if (response && !response.mfa_required) { + ({token, expiry, user} = response) + db.write('token', token) + db.write('user', user) + db.write('token_expiry', expiry) + helpers.successLog('Login successful') + } else if (response.mfa_required) { + helpers.infoLog('MFA required') + let mfa_code = helpers.prompt('Enter the 6-digit verification code generated by your authenticator app\n'); + [e, response] = await helpers.promiseWrapper(Paystack.verifyToken(mfa_code, response.token)) + if (response) { + ({token, expiry, user} = response) + db.write('token', token) + db.write('user', user) + db.write('token_expiry', expiry) + helpers.successLog('Login successful') + } else { + this.error('Login failed' + JSON.stringify(e) + JSON.stringify(response)) + } + } else { + this.error('Login failed' + JSON.stringify(e) + JSON.stringify(response)) + } + } + if (response || (token && user)) { + var [err, integration] = await helpers.promiseWrapper(Paystack.selectIntegration(user.integrations, token)) + if (err) { + this.error(err) + } + db.write('selected_integration', integration) + let user_role = db.read('selected_integration.logged_in_user_role') + var [err, integrationData] = await helpers.promiseWrapper(Paystack.getIntegration(integration.id, token)) + if (err) { + this.error(err) + return + } + integrationData.logged_in_user_role = user_role + db.write('selected_integration', integrationData) + + helpers.infoLog('Logged in as ' + user.email + ' - ' + integration.business_name + ' (' + integration.id + ')') + } else { + this.error(' - - - - - - ') + } + } +} + +LoginClass.description = 'Sign in to the CLI' + +module.exports = LoginClass diff --git a/src/commands/logout.js b/src/commands/logout.js new file mode 100644 index 0000000..aa6b60d --- /dev/null +++ b/src/commands/logout.js @@ -0,0 +1,12 @@ +const {Command} = require('@oclif/core') +const db = require('../lib/db'); +class LogoutCommand extends Command { + async run() { + db.clear(); + this.log("Logged out successfully") + } +} + +LogoutCommand.description = 'Log out of the CLI' + +module.exports = LogoutCommand \ No newline at end of file diff --git a/src/commands/open.js b/src/commands/open.js new file mode 100644 index 0000000..0f5aa63 --- /dev/null +++ b/src/commands/open.js @@ -0,0 +1,32 @@ +const { Command } = require('@oclif/core') +const open = require('open'); +class OpenCommand extends Command { + async run() { + const { args } = await this.parse(OpenCommand) + let page = args.page.toLowerCase(); + switch (page) { + case 'api': + open("https://paystack.com/docs/api/"); + break; + case 'docs': + open("https://paystack.com/docs/"); + break; + case 'documentation': + open("https://paystack.com/docs/"); + break; + case 'dashboard': + open("https://dashboard.paystack.com/"); + break; + default: + this.log(`Unrecognized argument ${page}`) + break; + } + } +} + +OpenCommand.description = 'Open Paystack docs, API reference or dashboard' +OpenCommand.args = [ + { name: 'page' } +] + +module.exports = OpenCommand \ No newline at end of file diff --git a/src/commands/page.js b/src/commands/page.js new file mode 100644 index 0000000..eae1d51 --- /dev/null +++ b/src/commands/page.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'page'; +let API = APIs[key]; +class PageCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(PageCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'page'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +PageCommand.description = helpers.getDescription(API, key) + +PageCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + PageCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + PageCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + PageCommand.flags[param.parameter] = Flags.boolean() + break + default: + PageCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + PageCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +PageCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = PageCommand; diff --git a/src/commands/paymentrequest.js b/src/commands/paymentrequest.js new file mode 100644 index 0000000..9cd01c0 --- /dev/null +++ b/src/commands/paymentrequest.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'paymentrequest'; +let API = APIs[key]; +class PaymentrequestCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(PaymentrequestCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'paymentrequest'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +PaymentrequestCommand.description = helpers.getDescription(API, key) + +PaymentrequestCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + PaymentrequestCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + PaymentrequestCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + PaymentrequestCommand.flags[param.parameter] = Flags.boolean() + break + default: + PaymentrequestCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + PaymentrequestCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +PaymentrequestCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = PaymentrequestCommand; diff --git a/src/commands/paymentsessiontimeout.js b/src/commands/paymentsessiontimeout.js new file mode 100644 index 0000000..c9f946c --- /dev/null +++ b/src/commands/paymentsessiontimeout.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'paymentsessiontimeout'; +let API = APIs[key]; +class PaymentsessiontimeoutCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(PaymentsessiontimeoutCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'paymentsessiontimeout'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +PaymentsessiontimeoutCommand.description = helpers.getDescription(API, key) + +PaymentsessiontimeoutCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + PaymentsessiontimeoutCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + PaymentsessiontimeoutCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + PaymentsessiontimeoutCommand.flags[param.parameter] = Flags.boolean() + break + default: + PaymentsessiontimeoutCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + PaymentsessiontimeoutCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +PaymentsessiontimeoutCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = PaymentsessiontimeoutCommand; diff --git a/src/commands/plan.js b/src/commands/plan.js new file mode 100644 index 0000000..26dcad0 --- /dev/null +++ b/src/commands/plan.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'plan'; +let API = APIs[key]; +class PlanCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(PlanCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'plan'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +PlanCommand.description = helpers.getDescription(API, key) + +PlanCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + PlanCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + PlanCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + PlanCommand.flags[param.parameter] = Flags.boolean() + break + default: + PlanCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + PlanCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +PlanCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = PlanCommand; diff --git a/src/commands/product.js b/src/commands/product.js new file mode 100644 index 0000000..12d97fd --- /dev/null +++ b/src/commands/product.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'product'; +let API = APIs[key]; +class ProductCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(ProductCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'product'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +ProductCommand.description = helpers.getDescription(API, key) + +ProductCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + ProductCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + ProductCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + ProductCommand.flags[param.parameter] = Flags.boolean() + break + default: + ProductCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + ProductCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +ProductCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = ProductCommand; diff --git a/src/commands/refund.js b/src/commands/refund.js new file mode 100644 index 0000000..f166e03 --- /dev/null +++ b/src/commands/refund.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'refund'; +let API = APIs[key]; +class RefundCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(RefundCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'refund'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +RefundCommand.description = helpers.getDescription(API, key) + +RefundCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + RefundCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + RefundCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + RefundCommand.flags[param.parameter] = Flags.boolean() + break + default: + RefundCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + RefundCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +RefundCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = RefundCommand; diff --git a/src/commands/sample.js b/src/commands/sample.js new file mode 100644 index 0000000..5871eed --- /dev/null +++ b/src/commands/sample.js @@ -0,0 +1,32 @@ +const {Command} = require('@oclif/core') +const shell = require('shelljs') +if (!shell.which('git')) { + shell.echo('Sorry, this script requires git') + shell.exit(1) +} + +let samples = require('../lib/samples') + +class SampleCommand extends Command { + async run() { + const {args} = await this.parse(SampleCommand) + let keys = Object.keys(samples) + if (keys.indexOf(args.sample) < 0) { + this.error('No sample app available with the name ' + args.sample + ', available samples are ' + keys.join(', ')) + } + let sample = samples[args.sample] + + shell.cd(args.filepath) + shell.exec('git clone ' + sample.git) + shell.cd(sample.name) + shell.exec('npm install') + shell.exec('npm start') + } +} +let keys = Object.keys(samples) +SampleCommand.description = 'Get started quickly with a Paystack sample project. Available samples are ' + keys.toString() +SampleCommand.args = [ + {name: 'sample'}, + {name: 'filepath'}, +] +module.exports = SampleCommand diff --git a/src/commands/settlement.js b/src/commands/settlement.js new file mode 100644 index 0000000..0998c7f --- /dev/null +++ b/src/commands/settlement.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'settlement'; +let API = APIs[key]; +class SettlementCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(SettlementCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'settlement'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +SettlementCommand.description = helpers.getDescription(API, key) + +SettlementCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + SettlementCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + SettlementCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + SettlementCommand.flags[param.parameter] = Flags.boolean() + break + default: + SettlementCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + SettlementCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +SettlementCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = SettlementCommand; diff --git a/src/commands/split.js b/src/commands/split.js new file mode 100644 index 0000000..8b67931 --- /dev/null +++ b/src/commands/split.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'split'; +let API = APIs[key]; +class SplitCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(SplitCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'split'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +SplitCommand.description = helpers.getDescription(API, key) + +SplitCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + SplitCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + SplitCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + SplitCommand.flags[param.parameter] = Flags.boolean() + break + default: + SplitCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + SplitCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +SplitCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = SplitCommand; diff --git a/src/commands/subaccount.js b/src/commands/subaccount.js new file mode 100644 index 0000000..6e1f8a0 --- /dev/null +++ b/src/commands/subaccount.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'subaccount'; +let API = APIs[key]; +class SubaccountCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(SubaccountCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'subaccount'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +SubaccountCommand.description = helpers.getDescription(API, key) + +SubaccountCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + SubaccountCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + SubaccountCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + SubaccountCommand.flags[param.parameter] = Flags.boolean() + break + default: + SubaccountCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + SubaccountCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +SubaccountCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = SubaccountCommand; diff --git a/src/commands/subscription.js b/src/commands/subscription.js new file mode 100644 index 0000000..f1bc459 --- /dev/null +++ b/src/commands/subscription.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'subscription'; +let API = APIs[key]; +class SubscriptionCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(SubscriptionCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'subscription'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +SubscriptionCommand.description = helpers.getDescription(API, key) + +SubscriptionCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + SubscriptionCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + SubscriptionCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + SubscriptionCommand.flags[param.parameter] = Flags.boolean() + break + default: + SubscriptionCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + SubscriptionCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +SubscriptionCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = SubscriptionCommand; diff --git a/src/commands/transaction.js b/src/commands/transaction.js new file mode 100644 index 0000000..91e41c2 --- /dev/null +++ b/src/commands/transaction.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'transaction'; +let API = APIs[key]; +class TransactionCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(TransactionCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'transaction'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +TransactionCommand.description = helpers.getDescription(API, key) + +TransactionCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + TransactionCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + TransactionCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + TransactionCommand.flags[param.parameter] = Flags.boolean() + break + default: + TransactionCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + TransactionCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +TransactionCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = TransactionCommand; diff --git a/src/commands/transfer.js b/src/commands/transfer.js new file mode 100644 index 0000000..4bdd0d8 --- /dev/null +++ b/src/commands/transfer.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'transfer'; +let API = APIs[key]; +class TransferCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(TransferCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'transfer'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +TransferCommand.description = helpers.getDescription(API, key) + +TransferCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + TransferCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + TransferCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + TransferCommand.flags[param.parameter] = Flags.boolean() + break + default: + TransferCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + TransferCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +TransferCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = TransferCommand; diff --git a/src/commands/transferrecipient.js b/src/commands/transferrecipient.js new file mode 100644 index 0000000..86c85d4 --- /dev/null +++ b/src/commands/transferrecipient.js @@ -0,0 +1,92 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/APIs.json') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') +let key = 'transferrecipient'; +let API = APIs[key]; +class TransferrecipientCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(TransferrecipientCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'transferrecipient'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +TransferrecipientCommand.description = helpers.getDescription(API, key) + +TransferrecipientCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + TransferrecipientCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + TransferrecipientCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + TransferrecipientCommand.flags[param.parameter] = Flags.boolean() + break + default: + TransferrecipientCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) + if(path.variables){ + path.variables.forEach((variable)=>{ + if(addedFlags.indexOf(variable.key) < 0){ + TransferrecipientCommand.flags[variable.key] = Flags.string(); + addedFlags.push(variable.key); + } + }) + } + +}) +TransferrecipientCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = TransferrecipientCommand; diff --git a/src/commands/verifications.js b/src/commands/verifications.js new file mode 100644 index 0000000..cba9fbf --- /dev/null +++ b/src/commands/verifications.js @@ -0,0 +1,74 @@ + +const {Command, Flags} = require('@oclif/core') +const helpers = require('../lib/helpers') +const APIs = require('../lib/paystack/apis') +const db = require('../lib/db') +let key = 'verifications'; +let API = APIs[key]; +class VerificationsCommand extends Command { + + + async run() { + const {args, flags} = await this.parse(VerificationsCommand) + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + let schema = helpers.findSchema(key, args.endpoint, flags) + if(!schema){ + helpers.errorLog(`ValidationError: Invalid endpoint 'verifications'`) + return; + } + let [err, result] = await helpers.promiseWrapper(helpers.executeSchema(schema, flags)) + if (err) { + if (err.response) { + helpers.errorLog(err.response.data.message) + return + } + helpers.errorLog(err) + return + } + helpers.successLog(result.message) + helpers.jsonLog(result.data) + + } +} + + +VerificationsCommand.description = helpers.getDescription(API, key) + +VerificationsCommand.flags = { + domain: Flags.string(), +} +let addedFlags = ['domain'] +let endpoints = []; +API.forEach(path => { + endpoints.push(path.api); + path.params.forEach(param => { + if (addedFlags.indexOf(param.parameter) < 0) { + switch (param.type) { + case 'String': + VerificationsCommand.flags[param.parameter] = Flags.string() + break + case 'Number': + VerificationsCommand.flags[param.parameter] = Flags.integer() + break + case 'Boolean': + VerificationsCommand.flags[param.parameter] = Flags.boolean() + break + default: + VerificationsCommand.flags[param.parameter] = Flags.string() + } + addedFlags.push(param.parameter) + } + }) +}) +VerificationsCommand.args = [ + {name: 'endpoint', required: true, options: endpoints} + ] + + +module.exports = VerificationsCommand; + + diff --git a/src/commands/webhook.js b/src/commands/webhook.js new file mode 100644 index 0000000..4d329a7 --- /dev/null +++ b/src/commands/webhook.js @@ -0,0 +1,122 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable block-scoped-var */ +/* eslint-disable no-redeclare */ +/* eslint-disable camelcase */ +const {Command,Flags} = require('@oclif/core') +const ngrok = require('ngrok') +const helpers = require('../lib/helpers') +const Paystack = require('../lib/paystack') +const db = require('../lib/db') + +class WebhookCommand extends Command { + async run() { + let selected_integration = db.read('selected_integration.id') + let user = db.read('user.id') + if (!selected_integration || !user) { + this.error("You're not signed in, please run the `paystack login` command before you begin") + } + const {args, flags} = await this.parse(WebhookCommand) + switch (args.subcommand) { + case 'listen': { + let token = '' + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + token = db.read('token') + } + + if (!flags.forward) { + this.error('To listen to webhook events locally, you have to specify a local route to forward events to using the forward flag e.g --forward localhost:3000/webhook') + } + let urlObject = helpers.parseURL(flags.forward); + if(urlObject.hostname !== 'localhost' && urlObject.hostname !== '127.0.0.1'){ + return helpers.errorLog(`Invalid host provided "${urlObject.hostname}" - You can only forward events to localhost`); + } + if (!urlObject.port) { + urlObject.port = 80 + } + if (!urlObject.search || urlObject.search === '?') { + urlObject.search = '' + } + try { + await ngrok.disconnect() + } catch (error) { + this.error(error) + } + let ngrokHost = await ngrok.connect(urlObject.port) + let ngrokURL = ngrokHost + urlObject.pathname + urlObject.search + let domain = 'test' + if (flags.domain === 'live') { + domain = 'live' + } + let originalWebhookUrl = db.read('selected_integration.' + domain + '_webhook_endpoint') + helpers.infoLog(`Forwarding webhook events to ${flags.forward}`) + + // eslint-disable-next-line no-unused-vars + var [err, result] = await helpers.promiseWrapper(Paystack.setWebhook(ngrokURL, token, db.read('selected_integration.id'), domain)) + if (err) { + this.error(err) + } + this.log('Webhook events would now be forwarded to ' + flags.forward) + const api = ngrok.getApi() + let tunnels = await api.get('api/tunnels') + tunnels = JSON.parse(tunnels).tunnels + let tunnel + for (let i = 0; i < tunnels.length; i++) { + if (tunnels[i].public_url === ngrokHost) { + tunnel = tunnels[i] + } + } + if (process.platform === 'win32') { + var rl = require('readline').createInterface({ + input: process.stdin, + output: process.stdout, + }) + rl.on('SIGINT', function () { + process.emit('SIGINT') + }) + } + process.on('SIGINT', async () => { + // graceful shutdown + this.log('cleaning up ') + var [err, result] = await helpers.promiseWrapper(Paystack.setWebhook(originalWebhookUrl, token, db.read('selected_integration.id'), domain)) + if (err) { + this.error(err) + } + // eslint-disable-next-line no-process-exit + process.exit() + }) + helpers.webhookInspector(api, tunnel) + break + } + case 'ping': { + await helpers.promiseWrapper(Paystack.refreshIntegration()) + // eslint-disable-next-line no-unused-vars + var [e, response] = await helpers.promiseWrapper(Paystack.pingWebhook(flags)) + helpers.infoLog('- - - - - WEBHOOK RESPONSE - - - - - -') + helpers.infoLog(response.code + ' - - ' + response.text) + if (helpers.isJson(response.data)) { + helpers.jsonLog(response.data) + } else { + helpers.infoLog(response.data) + } + break + } + } + } +} + +WebhookCommand.description = 'Listen for webhook events locally, and ping your webhook URL from the CLI' +WebhookCommand.args = [ + {name: 'subcommand'}, +] + +WebhookCommand.flags = { + forward: Flags.string(), + domain: Flags.string(), +} +module.exports = WebhookCommand diff --git a/src/commands/whoami.js b/src/commands/whoami.js new file mode 100644 index 0000000..9ebf20a --- /dev/null +++ b/src/commands/whoami.js @@ -0,0 +1,25 @@ +const {Command} = require('@oclif/core') +const db = require('../lib/db') +const helpers= require('../lib/helpers') +class WhoCommand extends Command { + async run() { + let selected_integration = db.read('selected_integration.id') + let user_id = db.read('user.id') + let user = db.read('user'); + let integration = db.read('selected_integration') + if (!selected_integration || !user_id) { + return this.log("You're not signed in yet") + } + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + if (expiry > now) { + return this.log('Logged in as ' + user.email + ' - ' + integration.business_name + ' (' + integration.id + ')') + } else { + return this.log("Your sign in session expired ") + } + } +} + +WhoCommand.description = 'Display the current logged in user' + +module.exports = WhoCommand \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..853bde8 --- /dev/null +++ b/src/index.js @@ -0,0 +1 @@ +module.exports = require('@oclif/core').run diff --git a/lib/Shell.js b/src/lib/Shell.js similarity index 100% rename from lib/Shell.js rename to src/lib/Shell.js diff --git a/src/lib/db.js b/src/lib/db.js new file mode 100644 index 0000000..af6d54a --- /dev/null +++ b/src/lib/db.js @@ -0,0 +1,32 @@ +const low = require('lowdb') +const FileSync = require('lowdb/adapters/FileSync') + +const adapter = new FileSync('db.json') +const db = low(adapter) + +// eslint-disable-next-line camelcase +db.defaults({token: '', user: {}, selected_integration: {}}).write() + +module.exports = { + clear: function(){ + db.set('token','').write(); + db.set('token_expiry', Number(Date.now())/1000).write(); + db.set('user', {}).write(); + db.set('selected_integration', {}).write(); + }, + write: function (key, value) { + db.set(key, value).write() + }, + read: function (key) { + return db.get(key).value() + }, + addToList: function (key, value) { + db.get(key) + .push(value) + .write() + }, + query: function (key, query) { + return db.get(key) + .find(query).value() + }, +} diff --git a/src/lib/helpers.js b/src/lib/helpers.js new file mode 100644 index 0000000..5500ef1 --- /dev/null +++ b/src/lib/helpers.js @@ -0,0 +1,222 @@ +/* eslint-disable node/no-extraneous-require */ +/* eslint-disable no-console */ +const readlineSync = require('readline-sync') +const chalk = require('chalk') +const url = require('url') +const HttpsProxyAgent = require("https-proxy-agent"); +const httpsAgent = new HttpsProxyAgent({host: "192.168.100.54", port: "9090"}) +const APIs = require('./paystack/APIs.json') +const { CliUx } = require('@oclif/core'); +const axios = require('axios') +const db = require('./db') +const pjson = require('pjson'); + +function prompt(question, mute = false) { + return readlineSync.question(question, { hideEchoBack: mute }) +} +const promiseWrapper = promise => ( + promise + .then(data => ([null, data])) + .catch(error => ([error])) +) + +function jsonLog(json) { + console.log(json) +} +function successLog(error) { + const eLog = chalk.green(error) + console.log(eLog) +} +function errorLog(error) { + const eLog = chalk.red(error) + console.log(eLog) +} +function isJson(val) { + return Boolean(Array.isArray(val) || val instanceof Object) +} + +function infoLog(error) { + const eLog = chalk.blueBright(error) + console.log(eLog) +} +function parseURL(uri) { + if (!uri.startsWith('http')) uri = 'http://' + uri + return url.parse(uri) +} +function findSchema(command, topic) { + let schema = null + APIs[command].forEach(f => { + if (f.api === topic) { + schema = f + } + }) + return schema +} + +function getKeys(token, type = 'secret', domain = 'test') { + return new Promise((resolve, reject) => { + axios.get('https://api.paystack.co/integration/keys', { headers: { Authorization: 'Bearer ' + token, 'jwt-auth': true, 'User-Agent': `Paystack-CLI v${pjson.version}` } }).then(response => { + let key = {}; + let keys = response.data.data; + if (keys.length) { + for (let i = 0; i < keys.length; i++) { + if (keys[i].domain === domain && keys[i].type === type) { + key = keys[i] + break + } + } + } + resolve(key) + }).catch(error => { + console.log(error); + if (error.response) { + reject(error.response.data.message) + return + } + reject(error) + }) + }) +} + +function buildAPIEndpoint(schema) { + return endpoint = schema.baseUrl + schema.path; +} + +async function executeSchema(schema, flags) { + let domain = 'test' + let endpoint = buildAPIEndpoint(schema); + // schema.endpoint = endpoint; + if (flags.domain) { + domain = flags.domain + } + + let token = db.read('token'); + let keyObject = await getKeys(token, 'secret', domain); + // let key = db.query('selected_integration.keys', {domain, type: 'secret'}).key + let instance = axios.create({ + baseURL: 'https://api.paystack.co', + timeout: 5000, + headers: { Authorization: 'Bearer ' + keyObject.key, 'User-Agent': `Paystack-CLI v${pjson.version}` } + }) + return new Promise((resolve, reject) => { + let query + let data + if (schema.method === 'GET') query = flags + if (schema.method === 'POST' || schema.method === 'PUT') data = flags; + if (schema.variables) { + schema.variables.every((variable) => { + if (!flags[variable.key]) { + reject('--' + variable.key + ' is required'); + return false + } + endpoint = endpoint.replace(`:${variable.key}`, flags[variable.key]); + return true + }) + } + schema.endpoint = endpoint; + if (schema.endpoint.indexOf('{')) { + let path = schema.endpoint.slice(schema.endpoint.indexOf('{') + 1, schema.endpoint.indexOf('}')) + + schema.endpoint = schema.endpoint.replace('{' + path + '}', flags[path]) + } + if (schema.method === 'GET') { + let queryString = Object.keys(flags).map(key => key + '=' + flags[key]).join('&') + schema.endpoint = schema.endpoint + '?' + queryString + } + instance({ + url: schema.endpoint, + method: schema.method, + query, + data, + }).then(resp => { + resolve(resp.data) + }).catch(error => { + console.error(error); + if (error.response) { + reject(error.response.data.message) + return + } + reject(error) + }) + }) +} + +function base64ToString(encoded) { + let buffer = Buffer.from(encoded, 'base64') + return buffer.toString('ascii') +} + +function getWebhookMessage(requestBody) { + let category = requestBody.event.slice(0, requestBody.event.lastIndexOf('.')) + let message = '' + switch (category) { + case 'customeridentification': + message = 'Customer Identification status for ' + requestBody.data.customer.email + break + + case 'charge.dispute': + message = 'Dispute status for ' + requestBody.data.customer.email + break + case 'invoice': + message = 'Invoice status for ' + requestBody.data.customer.email + break + case 'paymentrequest': + message = 'Payment request status for ' + requestBody.request_code + break + case 'subscription': + message = 'Subscription created for ' + requestBody.data.customer.email + if (requestBody.data.event === 'subscription.disable') { + message = 'Subscription disabled for ' + requestBody.data.customer.email + } + break + case 'charge': + message = 'Transaction status for ' + requestBody.data.customer.email + break + case 'transfer': + message = 'Transfer status for ' + requestBody.data.transfer_code + break + } + return message +} + +function webhookInspector(ngrokApi, tunnel) { + let id = '' + setInterval(() => { + CliUx.ux.action.start('.') + ngrokApi.get(`/api/requests/http?tunnel_name=${tunnel.name}`).then(httpRequests => { + httpRequests = JSON.parse(httpRequests).requests + if (httpRequests.length === 0) { + return + } + let lastRequest = httpRequests[0] + if (lastRequest.id === id) { + return + } + id = lastRequest.id + let requestBody = base64ToString(lastRequest.request.raw) + requestBody = requestBody.slice(requestBody.indexOf('{"eve')) + requestBody = JSON.parse(requestBody) + let responseCode = lastRequest.response.status_code.toString() + let webhookDescription = getWebhookMessage(requestBody) + let responseMessage = lastRequest.response.status + ' - ' + requestBody.event + ' - ' + webhookDescription + if (responseCode.slice(0, 1) !== '2') { + responseMessage = chalk.red(responseMessage) + } + console.log(responseMessage) + console.log(base64ToString(lastRequest.response.raw)) + console.log('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -') + }) + }, 5000) +} + +function getDescription(section, title) { + let desc = '' + section.forEach(f => { + desc = desc + ', ' + f.api + }) + desc = desc + ' ' + title + desc = desc.slice(1) + return desc +} + +module.exports = { prompt, promiseWrapper, successLog, jsonLog, errorLog, infoLog, isJson, parseURL, findSchema, executeSchema, getDescription, webhookInspector, getWebhookMessage, base64ToString } diff --git a/src/lib/paystack.js b/src/lib/paystack.js new file mode 100644 index 0000000..e54cfbf --- /dev/null +++ b/src/lib/paystack.js @@ -0,0 +1,279 @@ +/* eslint-disable block-scoped-var */ +/* eslint-disable no-redeclare */ +/* eslint-disable no-console */ +/* eslint-disable camelcase */ +/* eslint-disable unicorn/filename-case */ +const HttpsProxyAgent = require("https-proxy-agent"); +const httpsAgent = new HttpsProxyAgent({host: "192.168.100.54", port: "9090"}) +const axios = require('axios') +const helpers = require('./helpers') +const db = require('./db') +const pjson = require('pjson'); +const crypto = require('crypto') +const webhookSamples = require('./paystack/webhooks') +function selectIntegration(integrations, token) { + return new Promise((resolve, reject) => { + console.log('Choose an integration - ') + let promptMessage = '' + + integrations.forEach((b, i) => { + promptMessage += i + 1 + ' - ' + b.business_name + ' (' + b.id + ')\n' + }) + let integration = helpers.prompt(promptMessage + '\nEnter the corresponding number - ') + + axios.post('https://api.paystack.co/user/switch_integration', { integration: integrations[parseInt(integration, 10) - 1].id }, { headers: { Authorization: 'Bearer ' + token, 'jwt-auth': true, 'User-Agent':`Paystack-CLI v${pjson.version}` } }).then((response) => { + resolve(integrations[parseInt(integration, 10) - 1]) + }).catch(error => { + if(error.response){ + console.error(error.response.data) + return reject(error.response.data) + } + + console.error(error); + }) + }) +} + +async function refreshIntegration() { + let user_role = db.read('selected_integration.logged_in_user_role') + let integration = db.read('selected_integration') + let token = '' + let user + let expiry = parseInt(db.read('token_expiry'), 10) * 1000 + let now = parseFloat(Date.now().toString()) + + if (expiry > now) { + token = db.read('token') + } else { + let password = helpers.prompt("What's your password: (" + db.read('user.email') + ') \n>', true) + var [err, response] = await helpers.promiseWrapper(signIn(db.read('user.email'), password)) + if (err) { + helpers.errorLog(err) + } + if (response && !response.mfa_required) { + ({ token, expiry, user } = response) + db.write('token', token) + db.write('user', user) + db.write('token_expiry', expiry) + helpers.successLog('Login successful') + } else if (response.mfa_required) { + helpers.infoLog('MFA required') + let mfa_code = helpers.prompt('Enter the 6-digit verification code generated by your authenticator app\n'); + [err, response] = await helpers.promiseWrapper(verifyToken(mfa_code, response.token)) + if (response) { + ({ token, expiry, user } = response) + db.write('token', token) + db.write('user', user) + db.write('token_expiry', expiry) + helpers.successLog('Login successful') + } else { + this.error('Login failed' + JSON.stringify(err) + JSON.stringify(response)) + } + } else { + this.error('Login failed' + JSON.stringify(err) + JSON.stringify(response)) + } + if (!response) { + return false + } + token = response.token + } + + var [err, integrationData] = await helpers.promiseWrapper(getIntegration(integration.id, token)) + if (err) { + helpers.errorLog(err) + return false + } + integrationData.logged_in_user_role = user_role + db.write('selected_integration', integrationData) + return true +} + +function setWebhook(url, token, integration, domain = 'test') { + return new Promise((resolve, reject) => { + let data = {} + data[domain + '_webhook_endpoint'] = url + data.integration = integration + let headers = { + Authorization: 'Bearer ' + token, + 'jwt-auth': true, + 'User-Agent':`Paystack-CLI v${pjson.version}` + } + axios.put('https://api.paystack.co/integration/webhooks', data, { headers }).then(resp => { + resolve(resp.data.message) + }).catch(error => { + if(error.response){ + reject(error.response.data.message); + return + } + console.log(error.response.data) + reject(error) + }) + }) +} + +function getKeys(token, type = 'secret', domain = 'test') { + return new Promise((resolve, reject) => { + axios.get('https://api.paystack.co/integration/keys', { headers: { Authorization: 'Bearer ' + token, 'jwt-auth': true, 'User-Agent':`Paystack-CLI v${pjson.version}` } }).then(response => { + let key = {}; + let keys = response.data.data; + if (keys.length) { + for (let i = 0; i < keys.length; i++) { + if (keys[i].domain === domain && keys[i].type === type) { + key = keys[i] + break + } + } + } + resolve(key) + }).catch(error => { + if (error.response) { + reject(error.response.data.message) + return + } + reject(error) + }) + }) +} + +function pingWebhook(flags) { + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { + let canProceed + try { + canProceed = await refreshIntegration() + } catch (error) { + console.error(error) + } + if (!canProceed) { + helpers.errorLog('- - - - - - - - Unable to ping webhook URL - - - - - - - -') + return + } + let domain = 'test' + if (flags.domain) { + domain = flags.domain + } + let event = 'charge.success' + if (flags.event) { + event = flags.event + } + let eventObject = webhookSamples[event] + if (eventObject) { + // let key = db.query('selected_integration.keys', { domain, type: 'secret' }).key + let token = db.read('token'); + let keyObject = await getKeys(token, 'secret', 'test'); + + var hash = crypto.createHmac('sha512', keyObject.key).update(JSON.stringify(eventObject)).digest('hex') + let uri = db.read('selected_integration.' + domain + '_webhook_endpoint') + helpers.infoLog('- - - - - - - - - - - - - - - - - - - - - - - - - - - - ') + helpers.infoLog(`Sending sample ${event} event payload to ${uri}`) + axios.post(uri, eventObject, + { + headers: { + 'x-paystack-signature': hash, + 'User-Agent':`Paystack-CLI v${pjson.version}` + }, + }, + + ).then(response => { + resolve({ + code: response.status, + text: response.statusText, + data: response.data, + }) + }).catch(error => { + if (!error.response) { + resolve({ + code: 999, + text: error.message, + data: error.stack + } + ) + return + } + + resolve({ + code: error.response.status, + text: error.response.statusText, + data: error.response.data, + }) + }) + } else { + helpers.errorLog('Invalid event type - ' + event) + reject() + } + }) +} + +function getIntegration(id, token) { + return new Promise((resolve, reject) => { + axios.get('https://api.paystack.co/integration/' + id, + { + headers: { + Authorization: 'Bearer ' + token, + 'jwt-auth': true, + 'User-Agent':`Paystack-CLI v${pjson.version}` + }, + }).then(response => { + resolve(response.data.data) + }).catch(error => { + if (error.response) { + reject(error.response.data.message) + return + } + reject(error) + }) + }) +} + +function signIn(email, password) { + return new Promise((resolve, reject) => { + let expiry = parseInt(db.read('token_expiry'), 10) + let now = parseFloat(Date.now().toString()) + if (expiry > now) { + resolve({ + token: db.read('token'), + user: db.read('user'), + }) + return + } + helpers.infoLog('Logging in') + axios({ + url: 'https://api.paystack.co/login', + method: 'POST', + data: { email, password } + }).then(response => { + resolve(response.data.data) + }).catch(error => { + if (error.response) { + helpers.errorLog(JSON.stringify(error.response.data.message) || 'Unable to sign in, please try again in a few minutes') + reject(new Error('LOGIN ERROR: ' + error.response.data.message)) + return + } + console.error(error); + + }) + }) +} +function verifyToken(totp, token) { + return new Promise((resolve, reject) => { + helpers.infoLog('Verifying token') + axios({ + url: 'https://api.paystack.co/verify-mfa', + method: 'POST', + headers: { + 'jwt-auth': true, + authorization: `Bearer ${token}`, + }, + data: { totp }, + }).then(response => { + resolve(response.data.data) + }).catch(error => { + helpers.errorLog(error.response.data.message || 'Unable to sign in, please try again in a few minutes') + reject(new Error('LOGIN ERROR: ' + error.response.data.message)) + }) + }) +} + +module.exports = { + signIn, getKeys, setWebhook, selectIntegration, getIntegration, pingWebhook, refreshIntegration, verifyToken, +} diff --git a/src/lib/paystack/APIs.json b/src/lib/paystack/APIs.json new file mode 100644 index 0000000..bd1bd1e --- /dev/null +++ b/src/lib/paystack/APIs.json @@ -0,0 +1,3071 @@ +{ + "transaction": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/:id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "transaction", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) The ID of the transaction to fetch" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/:id/event", + "method": "GET", + "params": [], + "api": "get_event", + "parent": "transaction", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/:id/session", + "method": "GET", + "params": [], + "api": "get_session", + "parent": "transaction", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "transaction" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/initialize", + "method": "POST", + "params": [ + { + "parameter": "email", + "description": "(Required) Customer's email address", + "required": true + }, + { + "parameter": "amount", + "description": "(Required) Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "currency", + "description": "The transaction currency", + "required": false + }, + { + "parameter": "reference", + "description": "Unique transaction reference. Only -, ., = and alphanumeric characters allowed.", + "required": false + }, + { + "parameter": "callback_url", + "description": "Fully qualified url, e.g. https://example.com/ . Use this to override the callback url provided on the dashboard for this transaction", + "required": false + }, + { + "parameter": "plan", + "description": "If transaction is to create a subscription to a predefined plan, provide plan code here. \nThis would invalidate the value provided in amount", + "required": false + }, + { + "parameter": "invoice_limit", + "description": "Number of times to charge customer during subscription to plan", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + }, + { + "parameter": "channels", + "description": "An array of payment channels to control what channels you want to make available to the user to make a payment with", + "required": false + }, + { + "parameter": "channels", + "description": "An array of payment channels to control what channels you want to make available to the user to make a payment with", + "required": false + }, + { + "parameter": "split_code", + "description": "The split code of the transaction split", + "required": false + }, + { + "parameter": "subaccount", + "description": "The code for the subaccount that owns the payment", + "required": false + }, + { + "parameter": "transaction_charge", + "description": "A flat fee to charge the subaccount for a transaction. \nThis overrides the split percentage set when the subaccount was created", + "required": false + }, + { + "parameter": "bearer", + "description": "The bearer of the transaction charge", + "required": false + } + ], + "api": "initialize", + "parent": "transaction" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/verify/:reference", + "method": "GET", + "params": [], + "api": "verify", + "parent": "transaction", + "variables": [ + { + "key": "reference", + "value": "in ipsum qui", + "description": "(Required) The transaction reference to verify" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/timeline/:id_or_reference", + "method": "GET", + "params": [], + "api": "fetch_timeline", + "parent": "transaction", + "variables": [ + { + "key": "id_or_reference", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/totals", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "totals", + "parent": "transaction" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/export", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "export", + "parent": "transaction" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/charge_authorization", + "method": "POST", + "params": [ + { + "parameter": "email", + "description": "(Required) Customer's email address", + "required": true + }, + { + "parameter": "amount", + "description": "(Required) Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "authorization_code", + "description": "(Required) Valid authorization code to charge", + "required": true + }, + { + "parameter": "reference", + "description": "Unique transaction reference. Only -, ., = and alphanumeric characters allowed.", + "required": false + }, + { + "parameter": "currency", + "description": "The transaction currency", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + }, + { + "parameter": "split_code", + "description": "The split code of the transaction split", + "required": false + }, + { + "parameter": "subaccount", + "description": "The code for the subaccount that owns the payment", + "required": false + }, + { + "parameter": "transaction_charge", + "description": "A flat fee to charge the subaccount for a transaction. \nThis overrides the split percentage set when the subaccount was created", + "required": false + }, + { + "parameter": "bearer", + "description": "The beare of the transaction charge", + "required": false + }, + { + "parameter": "queue", + "description": "If you are making a scheduled charge call, it is a good idea to queue them so the processing system does not get overloaded causing transaction processing errors.", + "required": false + } + ], + "api": "charge_authorization", + "parent": "transaction" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/check_authorization", + "method": "POST", + "params": [ + { + "parameter": "email", + "description": "(Required) Customer's email address", + "required": true + }, + { + "parameter": "amount", + "description": "(Required) Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "authorization_code", + "description": "Valid authorization code to charge", + "required": false + }, + { + "parameter": "currency", + "description": "The transaction currency", + "required": false + } + ], + "api": "check_authorization", + "parent": "transaction" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transaction/partial_debit", + "method": "POST", + "params": [ + { + "parameter": "email", + "description": "(Required) Customer's email address", + "required": true + }, + { + "parameter": "amount", + "description": "(Required) Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "authorization_code", + "description": "(Required) Valid authorization code to charge", + "required": true + }, + { + "parameter": "currency", + "description": "(Required) The transaction currency", + "required": true + }, + { + "parameter": "reference", + "description": "Unique transaction reference. Only -, ., = and alphanumeric characters allowed.", + "required": false + }, + { + "parameter": "at_least", + "description": "Minimum amount to charge", + "required": false + } + ], + "api": "partial_debit", + "parent": "transaction" + } + ], + "split": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "split/:id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "split", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "split/:id", + "method": "PUT", + "params": [ + { + "parameter": "name", + "description": "Name of the transaction split", + "required": false + }, + { + "parameter": "active", + "description": "Toggle status of split. When true, the split is active, else it's inactive", + "required": false + }, + { + "parameter": "bearer_type", + "description": "This allows you specify how the transaction charge should be processed", + "required": false + }, + { + "parameter": "bearer_subaccount", + "description": "This is the subaccount code of the customer or partner that would bear the transaction charge if you specified subaccount as the bearer type", + "required": false + } + ], + "api": "update", + "parent": "split", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "split", + "method": "POST", + "params": [ + { + "parameter": "name", + "description": "(Required) Name of the transaction split", + "required": true + }, + { + "parameter": "type", + "description": "(Required) The type of transaction split you want to create.", + "required": true + }, + { + "parameter": "subaccounts", + "description": "(Required) A list of object containing subaccount code and number of shares", + "required": true + }, + { + "parameter": "subaccounts", + "description": "(Required) A list of object containing subaccount code and number of shares", + "required": true + }, + { + "parameter": "currency", + "description": "(Required) The transaction currency", + "required": true + }, + { + "parameter": "bearer_type", + "description": "This allows you specify how the transaction charge should be processed", + "required": false + }, + { + "parameter": "bearer_subaccount", + "description": "This is the subaccount code of the customer or partner that would bear the transaction charge if you specified subaccount as the bearer type", + "required": false + } + ], + "api": "create", + "parent": "split" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "split", + "method": "GET", + "params": [ + { + "parameter": "name", + "required": false + }, + { + "parameter": "active", + "required": false + }, + { + "parameter": "sort_by", + "required": false + }, + { + "parameter": "from", + "required": false + }, + { + "parameter": "to", + "required": false + }, + { + "parameter": "perPage", + "required": false + }, + { + "parameter": "page", + "required": false + } + ], + "api": "list", + "parent": "split" + } + ], + "customer": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "customer/:code", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "customer", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "customer/:code", + "method": "PUT", + "params": [ + { + "parameter": "first_name", + "description": "Customer's first name", + "required": false + }, + { + "parameter": "last_name", + "description": "Customer's last name", + "required": false + }, + { + "parameter": "phone", + "description": "Customer's phone number", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + } + ], + "api": "update", + "parent": "customer", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "customer/:code/identification", + "method": "POST", + "params": [ + { + "parameter": "type", + "description": "(Required) Predefined types of identification.", + "required": true + }, + { + "parameter": "country", + "description": "(Required) Two-letter country code of identification issuer", + "required": true + }, + { + "parameter": "bvn", + "description": "(Required) Customer's Bank Verification Number", + "required": true + }, + { + "parameter": "bank_code", + "description": "(Required) You can get the list of bank codes by calling the List Banks endpoint (https://api.paystack.co/bank).", + "required": true + }, + { + "parameter": "account_number", + "description": "(Required) Customer's bank account number.", + "required": true + }, + { + "parameter": "value", + "description": "Customer's identification number. Required if type is bvn", + "required": true + } + ], + "api": "validate", + "parent": "customer", + "variables": [ + { + "key": "code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "customer", + "method": "POST", + "params": [ + { + "parameter": "email", + "description": "Customer's email address", + "required": true + }, + { + "parameter": "first_name", + "description": "Customer's first name", + "required": false + }, + { + "parameter": "last_name", + "description": "Customer's last name", + "required": false + }, + { + "parameter": "phone", + "description": "Customer's phone number", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + } + ], + "api": "create", + "parent": "customer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "customer", + "method": "GET", + "params": [ + { + "parameter": "use_cursor", + "required": false + }, + { + "parameter": "next", + "required": false + }, + { + "parameter": "previous", + "required": false + }, + { + "parameter": "from", + "required": false + }, + { + "parameter": "to", + "required": false + }, + { + "parameter": "perPage", + "required": false + }, + { + "parameter": "page", + "required": false + } + ], + "api": "list", + "parent": "customer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "customer/set_risk_action", + "method": "POST", + "params": [ + { + "parameter": "customer", + "description": "(Required) Customer's code, or email address", + "required": true + }, + { + "parameter": "risk_action", + "description": "One of the possible risk actions [ default, allow, deny ]. allow to whitelist. \ndeny to blacklist. Customers start with a default risk action.\n", + "required": false + } + ], + "api": "white/blacklist", + "parent": "customer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "customer/deactivate_authorization", + "method": "POST", + "params": [ + { + "parameter": "authorization_code", + "description": "(Required) Customer's authorization code to be deactivated", + "required": true + } + ], + "api": "deactivate_authorization", + "parent": "customer" + } + ], + "dedicatedaccount": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "dedicated_account/:account_id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "dedicatedaccount", + "variables": [ + { + "key": "account_id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dedicated_account/:account_id", + "method": "DELETE", + "params": [], + "api": "deactivate", + "parent": "dedicatedaccount", + "variables": [ + { + "key": "account_id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dedicated_account", + "method": "POST", + "params": [ + { + "parameter": "customer", + "description": "(Required) Customer ID or code", + "required": true + }, + { + "parameter": "preferred_bank", + "description": "The bank slug for preferred bank. To get a list of available banks, use the List Providers endpoint", + "required": false + }, + { + "parameter": "subaccount", + "description": "Subaccount code of the account you want to split the transaction with", + "required": false + }, + { + "parameter": "split_code", + "description": "Split code consisting of the lists of accounts you want to split the transaction with", + "required": false + } + ], + "api": "create", + "parent": "dedicatedaccount" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dedicated_account", + "method": "GET", + "params": [ + { + "parameter": "account_number", + "required": false + }, + { + "parameter": "customer", + "required": false + }, + { + "parameter": "active", + "required": false + }, + { + "parameter": "currency", + "required": false + }, + { + "parameter": "provider_slug", + "required": false + }, + { + "parameter": "bank_id", + "required": false + }, + { + "parameter": "perPage", + "required": false + }, + { + "parameter": "page", + "required": false + } + ], + "api": "list", + "parent": "dedicatedaccount" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dedicated_account/available_providers", + "method": "GET", + "params": [], + "api": "providers", + "parent": "dedicatedaccount" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dedicated_account/split", + "method": "POST", + "params": [ + { + "parameter": "account_number", + "description": "(Required) Valid Dedicated virtual account", + "required": true + }, + { + "parameter": "subaccount", + "description": "Subaccount code of the account you want to split the transaction with", + "required": false + }, + { + "parameter": "split_code", + "description": "Split code consisting of the lists of accounts you want to split the transaction with", + "required": false + } + ], + "api": "split", + "parent": "dedicatedaccount" + } + ], + "subaccount": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "subaccount/:code", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "subaccount", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "subaccount/:code", + "method": "PUT", + "params": [ + { + "parameter": "business_name", + "description": "Name of business for subaccount", + "required": false + }, + { + "parameter": "settlement_bank", + "description": "Bank code for the bank. You can get the list of Bank Codes by calling the List Banks endpoint.", + "required": false + }, + { + "parameter": "account_number", + "description": "Bank account number", + "required": false + }, + { + "parameter": "active", + "description": "Activate or deactivate a subaccount", + "required": false + }, + { + "parameter": "percentage_charge", + "description": "Customer's phone number", + "required": false + }, + { + "parameter": "description", + "description": "A description for this subaccount", + "required": false + }, + { + "parameter": "primary_contact_email", + "description": "A contact email for the subaccount", + "required": false + }, + { + "parameter": "primary_contact_name", + "description": "The name of the contact person for this subaccount", + "required": false + }, + { + "parameter": "primary_contact_phone", + "description": "A phone number to call for this subaccount", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + } + ], + "api": "update", + "parent": "subaccount", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "subaccount", + "method": "POST", + "params": [ + { + "parameter": "business_name", + "description": "(Required) Name of business for subaccount", + "required": true + }, + { + "parameter": "settlement_bank", + "description": "(Required) Bank code for the bank. You can get the list of Bank Codes by calling the List Banks endpoint.", + "required": true + }, + { + "parameter": "account_number", + "description": "(Required) Bank account number", + "required": true + }, + { + "parameter": "percentage_charge", + "description": "(Required) Customer's phone number", + "required": true + }, + { + "parameter": "description", + "description": "A description for this subaccount", + "required": false + }, + { + "parameter": "primary_contact_email", + "description": "A contact email for the subaccount", + "required": false + }, + { + "parameter": "primary_contact_name", + "description": "The name of the contact person for this subaccount", + "required": false + }, + { + "parameter": "primary_contact_phone", + "description": "A phone number to call for this subaccount", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + } + ], + "api": "create", + "parent": "subaccount" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "subaccount", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "subaccount" + } + ], + "plan": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "plan/:code", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "plan", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "plan/:code", + "method": "PUT", + "params": [ + { + "parameter": "name", + "description": "Name of plan", + "required": false + }, + { + "parameter": "amount", + "description": "Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": false + }, + { + "parameter": "interval", + "description": "Interval in words. Valid intervals are daily, weekly, monthly,biannually, annually", + "required": false + }, + { + "parameter": "description", + "description": "A description for this plan", + "required": false + }, + { + "parameter": "send_invoices", + "description": "Set to false if you don't want invoices to be sent to your customers", + "required": false + }, + { + "parameter": "send_sms", + "description": "Set to false if you don't want text messages to be sent to your customers", + "required": false + }, + { + "parameter": "currency", + "description": "Currency in which amount is set. Allowed values are NGN, GHS, ZAR or USD", + "required": false + }, + { + "parameter": "invoice_limit", + "description": "Number of invoices to raise during subscription to this plan. \nCan be overridden by specifying an invoice_limit while subscribing.", + "required": false + } + ], + "api": "update", + "parent": "plan", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "plan", + "method": "POST", + "params": [ + { + "parameter": "name", + "description": "(Required) Name of plan", + "required": true + }, + { + "parameter": "amount", + "description": "(Required) Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "interval", + "description": "(Required) Interval in words. Valid intervals are daily, weekly, monthly,biannually, annually", + "required": true + }, + { + "parameter": "description", + "description": "A description for this plan", + "required": false + }, + { + "parameter": "send_invoices", + "description": "Set to false if you don't want invoices to be sent to your customers", + "required": false + }, + { + "parameter": "send_sms", + "description": "Set to false if you don't want text messages to be sent to your customers", + "required": false + }, + { + "parameter": "currency", + "description": "Currency in which amount is set. Allowed values are NGN, GHS, ZAR or USD", + "required": false + }, + { + "parameter": "invoice_limit", + "description": "Number of invoices to raise during subscription to this plan. \nCan be overridden by specifying an invoice_limit while subscribing.", + "required": false + } + ], + "api": "create", + "parent": "plan" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "plan", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "interval", + "description": "Specify interval of the plan", + "required": false + }, + { + "parameter": "amount", + "description": "The amount on the plans to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "plan" + } + ], + "subscription": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "subscription/:code", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "subscription", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "subscription", + "method": "POST", + "params": [ + { + "parameter": "customer", + "description": "(Required) Customer's email address or customer code", + "required": true + }, + { + "parameter": "plan", + "description": "(Required) Plan code", + "required": true + }, + { + "parameter": "authorization", + "description": "If customer has multiple authorizations, you can set the desired authorization you wish to use for this subscription here. \nIf this is not supplied, the customer's most recent authorization would be used", + "required": false + }, + { + "parameter": "start_date", + "description": "Set the date for the first debit. (ISO 8601 format) e.g. 2017-05-16T00:30:13+01:00", + "required": false + } + ], + "api": "create", + "parent": "subscription" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "subscription", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "plan", + "description": "Plan ID", + "required": false + }, + { + "parameter": "customer", + "description": "Customer ID", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "subscription" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "subscription/disable", + "method": "POST", + "params": [ + { + "parameter": "code", + "description": "(Required) Subscription code", + "required": true + }, + { + "parameter": "token", + "description": "(Required) Email token", + "required": true + }, + { + "parameter": "authorization", + "description": "(Required) ", + "required": true + } + ], + "api": "disable", + "parent": "subscription" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "subscription/enable", + "method": "POST", + "params": [ + { + "parameter": "code", + "description": "(Required) Subscription code", + "required": true + }, + { + "parameter": "token", + "description": "(Required) Email token", + "required": true + }, + { + "parameter": "authorization", + "description": "(Required) ", + "required": true + } + ], + "api": "enable", + "parent": "subscription" + } + ], + "product": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "product/:id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "product", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "product/:id", + "method": "PUT", + "params": [ + { + "parameter": "name", + "description": "Name of product", + "required": false + }, + { + "parameter": "description", + "description": "The description of the product", + "required": false + }, + { + "parameter": "price", + "description": "Price should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": false + }, + { + "parameter": "currency", + "description": "Currency in which price is set. Allowed values are: NGN, GHS, ZAR or USD", + "required": false + }, + { + "parameter": "limited", + "description": "Set to true if the product has limited stock. Leave as false if the product has unlimited stock", + "required": false + }, + { + "parameter": "quantity", + "description": "Number of products in stock. Use if limited is true", + "required": false + } + ], + "api": "update", + "parent": "product", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "product/:id", + "method": "DELETE", + "params": [], + "api": "delete", + "parent": "product", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "product", + "method": "POST", + "params": [ + { + "parameter": "name", + "description": "(Required) Name of product", + "required": true + }, + { + "parameter": "description", + "description": "(Required) The description of the product", + "required": true + }, + { + "parameter": "price", + "description": "(Required) Price should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "currency", + "description": "(Required) Currency in which price is set. Allowed values are: NGN, GHS, ZAR or USD", + "required": true + }, + { + "parameter": "limited", + "description": "Set to true if the product has limited stock. Leave as false if the product has unlimited stock", + "required": false + }, + { + "parameter": "quantity", + "description": "Number of products in stock. Use if limited is true", + "required": false + } + ], + "api": "create", + "parent": "product" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "product", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "required": false + }, + { + "parameter": "page", + "required": false + }, + { + "parameter": "active", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "product" + } + ], + "page": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "page/:id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "page", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "page/:id", + "method": "PUT", + "params": [ + { + "parameter": "name", + "description": "Name of page", + "required": false + }, + { + "parameter": "description", + "description": "The description of the page", + "required": false + }, + { + "parameter": "amount", + "description": "Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": false + }, + { + "parameter": "active", + "description": "Set to false to deactivate page url", + "required": false + } + ], + "api": "update", + "parent": "page", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "page/:id/product", + "method": "POST", + "params": [ + { + "parameter": "product", + "description": "(Required) IDs of all products to add to a page", + "required": true + }, + { + "parameter": "product", + "description": "(Required) IDs of all products to add to a page", + "required": true + } + ], + "api": "add_products", + "parent": "page", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "page", + "method": "POST", + "params": [ + { + "parameter": "name", + "description": "(Required) Name of page", + "required": true + }, + { + "parameter": "description", + "description": "The description of the page", + "required": false + }, + { + "parameter": "amount", + "description": "Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": false + }, + { + "parameter": "slug", + "description": "URL slug you would like to be associated with this page. Page will be accessible at https://paystack.com/pay/[slug]", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + }, + { + "parameter": "redirect_url", + "description": "If you would like Paystack to redirect to a URL upon successful payment, specify the URL here.", + "required": false + } + ], + "api": "create", + "parent": "page" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "page", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "page" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "page/check_slug_availability/:slug", + "method": "GET", + "params": [], + "api": "check_slug_availability", + "parent": "page", + "variables": [ + { + "key": "slug", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + } + ], + "paymentrequest": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest/:id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "paymentrequest", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest/:id", + "method": "PUT", + "params": [ + { + "parameter": "customer", + "description": "Customer id or code", + "required": false + }, + { + "parameter": "amount", + "description": "Payment request amount. Only useful if line items and tax values are ignored. \nThe endpoint will throw a friendly warning if neither is available.", + "required": false + }, + { + "parameter": "currency", + "description": "Specify the currency of the invoice. Allowed values are NGN, GHS, ZAR and USD. Defaults to NGN", + "required": false + }, + { + "parameter": "due_date", + "description": "ISO 8601 representation of request due date", + "required": false + }, + { + "parameter": "description", + "description": "A short description of the payment request", + "required": false + }, + { + "parameter": "send_notification", + "description": "Indicates whether Paystack sends an email notification to customer. Defaults to true", + "required": false + }, + { + "parameter": "draft", + "description": "Indicate if request should be saved as draft. Defaults to false and overrides send_notification", + "required": false + }, + { + "parameter": "has_invoice", + "description": "Set to true to create a draft invoice (adds an auto incrementing invoice number if none is provided) \neven if there are no line_items or tax passed", + "required": false + }, + { + "parameter": "invoice_number", + "description": "Numeric value of invoice. Invoice will start from 1 and auto increment from there. This field is to help \noverride whatever value Paystack decides. Auto increment for subsequent invoices continue from this point.", + "required": false + } + ], + "api": "update", + "parent": "paymentrequest", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest", + "method": "POST", + "params": [ + { + "parameter": "customer", + "description": "(Required) Customer id or code", + "required": true + }, + { + "parameter": "amount", + "description": "Payment request amount. Only useful if line items and tax values are ignored. \nThe endpoint will throw a friendly warning if neither is available.", + "required": false + }, + { + "parameter": "currency", + "description": "Specify the currency of the invoice. Allowed values are NGN, GHS, ZAR and USD. Defaults to NGN", + "required": false + }, + { + "parameter": "due_date", + "description": "ISO 8601 representation of request due date", + "required": false + }, + { + "parameter": "description", + "description": "A short description of the payment request", + "required": false + }, + { + "parameter": "send_notification", + "description": "Indicates whether Paystack sends an email notification to customer. Defaults to true", + "required": false + }, + { + "parameter": "draft", + "description": "Indicate if request should be saved as draft. Defaults to false and overrides send_notification", + "required": false + }, + { + "parameter": "has_invoice", + "description": "Set to true to create a draft invoice (adds an auto incrementing invoice number if none is provided) \neven if there are no line_items or tax passed", + "required": false + }, + { + "parameter": "invoice_number", + "description": "Numeric value of invoice. Invoice will start from 1 and auto increment from there. This field is to help \noverride whatever value Paystack decides. Auto increment for subsequent invoices continue from this point.", + "required": false + }, + { + "parameter": "split_code", + "description": "The split code of the transaction split.", + "required": false + } + ], + "api": "create", + "parent": "paymentrequest" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "customer", + "description": "Customer ID", + "required": false + }, + { + "parameter": "status", + "description": "Invoice status to filter", + "required": false + }, + { + "parameter": "currency", + "description": "If your integration supports more than one currency, choose the one to filter", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "paymentrequest" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest/verify/:id", + "method": "GET", + "params": [], + "api": "verify", + "parent": "paymentrequest", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest/notify/:id", + "method": "POST", + "params": [], + "api": "send_notification", + "parent": "paymentrequest", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest/totals", + "method": "GET", + "params": [], + "api": "totals", + "parent": "paymentrequest" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest/finalize/:id", + "method": "POST", + "params": [], + "api": "finalize", + "parent": "paymentrequest", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "paymentrequest/archive/:id", + "method": "POST", + "params": [], + "api": "archive", + "parent": "paymentrequest", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + } + ], + "settlement": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "settlement", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "required": false + }, + { + "parameter": "page", + "required": false + } + ], + "api": "fetch", + "parent": "settlement" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "settlement/:id/transaction", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "required": false + }, + { + "parameter": "page", + "required": false + } + ], + "api": "transactions", + "parent": "settlement", + "variables": [ + { + "key": "id" + } + ] + } + ], + "transferrecipient": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "transferrecipient/:code", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "transferrecipient", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Transfer recipient code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transferrecipient/:code", + "method": "PUT", + "params": [ + { + "parameter": "name", + "description": "Recipient's name", + "required": false + }, + { + "parameter": "email", + "description": "Recipient's email address", + "required": false + } + ], + "api": "update", + "parent": "transferrecipient", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Transfer recipient code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transferrecipient/:code", + "method": "DELETE", + "params": [], + "api": "delete", + "parent": "transferrecipient", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Transfer recipient code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transferrecipient", + "method": "POST", + "params": [ + { + "parameter": "type", + "description": "(Required) Recipient Type (Only nuban at this time)", + "required": true + }, + { + "parameter": "name", + "description": "(Required) Recipient's name", + "required": true + }, + { + "parameter": "account_number", + "description": "(Required) Recipient's bank account number", + "required": true + }, + { + "parameter": "bank_code", + "description": "(Required) Recipient's bank code. You can get the list of Bank Codes by calling the List Banks endpoint", + "required": true + }, + { + "parameter": "description", + "description": "A description for this recipient", + "required": false + }, + { + "parameter": "currency", + "description": "Currency for the account receiving the transfer", + "required": false + }, + { + "parameter": "authorization_code", + "description": "An authorization code from a previous transaction", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + } + ], + "api": "create", + "parent": "transferrecipient" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transferrecipient", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "transferrecipient" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transferrecipient/bulk", + "method": "POST", + "params": [ + { + "parameter": "batch", + "description": "(Required) A list of transfer recipient object. Each object should contain type, name, and bank_code. \nAny Create Transfer Recipient param can also be passed.", + "required": true + }, + { + "parameter": "batch", + "description": "(Required) A list of transfer recipient object. Each object should contain type, name, and bank_code. \nAny Create Transfer Recipient param can also be passed.", + "required": true + } + ], + "api": "bulk", + "parent": "transferrecipient" + } + ], + "transfer": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer", + "method": "POST", + "params": [ + { + "parameter": "source", + "description": "(Required) Where should we transfer from? Only balance is allowed for now", + "required": true + }, + { + "parameter": "amount", + "description": "(Required) Amount to transfer in kobo if currency is NGN and pesewas if currency is GHS.", + "required": true + }, + { + "parameter": "recipient", + "description": "(Required) The transfer recipient's code", + "required": true + }, + { + "parameter": "reason", + "description": "The reason or narration for the transfer.", + "required": false + }, + { + "parameter": "currency", + "description": "Specify the currency of the transfer. Defaults to NGN.", + "required": false + }, + { + "parameter": "reference", + "description": "If specified, the field should be a unique identifier (in lowercase) for the object. \nOnly -,_ and alphanumeric characters are allowed.", + "required": false + } + ], + "api": "initiate", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "status", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/finalize_transfer", + "method": "POST", + "params": [ + { + "parameter": "transfer_code", + "description": "(Required) The transfer code you want to finalize", + "required": true + }, + { + "parameter": "otp", + "description": "(Required) OTP sent to business phone to verify transfer", + "required": true + } + ], + "api": "finalize", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/bulk", + "method": "POST", + "params": [ + { + "parameter": "source", + "description": "Where should we transfer from? Only balance is allowed for now", + "required": false + }, + { + "parameter": "transfers", + "description": "A list of transfer object. Each object should contain amount, recipient, and reference", + "required": false + }, + { + "parameter": "transfers", + "description": "A list of transfer object. Each object should contain amount, recipient, and reference", + "required": false + } + ], + "api": "initiate_bulk", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/:code", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "transfer", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Transfer code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/verify/:reference", + "method": "GET", + "params": [], + "api": "verify", + "parent": "transfer", + "variables": [ + { + "key": "reference", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/export", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "status", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "export", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/resend_otp", + "method": "POST", + "params": [ + { + "parameter": "transfer_code", + "description": "(Required) The transfer code that requires an OTP validation", + "required": true + }, + { + "parameter": "reason", + "description": "(Required) Either resend_otp or transfer", + "required": true + } + ], + "api": "resend_otp_for", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/disable_otp", + "method": "POST", + "params": [], + "api": "disable_otp_requirement_for", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/disable_otp_finalize", + "method": "POST", + "params": [ + { + "parameter": "otp", + "description": "(Required) OTP sent to business phone to verify disabling OTP requirement", + "required": true + } + ], + "api": "finalize_disabling_of_otp_requirement_for", + "parent": "transfer" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "transfer/enable_otp", + "method": "POST", + "params": [], + "api": "enable_otp_requirement_for", + "parent": "transfer" + } + ], + "balance": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "balance", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "balance" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "balance/ledger", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "ledger", + "parent": "balance" + } + ], + "charge": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "charge", + "method": "POST", + "params": [ + { + "parameter": "email", + "description": "(Required) Customer's email address", + "required": true + }, + { + "parameter": "amount", + "description": "(Required) Amount should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "currency", + "description": "The transaction currency", + "required": false + }, + { + "parameter": "reference", + "description": "Unique transaction reference. Only -, ., = and alphanumeric characters allowed.", + "required": false + }, + { + "parameter": "metadata", + "description": "Stringified JSON object of custom data", + "required": false + }, + { + "parameter": "split_code", + "description": "The split code of the transaction split", + "required": false + }, + { + "parameter": "subaccount", + "description": "The code for the subaccount that owns the payment", + "required": false + }, + { + "parameter": "transaction_charge", + "description": "A flat fee to charge the subaccount for a transaction. \nThis overrides the split percentage set when the subaccount was created", + "required": false + }, + { + "parameter": "bearer", + "description": "The bearer of the transaction charge", + "required": false + }, + { + "parameter": "ussd", + "description": "USSD type to charge (don't send if charging an authorization code, bank or card)", + "required": false + }, + { + "parameter": "mobile_money", + "description": "Mobile details (don't send if charging an authorization code, bank or card)", + "required": false + }, + { + "parameter": "authorization_code", + "description": "An authorization code to charge (don't send if charging a bank account)", + "required": false + }, + { + "parameter": "bank", + "description": "Bank account to charge (don't send if charging an authorization code)", + "required": false + } + ], + "api": "create", + "parent": "charge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "charge/submit_pin", + "method": "POST", + "params": [ + { + "parameter": "pin", + "description": "(Required) Customer's PIN", + "required": true + }, + { + "parameter": "reference", + "description": "(Required) Transaction reference that requires the PIN", + "required": true + } + ], + "api": "submit_pin", + "parent": "charge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "charge/submit_otp", + "method": "POST", + "params": [ + { + "parameter": "otp", + "description": "(Required) Customer's OTP", + "required": true + }, + { + "parameter": "reference", + "description": "(Required) The reference of the ongoing transaction", + "required": true + } + ], + "api": "submit_otp", + "parent": "charge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "charge/submit_phone", + "method": "POST", + "params": [ + { + "parameter": "phone", + "description": "(Required) Customer's mobile number", + "required": true + }, + { + "parameter": "reference", + "description": "(Required) The reference of the ongoing transaction", + "required": true + } + ], + "api": "submit_phone", + "parent": "charge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "charge/submit_birthday", + "method": "POST", + "params": [ + { + "parameter": "birthday", + "description": "(Required) Customer's birthday in the format YYYY-MM-DD e.g 2016-09-21", + "required": true + }, + { + "parameter": "reference", + "description": "(Required) The reference of the ongoing transaction", + "required": true + } + ], + "api": "submit_birthday", + "parent": "charge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "charge/submit_address", + "method": "POST", + "params": [ + { + "parameter": "address", + "description": "(Required) Customer's address", + "required": true + }, + { + "parameter": "reference", + "description": "(Required) The reference of the ongoing transaction", + "required": true + }, + { + "parameter": "city", + "description": "(Required) Customer's city", + "required": true + }, + { + "parameter": "state", + "description": "(Required) Customer's state", + "required": true + }, + { + "parameter": "zipcode", + "description": "(Required) Customer's zipcode", + "required": true + } + ], + "api": "submit_address", + "parent": "charge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "charge/:reference", + "method": "GET", + "params": [], + "api": "check_pending", + "parent": "charge", + "variables": [ + { + "key": "reference", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + } + ], + "bulkcharge": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "bulkcharge/:code", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "bulkcharge", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Batch code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "bulkcharge/:code/charges", + "method": "GET", + "params": [], + "api": "fetch_charges", + "parent": "bulkcharge", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Batch code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "bulkcharge", + "method": "POST", + "params": [], + "api": "initiate", + "parent": "bulkcharge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "bulkcharge", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "bulkcharge" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "bulkcharge/pause/:code", + "method": "GET", + "params": [], + "api": "pause", + "parent": "bulkcharge", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Batch code" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "bulkcharge/resume/:code", + "method": "GET", + "params": [], + "api": "resume", + "parent": "bulkcharge", + "variables": [ + { + "key": "code", + "value": "in ipsum qui", + "description": "(Required) Batch code" + } + ] + } + ], + "paymentsessiontimeout": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "integration/payment_session_timeout", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "paymentsessiontimeout" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "integration/payment_session_timeout", + "method": "PUT", + "params": [ + { + "parameter": "timeout", + "description": "(Required) Time in seconds before a transaction becomes invalid", + "required": true + } + ], + "api": "update", + "parent": "paymentsessiontimeout" + } + ], + "refund": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "refund", + "method": "POST", + "params": [ + { + "parameter": "transaction", + "description": "(Required) Transaction reference or id", + "required": true + }, + { + "parameter": "amount", + "description": "Amount ( in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR ) to be refunded to the customer. \nAmount cannot be more than the original transaction amount", + "required": false + }, + { + "parameter": "currency", + "description": "Three-letter ISO currency", + "required": false + }, + { + "parameter": "customer_note", + "description": "Customer reason", + "required": false + }, + { + "parameter": "merchant_note", + "description": "Merchant reason", + "required": false + } + ], + "api": "create", + "parent": "refund" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "refund", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "refund" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "refund/:id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "refund", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + } + ], + "dispute": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute/:id", + "method": "GET", + "params": [], + "api": "fetch", + "parent": "dispute", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) Dispute ID" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute/:id", + "method": "PUT", + "params": [ + { + "parameter": "refund_amount", + "description": "(Required) The amount to refund, in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "uploaded_filename", + "description": "Filename of attachment returned via response from the Dispute upload URL", + "required": false + } + ], + "api": "update", + "parent": "dispute", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) Dispute ID" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute/:id/upload_url", + "method": "GET", + "params": [], + "api": "get_upload_url", + "parent": "dispute", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) Dispute ID" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute/:id/resolve", + "method": "PUT", + "params": [ + { + "parameter": "resolution", + "description": "(Required) Dispute resolution.", + "required": true + }, + { + "parameter": "message", + "description": "(Required) Reason for resolving", + "required": true + }, + { + "parameter": "refund_amount", + "description": "(Required) The amount to refund, in kobo if currency is NGN, pesewas, if currency is GHS, and cents, if currency is ZAR", + "required": true + }, + { + "parameter": "uploaded_filename", + "description": "(Required) Filename of attachment returned via response from the Dispute upload URL", + "required": true + }, + { + "parameter": "evidence", + "description": "Evidence Id for fraud claims", + "required": false + } + ], + "api": "resolve_a", + "parent": "dispute", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) Dispute ID" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute/:id/evidence", + "method": "POST", + "params": [ + { + "parameter": "customer_email", + "description": "(Required) Customer email", + "required": true + }, + { + "parameter": "customer_name", + "description": "(Required) Customer name", + "required": true + }, + { + "parameter": "customer_phone", + "description": "(Required) Customer mobile number", + "required": true + }, + { + "parameter": "service_details", + "description": "(Required) Details of service offered", + "required": true + }, + { + "parameter": "delivery_address", + "description": "Delivery address", + "required": false + }, + { + "parameter": "delivery_date", + "description": "ISO 8601 representation of delivery date (YYYY-MM-DD)", + "required": false + } + ], + "api": "add_evidence", + "parent": "dispute", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) Dispute ID" + } + ] + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "status", + "description": "Dispute Status.", + "required": false + }, + { + "parameter": "transaction", + "description": "Transaction ID", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "list", + "parent": "dispute" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute/export", + "method": "GET", + "params": [ + { + "parameter": "perPage", + "description": "Number of records to fetch per page", + "required": false + }, + { + "parameter": "page", + "description": "The section to retrieve", + "required": false + }, + { + "parameter": "status", + "required": false + }, + { + "parameter": "from", + "description": "The start date", + "required": false + }, + { + "parameter": "to", + "description": "The end date", + "required": false + } + ], + "api": "export", + "parent": "dispute" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "dispute/transaction/:id", + "method": "GET", + "params": [], + "api": "list_transaction", + "parent": "dispute", + "variables": [ + { + "key": "id", + "value": "in ipsum qui", + "description": "(Required) Transaction ID" + } + ] + } + ], + "bank": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "bank", + "method": "GET", + "params": [ + { + "parameter": "country", + "required": false + }, + { + "parameter": "pay_with_bank_transfer", + "required": false + }, + { + "parameter": "use_cursor", + "required": false + }, + { + "parameter": "perPage", + "required": false + }, + { + "parameter": "next", + "required": false + }, + { + "parameter": "previous", + "required": false + }, + { + "parameter": "gateway", + "required": false + } + ], + "api": "list", + "parent": "bank" + }, + { + "baseUrl": "https://api.paystack.co/", + "path": "bank/resolve", + "method": "GET", + "params": [ + { + "parameter": "account_number", + "required": false + }, + { + "parameter": "bank_code", + "required": false + } + ], + "api": "resolve", + "parent": "bank" + } + ], + "card": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "decision/bin/:bin", + "method": "GET", + "params": [], + "api": "resolve", + "parent": "card", + "variables": [ + { + "key": "bin", + "value": "in ipsum qui", + "description": "(Required) " + } + ] + } + ], + "country": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "country", + "method": "GET", + "params": [], + "api": "list", + "parent": "country" + } + ], + "avs": [ + { + "baseUrl": "https://api.paystack.co/", + "path": "address_verification/states", + "method": "GET", + "params": [ + { + "parameter": "type", + "required": false + }, + { + "parameter": "country", + "required": false + }, + { + "parameter": "currency", + "required": false + } + ], + "api": "list", + "parent": "avs" + } + ] +} \ No newline at end of file diff --git a/src/lib/paystack/apis.js b/src/lib/paystack/apis.js new file mode 100644 index 0000000..6e2bd8f --- /dev/null +++ b/src/lib/paystack/apis.js @@ -0,0 +1,2102 @@ +#!/usr/bin/env node +module.exports = { + subaccount: [ + { + api: 'update', + endpoint: 'https://api.paystack.co/subaccount', + method: 'PUT', + params: [ + { + parameter: 'business_name', + required: true, + type: 'String', + }, + { + parameter: 'settlement_bank', + required: true, + type: 'String', + }, + { + parameter: 'account_number', + required: true, + type: 'String', + }, + { + parameter: 'percentage_charge', + required: true, + type: 'String', + }, + { + parameter: 'primary_contact_email', + required: false, + type: 'String', + }, + { + parameter: 'primary_contact_name', + required: false, + type: 'String', + }, + { + parameter: 'primary_contact_phone', + required: false, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + { + parameter: 'settlement_schedule', + required: false, + type: 'String', + }, + ], + description: null, + }, + { + api: 'fetch', + endpoint: 'https://api.paystack.co/subaccount/{id}', + method: 'GET', + params: [ + { + parameter: 'id', + required: true, + type: 'String', + }, + ], + description: null, + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/subaccount', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve', + }, + { + api: 'create', + endpoint: 'https://api.paystack.co/subaccount', + method: 'POST', + params: [ + { + parameter: 'business_name', + required: true, + type: 'String', + }, + { + parameter: 'settlement_bank', + required: true, + type: 'String', + }, + { + parameter: 'account_number', + required: true, + type: 'String', + }, + { + parameter: 'percentage_charge', + required: true, + type: 'String', + }, + { + parameter: 'primary_contact_email', + required: false, + type: 'String', + }, + { + parameter: 'primary_contact_name', + required: false, + type: 'String', + }, + { + parameter: 'primary_contact_phone', + required: false, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + { + parameter: 'settlement_schedule', + required: false, + type: 'String', + }, + ], + description: '**Body Params**\n- **business_name** (_required_) - Name of business for subaccount\n- **settlement_bank** (_required_) - Name of Bank (see list of accepted names by calling [List Banks](https://developers.paystack.co/v1.0/docs/list-banks)\n- **account_number** (_required_) - NUBAN Bank Account Number\n- **percentage_charge** (_required_) - What is the default percentage charged when receiving on behalf of this subaccount?\n- **primary_contact_email** - A contact email for the subaccount\n- **primary_contact_name** - A name for the contact person for this subaccount\n- **primary_contact_phone** - A phone number to call for this subaccount\n- **metadata** - Stringified JSON object\n- **settlement_schedule** - Any of `auto`, `weekly`, `monthly`, `manual`. Auto means payout is T+1 and manual means payout to the subaccount should only be made when requested.\n\nReceive payments for the created subaccount by providing their code when doing a transaction. More details here: [Split Payments Overview](https://developers.paystack.co/v1.0/docs/split-payments-overview)', + }, + ], + page: [ + { + api: 'update', + endpoint: 'https://api.paystack.co/page/', + method: 'PUT', + params: [ + { + parameter: 'name', + required: false, + type: 'String', + }, + { + parameter: 'description', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + { + parameter: 'active', + required: false, + type: 'String', + }, + ], + description: '**Body Params**\n- **name** - Name of page\n- **description** - Short description of page\n- **amount** - Amount to be charged in kobo. Will override the amount for existing subscriptions.\n- **active** - Set to false to deactivate page url.', + }, + { + api: 'fetch', + endpoint: 'https://api.paystack.co/page/id_or_plan_code', + method: 'GET', + params: [], + description: null, + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/page', + method: 'GET', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + { + parameter: 'interval', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **interval** - Filter list by plans with specified interval\n- **amount** - Filter list by plans with specified amount (in kobo)', + }, + { + api: 'check', + endpoint: 'https://api.paystack.co/page/check_slug_availability/{slug}', + method: 'GET', + params: [ + { + parameter: 'slug', + required: true, + type: 'String', + }, + ], + description: '**Path Params**\n- **slug** (_required_) - URL slug to be confirmed', + }, + { + api: 'create', + endpoint: 'https://api.paystack.co/page', + method: 'POST', + params: [ + { + parameter: 'name', + required: true, + type: 'String', + }, + { + parameter: 'description', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + { + parameter: 'slug', + required: false, + type: 'String', + }, + { + parameter: 'redirect_url', + required: false, + type: 'String', + }, + { + parameter: 'send_invoices', + required: false, + type: 'String', + }, + { + parameter: 'custom_fields', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **name** (_required_) - Name of page\n- **description** - Short description of page\n- **amount** - Default amount you want to accept using this page. If none is set, customer is free to provide any amount of their choice. The latter scenario is useful for accepting donations\n- **slug** - URL slug you would like to be associated with this page. Page will be accessible at https://paystack.com/pay/[slug]\n- **redirect_url** - If you would like Paystack to redirect someplace upon successful payment, specify the URL here.\n- **send_invoices** - Set to false if you don't want invoices to be sent to your customers\n- **custom_fields** - If you would like to accept custom fields, specify them here. See sample code for details.\n\nSend pages created to your customers by giving out a link in this format https://paystack.com/pay/:slug. For instance, a valid link for the page above would be https://paystack.com/pay/5nApBwZkvY", + }, + ], + transfer: [ + { + api: 'list', + endpoint: 'https://api.paystack.co/transfer', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve', + }, + { + api: 'finalize', + endpoint: 'https://api.paystack.co/transfer/finalize_transfer', + method: 'POST', + params: [ + { + parameter: 'transfer_code', + required: true, + type: 'String', + }, + { + parameter: 'otp', + required: true, + type: 'String', + }, + ], + description: '**Body Params**\n- **transfer_code** (_required_) - Transfer code\n- **otp** (_required_) - OTP sent to business phone to verify transfer.', + }, + { + api: 'initiate', + endpoint: 'https://api.paystack.co/transfer', + method: 'POST', + params: [ + { + parameter: 'source', + required: true, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'reason', + required: false, + type: 'String', + }, + { + parameter: 'recipient', + required: true, + type: 'String', + }, + { + parameter: 'reference', + required: false, + type: 'String', + }, + ], + description: 'Status of transfer object returned will be ‘pending’ if OTP is disabled. In the event that an OTP is required, status will read ‘otp’.\n\n**Body Params**\n- **source** (_required_) - Where should we transfer from? Only balance for now\n- **amount** - Amount to transfer in kobo\n- **currency** - NGN\n- **reason**\n- **recipient** (_required_) - Code for transfer recipient\n- **reference** - If specified, the field should be a unique identifier (in lowercase) for the object. Only `-` `,` `_` and alphanumeric characters allowed.', + }, + { + api: 'verify', + endpoint: 'https://api.paystack.co/transfer/{reference}', + method: 'GET', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'reference', + required: true, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve', + }, + { + api: 'disable', + endpoint: 'https://api.paystack.co/transfer/disable_otp', + method: 'POST', + params: [ + ], + description: 'In the event that you want to be able to complete transfers programmatically without use of OTPs, this endpoint helps disable that….with an OTP. No arguments required. You will get an OTP.\n\nIn the event that you want to be able to complete transfers programmatically without use of OTPs, this endpoint helps disable that….with an OTP. No arguments required. An OTP is sent to you on your business phone.', + }, + { + api: 'enable', + endpoint: 'https://api.paystack.co/transfer/enable_otp', + method: 'POST', + params: [], + description: 'In the event that a customer wants to stop being able to complete transfers programmatically, this endpoint helps turn OTP requirement back on. No arguments required.', + }, + { + api: 'initiate', + endpoint: 'https://api.paystack.co/transfer/bulk', + method: 'POST', + params: [ + + { + parameter: 'source', + required: true, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'transfers', + required: false, + type: 'Array', + }, + ], + description: 'You need to disable the Transfers OTP requirement to use this endpoint.\n\n**Body Params**\n- **(no name)**\n\nStatus of transfer object returned will be ‘pending’ if OTP is disabled. In the event that an OTP is required, status will read ‘otp’.', + }, + { + api: 'finalize', + endpoint: 'https://api.paystack.co/transfer/disable_otp_finalize', + method: 'POST', + params: [ + { + parameter: 'otp', + required: true, + type: 'String', + }, + + ], + description: '**Body Params**\n- **otp** (_required_) - OTP sent to business phone to verify disabling OTP requirement\n\n', + }, + { + api: 'fetch', + endpoint: 'https://api.paystack.co/transfer/code', + method: 'GET', + params: [ + { + parameter: 'code', + required: true, + type: 'String', + }, + ], + description: '**Path Params**\n- **id_or_code** (_required_) - An ID or code for the transfer whose details you want to retrieve.', + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/transfer/', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + ], + description: 'This lists all bulk charge batches created by the integration. Statuses can be `active`, `paused`, or `complete`.\n\n**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve', + }, + { + api: 'resend_otp', + endpoint: 'https://api.paystack.co/transfer/resend_otp', + method: 'POST', + params: [ + { + parameter: 'transfer_code', + required: true, + type: 'String', + }, + { + parameter: 'reason', + required: true, + type: 'String', + }, + ], + description: 'Creates a new recipient. An duplicate account number will lead to the retrieval of the existing record.\n\n**Body Params**\n- **transfer_code** (_required_) - Transfer code\n- **reason** (_required_) - either `resend_otp` or `transfer`', + }, + ], + paymentrequest: [ + { + api: 'create', + endpoint: 'https://api.paystack.co/paymentrequest', + method: 'POST', + params: [ + { + parameter: 'customer', + required: true, + type: 'String', + }, + { + parameter: 'due_date', + required: true, + type: 'String', + }, + { + parameter: 'amount', + required: true, + type: 'Number', + }, + { + parameter: 'description', + required: false, + type: 'String', + }, + { + parameter: 'line_items', + required: false, + type: 'String', + }, + { + parameter: 'tax', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'send_notification', + required: false, + type: 'String', + }, + { + parameter: 'draft', + required: false, + type: 'String', + }, + { + parameter: 'send_notification', + required: false, + type: 'String', + }, + { + parameter: 'has_invoice', + required: false, + type: 'String', + }, + { + parameter: 'invoice_number', + required: false, + type: 'String', + }, + ], + description: '**Body Params**\n- **customer** (_required_) - Customer ID or code\n- **due_date** (_required_) - ISO 8601 representation of request due date\n- **amount** (_required_) - Invoice amount. Only useful if line items and tax values are ignored. endpoint will throw a friendly warning if neither is available.\n- **description**\n- **line_items** - Array of line items in the format `[{"name":"item 1", "amount":2000}]`\n- **tax** - Array of taxes to be charged in the format `[{"name":"VAT", "amount":2000}]`\n- **currency** - Defaults to Naira\n- **send_notification** - Indicates whether Paystack sends an email notification to customer. Defaults to `true`.\n- **draft** - Indicate if request should be saved as draft. Defaults to `false` and overrides send_notification.\n- **send_notification** - Indicates whether Paystack sends an email notification to customer. Defaults to `true`.\n- **has_invoice** - Set to `true` to create a draft invoice (adds an auto incrementing invoice number if none is provided) even if there are no `line_items` or `tax` passed.\n- **invoice_number** - Numeric value of invoice. Invoice will start from 1 and auto increment from there. This field is to help override whatever value Paystack decides. Auto increment for subsequent invoices continue from this point.', + }, + { + api: 'finalize', + endpoint: 'https://api.paystack.co/paymentrequest/finalize/ID_OR_CODE', + method: 'POST', + params: [ + + { + parameter: 'Body Params', + required: false, + type: 'String', + }, + { + parameter: 'send_notification', + required: false, + type: 'String', + }, + ], + description: 'Publishes invoice that is draft by sending customer the invoice via email\n\n**Body Params**\n- **send_notification** - Indicates whether Paystack sends an email notification to customer. Defaults to `true`', + }, + { + api: 'send', + endpoint: 'https://api.paystack.co/paymentrequest/notify/ID_OR_CODE', + method: 'POST', + params: [ + { + parameter: 'id', + required: false, + type: 'String', + }, + ], + description: '**Path Params**\n- **id** - Invoice code for which you want to send a notification for', + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/paymentrequest', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'customer', + required: false, + type: 'String', + }, + { + parameter: 'status', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'paid', + required: false, + type: 'String', + }, + { + parameter: 'include_archive', + required: false, + type: 'String', + }, + { + parameter: 'payment_request', + required: false, + type: 'String', + }, + ], + description: "**Query Params**\n- **customer** - Specify an ID for the customer whose requests you want to retrieve\n- **status** - Filter requests by status ('failed', 'success', 'abandoned')\n- **currency** - Filter requests sent in a particular currency.\n- **paid** - Filter requests that have been paid for \n- **include_archive** - Includes archived requests in the response\n- **payment_request** - Filter specific invoice by passing invoice code", + }, + { + api: 'view', + endpoint: 'https://api.paystack.co/paymentrequest/REQUEST_ID_OR_CODE', + method: 'GET', + params: [ + { + parameter: 'id', + required: true, + type: 'String', + }, + ], + description: '**Path Params**\n- **id** _(required)_ - An ID for the Invoice', + }, + { + api: 'invoice', + endpoint: 'https://api.paystack.co/paymentrequest/totals', + method: 'GET', + params: [], + description: null, + }, + { + api: 'update', + endpoint: 'https://api.paystack.co/paymentrequest/ID_OR_CODE', + method: 'PUT', + params: [ + { + parameter: 'description', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + { + parameter: 'line_item', + required: false, + type: 'String', + }, + { + parameter: 'tax', + required: false, + type: 'String', + }, + { + parameter: 'due_date', + required: false, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + { + parameter: 'send_notification', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'customer', + required: false, + type: 'String', + }, + ], + description: '**Body Params**\n- **description**\n- **amount**\n- **line_item**\n- **tax**\n- **due_date**\n- **metadata**\n- **send_notification**\n- **currency** - only works in draft mode\n- **customer** - only works in draft mode', + }, + { + api: 'verify', + endpoint: 'https://api.paystack.co/paymentrequest/verify/{id}', + method: 'GET', + params: [ + { + parameter: 'id', + required: false, + type: 'String', + }, + ], + description: '**Path Params**\n- **ID** - The invoice code for the Payment Request to be verified\n\nNote that a key is added called `pending_amount` when you fetch an invoice. This is because when paying for an invoice, you can choose to pay part but not all. Whenever a successful transaction is made, the key updates to reveal what’s left of the invoice to pay.', + }, + ], + transferrecipient: [ + { + api: 'create', + endpoint: 'https://api.paystack.co/transferrecipient', + method: 'POST', + params: [ + + { + parameter: 'Body Params', + required: false, + type: 'String', + }, + { + parameter: 'type', + required: true, + type: 'String', + }, + { + parameter: 'name', + required: true, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + { + parameter: 'bank_code', + required: true, + type: 'String', + }, + { + parameter: 'account_number', + required: true, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'description', + required: false, + type: 'String', + }, + ], + description: 'Creates a new recipient. An duplicate account number will lead to the retrieval of the existing record.\n\n**Body Params**\n- **type** (_required_) - Recipient Type (Only nuban at this time)\n- **name** (_required_) - A name for the recipient\n- **metadata** - Store additional information about your recipient in a structured format. JSON\n- **bank_code** (_required_) - Required if type is nuban. You can find a list of bank codes at [api.paystack.co/bank](https://api.paystack.co/bank)\n- **account_number** (_required_) - Required if type is `nuban`\n- **currency** - Currency for the account receiving the transfer.\n- **description**', + }, + { + api: 'delete', + endpoint: 'https://api.paystack.co/transferrecipient', + method: 'DELETE', + params: [], + description: null, + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/transferrecipient', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve', + }, + { + api: 'update', + endpoint: '{recipient_code_or_id}', + method: 'PUT', + params: [], + description: null, + }, + ], + subscription: [ + { + api: 'disable', + endpoint: 'https://api.paystack.co/subscription/disable', + method: 'POST', + params: [ + { + parameter: 'code', + required: true, + type: 'String', + }, + { + parameter: 'token', + required: true, + type: 'String', + }, + ], + description: '**Body Params**\n- **code** (_required_) - Subscription code\n- **token** (_required_) - Email token', + }, + { + api: 'fetch', + endpoint: ':id_or_subscription_code', + method: 'GET', + params: [], + description: null, + }, + { + api: 'create', + endpoint: 'https://api.paystack.co/subscription', + method: 'POST', + params: [ + { + parameter: 'customer', + required: true, + type: 'String', + }, + { + parameter: 'plan', + required: true, + type: 'String', + }, + { + parameter: 'authorization', + required: false, + type: 'String', + }, + { + parameter: 'start_date', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **customer** (_required_) - Customer's email address or customer code\n- **plan** (_required_) - Plan code\n- **authorization** - If customer has multiple authorizations, you can set the desired authorization you wish to use for this subscription here. If this is not supplied, the customer's most recent authorization would be used\n- **start_date** - Set the date for the first debit. (ISO 8601 format)\n\nNote the `email_token` attribute for the subscription object. We create one on each subscription so customers can cancel their subscriptions from within the invoices sent to their mailboxes. Since they are not authorized, the email tokens are what we use to authenticate the requests over the API.", + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/subscription', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + { + parameter: 'customer', + required: false, + type: 'String', + }, + { + parameter: 'plan', + required: false, + type: 'String', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **customer** - Filter by Customer ID\n- **plan** - Filter by Plan ID', + }, + { + api: 'enable', + endpoint: 'https://api.paystack.co/subscription/enable', + method: 'POST', + params: [ + { + parameter: 'code', + required: true, + type: 'String', + }, + { + parameter: 'token', + required: true, + type: 'String', + }, + ], + description: '**Body Params**\n- **code** (_required_) - Subscription code\n- **token** (_required_) - Email token', + }, + ], + bulkcharge: [ + { + api: 'fetch', + endpoint: 'https://api.paystack.co/bulkcharge/{code}', + method: 'GET', + params: [ + + { + parameter: 'code', + required: true, + type: 'String', + }, + ], + description: 'This endpoint retrieves a specific batch code. It also returns useful information on its progress by way of the `total_charges` and `pending_charges` attributes.\n\n**Path Params**\n- **id_or_code** (_required_) - An ID or code for the transfer whose details you want to retrieve.', + }, + { + api: 'fetch', + endpoint: 'https://api.paystack.co/bulkcharge/{code}/charges', + method: 'GET', + params: [ + + { + parameter: 'code', + required: true, + type: 'String', + }, + + { + parameter: 'status', + required: false, + type: 'String', + }, + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + ], + description: 'This endpoint retrieves the charges associated with a specified batch code. Pagination parameters are available. You can also filter by status. Charge statuses can be `pending`, `success` or `failed`.\n\n**Path Params**\n- **id_or_code** (_required_) - An ID or code for the batch whose charges you want to retrieve.\n\n**Query Params**\n- **status** - `pending`, `success` or `failed`\n- **perPage**\n- **page**\n', + }, + { + api: 'initiate', + endpoint: 'https://api.paystack.co/bulkcharge', + method: 'POST', + params: [ + + { + parameter: 'Body Params', + required: false, + type: 'String', + }, + { + parameter: '(no_name)', + required: false, + type: 'String', + }, + ], + description: 'Send an array of objects with authorization codes and amount in kobo so we can process transactions as a batch.\n\n**Body Params**\n- **(no_name)**', + }, + { + api: 'resume', + endpoint: 'https://api.paystack.co/bulkcharge/resume/batch_code', + method: 'GET', + params: [ + + { + parameter: 'Path Params', + required: false, + type: 'String', + }, + { + parameter: 'batch_code', + required: true, + type: 'String', + }, + ], + description: 'Use this endpoint to pause processing a batch\n\n**Path Params**\n- **batch_code** (_required_)', + }, + { + api: 'pause', + endpoint: 'https://api.paystack.co/bulkcharge/pause/{code}', + method: 'GET', + params: [ + + { + parameter: 'code', + required: true, + type: 'String', + }, + ], + description: 'Use this endpoint to pause processing a batch\n\n**Path Params**\n- **batch_code** (_required_)', + }, + ], + bank: [ + { + api: 'list', + endpoint: 'https://api.paystack.co/bank', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'country', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'type', + required: false, + type: 'String', + }, + { + parameter: 'gateway', + required: false, + type: 'String', + }, + { + parameter: 'pay_with_bank', + required: false, + type: 'Boolean', + }, + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'use_cursor', + required: false, + type: 'String', + }, + { + parameter: 'previous', + required: false, + type: 'String', + }, + { + parameter: 'next', + required: false, + type: 'String', + }, + ], + description: null, + }, + { + api: 'resolve', + endpoint: 'https://api.paystack.co/bank/resolve', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'account_number', + required: true, + type: 'String', + }, + { + parameter: 'bank_code', + required: true, + type: 'String', + }, + ], + description: 'This endpoint can be used to confirm that an account number and bank code match. It returns the following details: Account name, Account number and Bank ID', + }, + ], + identity: [ + { + api: 'resolve_bvn', + endpoint: 'https://api.paystack.co/bank/resolve_bvn/{bvn}', + method: 'GET', + params: [ + { + parameter: 'bvn', + required: true, + type: 'String', + }, + ], + description: 'The Resolve BVN service helps you build a KYC profile for a Nigeria-based customer using their BVN.', + }, + { + api: 'resolve_bvn_premium', + endpoint: 'https://api.paystack.co/identity/bvn/resolve/{bvn}', + method: 'GET', + params: [ + { + parameter: 'bvn', + required: true, + type: 'String', + }, + ], + description: 'The Resolve BVN service helps you build a KYC profile for a Nigeria-based customer using their BVN.', + }, + { + api: 'match_bvn', + endpoint: 'https://api.paystack.co/bvn/match', + method: 'POST', + params: [ + + { + parameter: 'bvn', + required: false, + type: 'String', + }, + { + parameter: 'account_number', + required: true, + type: 'String', + }, + { + parameter: 'bank_code', + required: true, + type: 'String', + }, + { + parameter: 'first_name', + required: true, + type: 'String', + }, + { + parameter: 'last_name', + required: true, + type: 'String', + }, + ], + description: 'The BVN Match service allows you to verify that an account number, first name, last name and middle name of a user matches their BVN.', + }, + { + api: 'resolve_card_bin', + endpoint: 'https://api.paystack.co/decision/bin/{bin)', + method: 'GET', + params: [ + { + parameter: 'bin', + required: true, + type: 'String', + }, + ], + description: 'Get more information about a customer\'s card', + }, + ], + charge: [ + { + api: 'submit', + endpoint: 'https://api.paystack.co/charge/submit_otp', + method: 'POST', + params: [ + + { + parameter: 'Body Params', + required: false, + type: 'String', + }, + { + parameter: 'otp', + required: true, + type: 'String', + }, + { + parameter: 'reference', + required: true, + type: 'String', + }, + ], + description: 'Submit OTP to complete a charge\n\n**Body Params**\n- **otp** (_required_) - OTP submitted by user\n- **reference** (_required_) - reference for ongoing transaction', + }, + { + api: 'submit', + endpoint: 'https://api.paystack.co/charge/submit_pin', + method: 'POST', + params: [ + { + parameter: 'pin', + required: true, + type: 'String', + }, + { + parameter: 'reference', + required: true, + type: 'String', + }, + ], + description: '**Body Params**\n- **pin** (_required_) - PIN submitted by user\n- **reference** (_required_) - reference for transaction that requested pin', + }, + { + api: 'submit', + endpoint: 'https://api.paystack.co/charge/submit_birthday', + method: 'POST', + params: [ + + { + parameter: 'Body Params', + required: false, + type: 'String', + }, + { + parameter: 'birthday', + required: true, + type: 'String', + }, + { + parameter: 'reference', + required: true, + type: 'String', + }, + ], + description: 'Submit Birthday when requested\n\n**Body Params**\n- **birthday** (_required_) - Birthday number submitted by user\n- **reference** (_required_) - reference for ongoing transaction', + }, + { + api: 'tokenize', + endpoint: 'https://api.paystack.co/charge/tokenize', + method: 'POST', + params: [ + + { + parameter: 'email', + required: true, + type: 'String', + }, + { + parameter: 'card', + required: true, + type: 'String', + }, + { + parameter: 'card.number', + required: true, + type: 'String', + }, + { + parameter: 'card.cvv', + required: true, + type: 'String', + }, + { + parameter: 'card.expiry_month', + required: true, + type: 'String', + }, + { + parameter: 'card.expiry_year', + required: true, + type: 'String', + }, + ], + description: "Send an array of objects with authorization codes and amount in kobo so we can process transactions as a batch.\n\n**Body Params**\n- **email** (_required_) - Customer's email address\n- **card** (_required_) - Card to tokenize\n- **card.number** (_required_) - Card to tokenize\n- **card.cvv** (_required_) - Card security code\n- **card.expiry_month** (_required_) - Expiry month of card\n- **card.expiry_year** (_required_) - Expiry year of card\n", + }, + { + api: 'check', + endpoint: 'https://api.paystack.co/charge/{reference}', + method: 'GET', + params: [ + { + parameter: 'reference', + required: true, + type: 'String', + }, + ], + description: "When you get \"pending\" as a charge status, wait 30 seconds or more, then make a check to see if its status has changed. Don't call too early as you may get a lot more pending than you should.\n\n**Body Params**\n- **reference** (_required_) - The reference to check", + }, + { + api: 'charge', + endpoint: 'https://api.paystack.co/charge', + method: 'POST', + params: [ + { + parameter: 'email', + required: true, + type: 'String', + }, + { + parameter: 'amount', + required: true, + type: 'Number', + }, + { + parameter: 'card', + required: true, + type: 'String', + }, + { + parameter: 'card.number', + required: true, + type: 'String', + }, + { + parameter: 'card.cvv', + required: true, + type: 'String', + }, + { + parameter: 'card.expiry_month', + required: true, + type: 'String', + }, + { + parameter: 'card.expiry_year', + required: true, + type: 'String', + }, + { + parameter: 'bank', + required: false, + type: 'String', + }, + { + parameter: 'bank.code', + required: true, + type: 'String', + }, + { + parameter: 'bank.account_number', + required: true, + type: 'String', + }, + { + parameter: 'authorization_code', + required: false, + type: 'String', + }, + { + parameter: 'pin', + required: false, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + ], + description: "Send card details or bank details or authorization code to start a charge.\nSimple guide to charging cards directly https://developers.paystack.co/docs/charging-from-your-backend\n\n**Body Params**\n- **email** (_required_) - Customer's email address\n- **amount** (_required_) - Amount in kobo\n- **card** (_required_) - Card number\n- **card.number** (_required_) - Card to tokenize\n- **card.cvv** (_required_) - Card security code\n- **card.expiry_month** (_required_) - Expiry month of card\n- **card.expiry_year** (_required_) - Expiry year of card\n- **bank** - Bank account to charge (don't send if charging an authorization code or card)\n- **bank.code** (_required_) - A code for the [bank](https://developers.paystack.co/v1.0/ref/banks) (check banks for the banks supported). Only the ones for which paywithbank is true will work.\n- **bank.account_number** (_required_) - 10 digit nuban for the account to charge\n- **authorization_code** - An authorization code to charge (don't send if charging a card or bank account)\n- **pin** - 4-digit PIN (send with a non-reusable authorization code)\n- **metadata** - A JSON object", + }, + { + api: 'submit', + endpoint: 'https://api.paystack.co/charge/submit_phone', + method: 'POST', + params: [ + { + parameter: 'phone', + required: true, + type: 'String', + }, + { + parameter: 'reference', + required: true, + type: 'String', + }, + ], + description: 'Submit Phone when requested\n\n**Body Params**\n- **phone** (_required_) - Phone number submitted by user\n- **reference** (_required_) - reference for ongoing transaction', + }, + ], + transaction: [ + { + api: 'verify', + endpoint: 'https://api.paystack.co/transaction/verify/{reference}', + method: 'GET', + params: [ + { + parameter: 'reference', + required: true, + type: 'String', + }, + ], + description: '**Path Params**\n- **reference** (_required_)', + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/transaction', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + { + parameter: 'customer', + required: false, + type: 'String', + }, + { + parameter: 'status', + required: false, + type: 'String', + }, + { + parameter: 'from', + required: false, + type: 'String', + }, + { + parameter: 'to', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + ], + description: "**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **customer** - Specify an ID for the customer whose transactions you want to retrieve\n- **status** - Filter transactions by status ('failed', 'success', 'abandoned')\n- **from** - A timestamp from which to start listing transaction e.g. 2016-09-24T00:00:05.000Z, 2016-09-21\n- **to** - A timestamp at which to stop listing transaction e.g. 2016-09-24T00:00:05.000Z, 2016-09-21\n- **amount** - Filter transactions by amount. Specify the amount in kobo.", + }, + { + api: 'view', + endpoint: 'https://api.paystack.co/transaction/{id}', + method: 'GET', + params: [ + { + parameter: 'id', + required: true, + type: 'String', + }, + ], + description: null, + }, + { + api: 'charge', + endpoint: 'https://api.paystack.co/transaction/charge_authorization', + method: 'POST', + params: [ + { + parameter: 'reference', + required: false, + type: 'String', + }, + { + parameter: 'authorization_code', + required: true, + type: 'String', + }, + { + parameter: 'amount', + required: true, + type: 'Number', + }, + { + parameter: 'plan', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'email', + required: true, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + { + parameter: 'subaccount', + required: false, + type: 'String', + }, + { + parameter: 'transaction_charge', + required: false, + type: 'String', + }, + { + parameter: 'bearer', + required: false, + type: 'String', + }, + { + parameter: 'invoice_limit', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **reference** - Unique transaction reference. Only `-` `,` `.` `,` `=` and alphanumeric characters allowed. System will generate one if none is provided\n- **authorization_code** - (_required_) Valid authorization code to charge\n- **amount** - (_required_) Amount in kobo\n- **plan** - If transaction is to create a subscription to a predefined plan, provide plan code here\n- **currency** - Currency in which amount should be charged\n- ** email** (_required_) - Customer's email address\n- **metadata** - Add a `custom_fields` attribute which has an array of objects if you would like the fields to be added to your transaction when displayed on the dashboard.\n- **subaccount** - The code for the subaccount that owns the payment.\n- **transaction_charge** - A flat fee to charge the subaccount for this transaction, in kobo. This overrides the split percentage set when the subaccount was created. Ideally, you will need to use this if you are splitting in flat rates (since subaccount creation only allows for percentage split).\n- **bearer** - Who bears Paystack charges? `account` or `subaccount`?\n- **invoice_limit** - Number of invoices to raise during the subscription. Overrides `invoice_limit` set on plan.", + }, + { + api: 'export', + endpoint: 'https://api.paystack.co/transaction/export', + method: 'GET', + params: [ + { + parameter: 'from', + required: false, + type: 'String', + }, + { + parameter: 'to', + required: false, + type: 'String', + }, + { + parameter: 'settled', + required: false, + type: 'String', + }, + { + parameter: 'payment_page', + required: false, + type: 'String', + }, + { + parameter: 'customer', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'settlement', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + { + parameter: 'status', + required: false, + type: 'String', + }, + ], + description: "**Query Params**\n- **from** - Lower bound of date range. Leave undefined to export transactions from day one.\n- **to** - Upper bound of date range. Leave undefined to export transactions till date.\n- **settled** - Set to `true` to export only settled transactions. `false` for pending transactions. Leave undefined to export all transactions\n- **payment_page** - Specify a payment page's id to export only transactions conducted on said page\n- **customer** - Specify customer id.\n- **currency** - Currency in which you are charging the customer in.\n- **settlement** - An ID for the settlement whose transactions we should export\n- **amount** - Amount for transactions to export\n- **status** - Status for transactions to export", + }, + { + api: 'check', + endpoint: 'https://api.paystack.co/transaction/check_authorization', + method: 'POST', + params: [ + + { + parameter: 'authorization_code', + required: true, + type: 'String', + }, + { + parameter: 'amount', + required: true, + type: 'Number', + }, + { + parameter: 'email', + required: true, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + ], + description: "All mastercard and visa authorizations can be checked with this endpoint to know if they have funds for the payment you seek.\n\n**Body Params**\n- **authorization_code** (_required_) - Authorization code for mastercard or VISA authorization belonging to email.\n- **amount** (_required_) - Amount in kobo\n- **email** (_required_) - Customer's email address\n- **currency** - A currency for the amount we want to check\n\nIn test mode, we will return insufficient funds for an amount greater than or equal 500,000 naira.", + }, + { + api: 'transaction', + endpoint: 'https://api.paystack.co/transaction/totals', + method: 'GET', + params: [ + { + parameter: 'from', + required: false, + type: 'String', + }, + { + parameter: 'to', + required: false, + type: 'String', + }, + ], + description: 'Total amount received on your account\n\n**Query Params**\n- **from** - Lower bound of date range. Leave undefined to show totals from day one.\n- **to** - Upper bound of date range. Leave undefined to show totals till date.', + }, + { + api: 'initialize', + endpoint: 'https://api.paystack.co/transaction/initialize', + method: 'POST', + params: [ + { + parameter: 'email', + required: true, + type: 'String', + }, + { + parameter: 'amount', + required: true, + type: 'Number', + }, + { + parameter: 'reference', + required: false, + type: 'String', + }, + { + parameter: 'callback_url', + required: false, + type: 'String', + }, + { + parameter: 'plan', + required: false, + type: 'String', + }, + { + parameter: 'invoice_limit', + required: false, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + { + parameter: 'subaccount', + required: false, + type: 'String', + }, + { + parameter: 'transaction_charge', + required: false, + type: 'String', + }, + { + parameter: 'bearer', + required: false, + type: 'String', + }, + { + parameter: 'channels', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **email** (_required_) - Customer's email address\n- **amount** (_required_) - Amount in kobo\n- **reference** - Generate a reference or leave this param blank for Paystack to generate one for you\n- **callback_url** - Overrides the callback URL set on Paystack dashboard.\n- **plan** - If transaction is to create a subscription to a predefined plan, provide plan code here. This would invalidate the value provided in `amount`\n- **invoice_limit** - Number of times to charge customer during subscription to plan\n- **metadata** - Stringified JSON object. Add a `custom_fields` attribute which has an array of objects if you would like the fields to be added to your transaction when displayed on the dashboard.\n- **subaccount** - The code for the subaccount that owns the payment.\n- **transaction_charge** - A flat fee to charge the subaccount for this transaction, in kobo. This overrides the split percentage set when the subaccount was created. Ideally, you will need to use this if you are splitting in flat rates (since subaccount creation only allows for percentage split).\n- **bearer** - Who bears Paystack charges? `account` or `subaccount` (defaults to `account`).\n- **channels** - Send us 'card' or 'bank' or 'card','bank' as an array to specify what options to show the user paying", + }, + { + api: 'fetch', + endpoint: 'https://api.paystack.co/transaction/id', + method: 'GET', + params: [ + { + parameter: 'id', + required: true, + type: 'String', + }, + ], + description: '**Path Params**\n- **id** (_required_) - An ID for the transaction to fetch', + }, + ], + plan: [ + { + api: 'update', + endpoint: 'https://api.paystack.co/plan/:id_or_plan_code', + method: 'PUT', + params: [ + { + parameter: 'name', + required: false, + type: 'String', + }, + { + parameter: 'description', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + { + parameter: 'interval', + required: false, + type: 'String', + }, + { + parameter: 'send_invoices', + required: false, + type: 'String', + }, + { + parameter: 'send_sms', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'invoice_limit', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **name** - Name of plan\n- **description** - Short description of plan\n- **amount** - Amount to be charged in kobo. Will override the amount for existing subscriptions.\n- **interval** - Interval in words. Valid intervals are `hourly`, `daily`, `weekly`, `monthly`, `annually`.\n- **send_invoices** - Set to false if you don't want invoices to be sent to your customers.\n- **send_sms** - Set to false if you don't want text messages to be sent to your customers\n- **currency** - Currency in which amount is set\n- **invoice_limit** - Number of invoices to raise during subscription to this plan. Will not override `invoice_limit` set on active subscriptions.", + }, + { + api: 'create', + endpoint: 'https://api.paystack.co/plan', + method: 'POST', + params: [ + { + parameter: 'name', + required: true, + type: 'String', + }, + { + parameter: 'description', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: true, + type: 'Number', + }, + { + parameter: 'interval', + required: true, + type: 'String', + }, + { + parameter: 'send_invoices', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'invoice_limit', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **name** (_required_) - Name of plan\n- **description** - Short description of plan\n- **amount** (_required_) - Amount to be charged in kobo\n- **interval** (_required_) - Interval in words. Valid intervals are `hourly`, `daily`, `weekly`, `monthly`, `annually`.\n- **send_invoices** - Set to false if you don't want invoices to be sent to your customers\n- **currency** - Currency in which amount is set\n- **invoice_limit** - Number of invoices to raise during subscription to this plan. Can be overridden by specifying an `invoice_limit` while subscribing.", + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/plan', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + { + parameter: 'interval', + required: false, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve\n- **interval** - Filter list by plans with specified interval\n- **amount** - Filter list by plans with specified amount (in kobo)', + }, + { + api: 'fetch', + endpoint: 'https://api.paystack.co/plan/id_or_plan_code', + method: 'GET', + params: [], + description: null, + }, + ], + customer: [ + { + api: 'update', + endpoint: 'https://api.paystack.co/customer/{id}', + method: 'PUT', + params: [ + { + parameter: 'first_name', + required: false, + type: 'String', + }, + { + parameter: 'last_name', + required: false, + type: 'String', + }, + { + parameter: 'phone', + required: false, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + { + parameter: 'id', + required: true, + type: 'Number', + }, + ], + description: "**Body Params**\n- **first_name** - Customer's first name\n- **last_name** - Customer's last name\n- **phone** - Customer's phone number\n- **metadata** - A set of key/value pairs that you can attach to the customer. It can be used to store additional information in a structured format.", + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/customer', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'perPage', + required: false, + type: 'String', + }, + { + parameter: 'page', + required: false, + type: 'Number', + }, + ], + description: '**Query Params**\n- **perPage** - Specify how many records you want to retrieve per page\n- **page** - Specify exactly what page you want to retrieve', + }, + { + api: 'create', + endpoint: 'https://api.paystack.co/customer', + method: 'POST', + params: [ + { + parameter: 'email', + required: true, + type: 'String', + }, + { + parameter: 'first_name', + required: false, + type: 'String', + }, + { + parameter: 'last_name', + required: false, + type: 'String', + }, + { + parameter: 'phone', + required: false, + type: 'String', + }, + { + parameter: 'metadata', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **email** (_required_) - Customer's email address\n- **first_name** - Customer's first name\n- **last_name** - Customer's last name\n- **phone** - Customer's phone number\n- **metadata** - A set of key/value pairs that you can attach to the customer. It can be used to store additional information in a structured format.", + }, + { + api: 'fetch', + endpoint: ':id_or_customer_code', + method: 'GET', + params: [ + { + parameter: 'exclude_transactions', + required: false, + type: 'String', + }, + ], + description: '**Query Params**\n- **exclude_transactions** - By default, fetching a customer returns all their transactions. Set this to true to disable this behaviour.', + }, + { + api: 'set_risk_action', + endpoint: 'https://api.paystack.co/customer/set_risk_action', + method: 'POST', + params: [ + { + parameter: 'customer', + required: false, + type: 'String', + }, + { + parameter: 'risk_action', + required: false, + type: 'String', + }, + ], + description: "**Body Params**\n- **customer** - Customer's ID, code, or email address\n- **risk_action** - One of the possible risk actions. `allow` to whitelist. `deny` to blacklist.", + }, + { + api: 'deactivate', + endpoint: 'https://api.paystack.co/customer/deactivate_authorization', + method: 'POST', + params: [ + + { + parameter: 'authorization_code', + required: true, + type: 'String', + }, + ], + description: 'For when the card needs to be forgotten...\n\n**Body Params**\n- **authorization_code** (_required_) - Authorization code to be deactivated\n\n', + }, + ], + refund: [ + { + api: 'create', + endpoint: 'https://api.paystack.co/refund', + method: 'POST', + params: [ + + { + parameter: 'Body Params', + required: false, + type: 'String', + }, + { + parameter: 'transaction', + required: true, + type: 'String', + }, + { + parameter: 'amount', + required: false, + type: 'Number', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + { + parameter: 'customer_note', + required: false, + type: 'String', + }, + { + parameter: 'merchant_note', + required: false, + type: 'String', + }, + ], + description: 'This creates a refund which is then processed by the Paystack team\n\n**Body Params**\n- **transaction** _(required)_: Identifier for transaction to be refunded\n- **amount** _(optional)_: How much in kobo to be refunded to the customer. Amount is optional(defaults to original transaction amount) and cannot be more than the original transaction amount.\n- **currency**: Three-letter ISO currency\n- **customer_note** _(optional)_: customer reason\n- **merchant_note** _(optional)_: merchant reason', + }, + { + api: 'fetch', + endpoint: ':id', + method: 'GET', + params: [ + { + parameter: 'id', + required: false, + type: 'String', + }, + ], + description: '**Path Params**\n- **id** - ID of the transaction to be refunded', + }, + { + api: 'fetch', + endpoint: ':id', + method: 'GET', + params: [ + { + parameter: 'id', + required: false, + type: 'String', + }, + ], + description: '**Path Params**\n- **id** - ID of the transaction to be refunded', + }, + { + api: 'list', + endpoint: 'https://api.paystack.co/refund', + method: 'GET', + parameterType: 'query', + params: [ + + { + parameter: 'transaction', + required: false, + type: 'String', + }, + { + parameter: 'currency', + required: false, + type: 'String', + }, + ], + description: '**Query Parameters**\n\n- **transaction**\n- **currency**', + }, + ], + integration: [ + { + api: 'update', + endpoint: 'https://api.paystack.co/integration/payment_session_timeout', + method: 'PUT', + params: [ + { + parameter: 'timeout', + required: false, + type: 'String', + }, + ], + description: ' Time before stopping session (in seconds). Set to 0 to cancel session timeouts', + }, + { + api: 'fetch', + endpoint: 'https://api.paystack.co/integration/payment_session_timeout', + method: 'GET', + params: [], + description: null, + }, + ], + balance: [ + { + api: 'check', + endpoint: 'https://api.paystack.co/balance', + method: 'GET', + params: [], + description: 'You can only transfer from what you have', + }, + { + api: 'ledger', + endpoint: 'https://api.paystack.co/balance/ledger', + method: 'GET', + params: [], + description: 'Returns all activity carried out from and to the Paystack Balance', + }, + ], + settlement: [ + { + api: 'fetch', + endpoint: 'https://api.paystack.co/settlement', + method: 'GET', + parameterType: 'query', + params: [ + { + parameter: 'from', + required: false, + type: 'String', + }, + { + parameter: 'to', + required: false, + type: 'String', + }, + { + parameter: 'subaccount', + required: false, + type: 'String', + }, + ], + description: 'Settlements made to your bank accounts and the bank accounts for your subaccounts\n\n**Query Params**\n- **from** - Lower bound of date range. Leave undefined to export settlement from day one.\n- **to** - Upper bound of date range. Leave undefined to export settlements till date.\n- **subaccount** - Provide a subaccount code to export only settlements for that subaccount. Set to `none` to export only transactions for the account.', + }, + ], + invoice: [ + { + api: 'archive', + endpoint: ':id_or_code', + method: 'POST', + params: [], + description: 'Used to archive an invoice. Invoice will no longer be fetched on list or returned on verify.', + }, + ], + verifications: [ + { + api: 'resolve', + endpoint: 'p', + method: 'POST', + params: [ + + { + parameter: 'Body Parameters', + required: false, + type: 'String', + }, + { + parameter: 'verification_type', + required: true, + type: 'String', + }, + { + parameter: 'phone', + required: true, + type: 'String', + }, + { + parameter: 'callback_url', + required: false, + type: 'String', + }, + ], + description: "Using the Truecaller API you can verify the authenticity of a customer. It returns the customer's name, phone number, email, social media handles and organization as available on their Truecaller profile.\n\n**Body Parameters**\n- **verification_type** _(required)_\n- **phone** _(required)_ - Customer phone number starting with country code (without the + prefix)\n- **callback_url** - Link on server to receive the truecaller details", + }, + ], +} diff --git a/lib/Paystack/webhooks.js b/src/lib/paystack/webhooks.js similarity index 100% rename from lib/Paystack/webhooks.js rename to src/lib/paystack/webhooks.js diff --git a/src/lib/samples.js b/src/lib/samples.js new file mode 100644 index 0000000..08a86bc --- /dev/null +++ b/src/lib/samples.js @@ -0,0 +1,27 @@ +/* eslint-disable camelcase */ +module.exports = { + sample_vue: { + name: 'sample-vue', + description: 'A sample vue application for accepting donations using Paystack', + git: 'https://github.com/PaystackOSS/sample-vue', + init_commands: ['npm install', 'npm run serve'], + }, + sample_react: { + name: 'sample-react', + description: 'A sample vue application for accepting donnations using Paystack', + git: 'https://github.com/PaystackOSS/sample-react.git', + init_commands: ['yarn install', 'yarn start'], + }, + gift_store: { + name: 'sample-gift-store', + description: 'Lorem ipsum dolor sit amet', + git: 'https://github.com/PaystackOSS/sample-gift-store', + init_commands: ['npm install', 'npm run serve'], + }, + sneaker_store: { + name: 'Kix', + description: 'A sample sneakers store with Paystack checkout', + git: 'https://git@github.com:PaystackOSS/sample-kix.git', + init_commands: ['npm install', 'npm run serve'], + }, +}