diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4ced078 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +# CI pipeline for @neo-cheems/openpay +# Runs tests against Openpay sandbox on push/PR. +# Note: tests are integration tests that call the real Openpay sandbox API. +# They pass against a live sandbox; rate limits or downtime may cause +# non-deterministic failures. + +name: CI + +on: + push: + branches: [develop] + pull_request: + branches: [master] + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [24] + fail-fast: false + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: TypeScript build (type-check + compile) + run: npm run build + + - name: Run tests + run: npm test + timeout-minutes: 5 diff --git a/.gitignore b/.gitignore index 60b6509..fec4151 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ node_modules /npm-debug.log -.settings/org.eclipse.wst.jsdt.ui.superType.container -.settings/org.eclipse.wst.jsdt.ui.superType.name package-lock.json +/lib +/dist +.reasonix +.claude \ No newline at end of file diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 39f6616..0000000 --- a/.jshintrc +++ /dev/null @@ -1,122 +0,0 @@ -{ - // -------------------------------------------------------------------- - // JSHint Nodeclipse Configuration v0.11 - // Strict Edition with some relaxations and switch to Node.js, no `use strict` - // by Ory Band, Michael Haschke, Paul Verest - // https://github.com/Nodeclipse/nodeclipse-1/blob/master/org.nodeclipse.ui/templates/common-templates/.jshintrc - // JSHint Documentation is at http://www.jshint.com/docs/options/ - // JSHint Integration v0.9.9 comes with JSHInt 2.1.10 , see https://github.com/eclipsesource/jshint-eclipse - // -------------------------------------------------------------------- - // from https://gist.github.com/haschek/2595796 - // - // This is a options template for [JSHint][1], using [JSHint example][2] - // and [Ory Band's example][3] as basis and setting config values to - // be most strict: - // - // * set all enforcing options to true - // * set all relaxing options to false - // * set all environment options to false, except the node value - // * set all JSLint legacy options to false - // - // [1]: http://www.jshint.com/ - // [2]: https://github.com/jshint/node-jshint/blob/master/example/config.json //404 - // [3]: https://github.com/oryband/dotfiles/blob/master/jshintrc - // - // @author http://michael.haschke.biz/ - // @license http://unlicense.org/ - - // == Enforcing Options =============================================== - // - // These options tell JSHint to be more strict towards your code. Use - // them if you want to allow only a safe subset of JavaScript, very - // useful when your codebase is shared with a big number of developers - // with different skill levels. Was all true. - - "bitwise" : true, // Prohibit bitwise operators (&, |, ^, etc.). - "curly" : true, // Require {} for every new block or scope. - "eqeqeq" : true, // Require triple equals i.e. `===`. - "forin" : true, // Tolerate `for in` loops without `hasOwnPrototype`. - "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` - "latedef" : true, // Prohibit variable use before definition. - "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`. - "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`. - "noempty" : true, // Prohibit use of empty blocks. - "nonew" : true, // Prohibit use of constructors for side-effects. - "plusplus" : false, // Prohibit use of `++` & `--`. //coding style related only - "regexp" : true, // Prohibit `.` and `[^...]` in regular expressions. - "undef" : true, // Require all non-global variables be declared before they are used. - "strict" : false, // Require `use strict` pragma in every file. - "trailing" : true, // Prohibit trailing whitespaces. - - // == Relaxing Options ================================================ - // - // These options allow you to suppress certain types of warnings. Use - // them only if you are absolutely positive that you know what you are - // doing. Was all false. - "asi" : false, // Tolerate Automatic Semicolon Insertion (no semicolons). - "boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. - "debug" : false, // Allow debugger statements e.g. browser breakpoints. - "eqnull" : false, // Tolerate use of `== null`. - "es5" : true, // Allow EcmaScript 5 syntax. // es5 is default https://github.com/jshint/jshint/issues/1411 - "esnext" : false, // Allow ES.next (ECMAScript 6) specific features such as `const` and `let`. - "evil" : false, // Tolerate use of `eval`. - "expr" : false, // Tolerate `ExpressionStatement` as Programs. - "funcscope" : false, // Tolerate declarations of variables inside of control structures while accessing them later from the outside. - "globalstrict" : false, // Allow global "use strict" (also enables 'strict'). - "iterator" : false, // Allow usage of __iterator__ property. - "lastsemic" : false, // Tolerat missing semicolons when the it is omitted for the last statement in a one-line block. - "laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. - "laxcomma" : true, // Suppress warnings about comma-first coding style. - "loopfunc" : false, // Allow functions to be defined within loops. - "multistr" : false, // Tolerate multi-line strings. - "onecase" : false, // Tolerate switches with just one case. - "proto" : false, // Tolerate __proto__ property. This property is deprecated. - "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`. - "scripturl" : false, // Tolerate script-targeted URLs. - "smarttabs" : false, // Tolerate mixed tabs and spaces when the latter are used for alignmnent only. - "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`. - "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. - "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`. - "validthis" : false, // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function. - - // == Environments ==================================================== - // - // These options pre-define global variables that are exposed by - // popular JavaScript libraries and runtime environmentsβ€”such as - // browser or node.js. - "browser" : false, // Standard browser globals e.g. `window`, `document`. - "couch" : false, // Enable globals exposed by CouchDB. - "devel" : false, // Allow development statements e.g. `console.log();`. - "dojo" : false, // Enable globals exposed by Dojo Toolkit. - "jquery" : false, // Enable globals exposed by jQuery JavaScript library. - "mootools" : false, // Enable globals exposed by MooTools JavaScript framework. - "node" : true, // Enable globals available when code is running inside of the NodeJS runtime environment. - "nonstandard" : false, // Define non-standard but widely adopted globals such as escape and unescape. - "prototypejs" : false, // Enable globals exposed by Prototype JavaScript framework. - "rhino" : false, // Enable globals available when your code is running inside of the Rhino runtime environment. - "wsh" : false, // Enable globals available when your code is running as a script for the Windows Script Host. - - // == JSLint Legacy =================================================== - // - // These options are legacy from JSLint. Aside from bug fixes they will - // not be improved in any way and might be removed at any point. - "nomen" : false, // Prohibit use of initial or trailing underbars in names. - "onevar" : false, // Allow only one `var` statement per function. - "passfail" : false, // Stop on first error. - "white" : false, // Check against strict whitespace and indentation rules. - - // == Undocumented Options ============================================ - // - // While I've found these options in [example1][2] and [example2][3] - // they are not described in the [JSHint Options documentation][4]. - // - // [4]: http://www.jshint.com/options/ - - "maxerr" : 100, // Maximum errors before stopping. - "predef" : [ // Extra globals. - //"exampleVar", - //"anotherCoolGlobal", - //"iLoveDouglas" - ] - //, "indent" : 2 // Specify indentation spacing -} diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..a45fd52 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24 diff --git a/.project b/.project deleted file mode 100644 index 8ec7b5a..0000000 --- a/.project +++ /dev/null @@ -1,18 +0,0 @@ - - - openpay-node - - - - - - com.eclipsesource.jshint.ui.builder - - - - - - org.nodeclipse.ui.NodeNature - org.eclipse.wst.jsdt.core.jsNature - - diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 544f970..0000000 --- a/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ - language: node_js - node_js: - - "8" - before_install: - - "npm config set strict-ssl false" diff --git a/README.md b/README.md index c52d8f1..206fabb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,83 @@ ![Openpay nodejs](https://www.openpay.mx/img/github/nodejs.jpg) +> **πŸ“¦ v4.x (this branch):** Full TypeScript rewrite with strict mode, SOLID architecture, +> typed interfaces for every resource, and Node.js β‰₯ 24 LTS. +> The callback API is 100 % backwards-compatible with v2.x. +> See [Upgrading from v2.x](#upgrading-from-v2x) below. + +## Requirements + +- **Node.js β‰₯ 24.0.0** (active LTS) +- TypeScript β‰₯ 5.x (optional β€” types are bundled) + ## Installation -`npm install openpay` +```bash +npm install @neo-cheems/openpay +``` + +## Quick Start + +### JavaScript (callback API β€” backwards compatible) + +```js +var Openpay = require('@neo-cheems/openpay'); +var openpay = new Openpay('your_merchant_id', 'your_private_key', 'mx', false); + +openpay.charges.create({ + method: 'card', + card: { + card_number: '4111111111111111', + holder_name: 'John Doe', + expiration_year: '28', + expiration_month: '12', + cvv2: '110' + }, + amount: 200.00, + description: 'Service Charge' +}, function (error, body, response) { + if (error) return console.error(error); + console.log('Charge created:', body.id); +}); +``` + +### TypeScript (typed β€” zero `any`) + +```ts +import Openpay from '@neo-cheems/openpay'; +import type { + ChargeRequest, + CustomerRequest, + PayoutRequest, + Callback, +} from '@neo-cheems/openpay/types'; +import { OpenpayError } from '@neo-cheems/openpay/errors'; + +const openpay = new Openpay('your_merchant_id', 'your_private_key', 'mx', false); + +// All request data is fully typed +const charge: ChargeRequest = { + method: 'card', + card: { + card_number: '4111111111111111', + holder_name: 'John Doe', + expiration_year: '28', + expiration_month: '12', + cvv2: '110', + }, + amount: 200.00, + description: 'Service Charge', +}; + +openpay.charges.create(charge, (error, body, response) => { + if (error instanceof OpenpayError) { + console.error(`Openpay ${error.statusCode}: ${error.description}`); + return; + } + // body is typed as `unknown` β€” narrow it with your own guards + console.log('Charge created:', (body as Record).id); +}); +``` ## Documentation @@ -11,19 +86,107 @@ Full API documentation available at http://docs.openpay.mx/. ## Overview ```js -//class -var Openpay = require('openpay'); -//instantiation -var openpay = new Openpay(' your merchant id ', ' your private key ', [ isProduction ]); -//use the api -openpay.< resource_name >.< method_name >( ... ) +// Import +var Openpay = require('@neo-cheems/openpay'); +// or: import Openpay from '@neo-cheems/openpay'; + +// Instantiation (country code is optional, defaults to 'mx') +var openpay = new Openpay('your_merchant_id', 'your_private_key', 'mx', false); +// merchantId privateKey country isProduction + +// Use any resource +openpay..(params..., callback); +``` + +### Constructor parameters + +| Param | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `merchantId` | `string` | βœ… | β€” | Your Openpay merchant ID | +| `privateKey` | `string` | βœ… | β€” | Your Openpay private key (`sk_...`) | +| `countryCode` | `'mx' \| 'pe' \| 'co'` | β€” | `'mx'` | Country API endpoint | +| `isProductionReady` | `boolean` | β€” | `false` | `true` = production, `false` = sandbox | + +All methods accept a callback as the **last** argument. + +The callback signature is `function(error, body, response)`: +- `error` β€” `null` when the response status is 200, 201, or 204; otherwise an `Error` (or `OpenpayError` in v4) +- `body` β€” the parsed JSON response body (`null` on error) +- `response` β€” `{ statusCode, headers }` + +## Architecture (v4.x) + +The library follows **SOLID** principles and clean TypeScript patterns: + +``` +src/ + openpay.ts # Openpay client class (~170 lines) + base-resource.ts # Abstract base for all resources + http-client.ts # HttpClient interface + urllib implementation (DIP) + types.ts # Typed interfaces for all request/response shapes + errors.ts # OpenpayError, NetworkError, TimeoutError + stringify-params.ts # Native ES2022 query-string builder (no underscore) + url-utils.ts # URL bracket escaping + resources/ + merchant.ts # GET /{merchantId} + charges.ts # POST /{merchantId}/charges ... + payouts.ts # POST /{merchantId}/payouts ... + fees.ts # POST /{merchantId}/fees ... + plans.ts # CRUD /{merchantId}/plans ... + cards.ts # CRUD /{merchantId}/cards ... + customers.ts # CRUD + 6 sub-resources (cards, charges, transfers, ...) + webhooks.ts # CRUD /{merchantId}/webhooks ... + tokens.ts # CRUD /{merchantId}/tokens ... + checkouts.ts # CRUD /{merchantId}/checkouts ... + stores.ts # GET /stores (different base URL) + pse.ts # POST /{merchantId}/charges (PSE) + groups.ts # Group customers + charges + subscriptions +``` + +| Principle | How it's applied | +|-----------|-----------------| +| **S**ingle Responsibility | Each resource class handles exactly one API entity | +| **O**pen/Closed | New resources extend `BaseResource` without modifying existing code | +| **L**iskov Substitution | Every resource has a uniform `request()` / `list()` interface | +| **I**nterface Segregation | `HttpClient`, `Callback`, `OpenpayConfig` β€” small, focused contracts | +| **D**ependency Inversion | Resources depend on the `HttpClient` abstraction, not on `urllib` directly | + +## Upgrading from v2.x + +### What changed + +- **Node.js β‰₯ 24** is now required (was `>=0.6.x`) +- The library is written in **TypeScript** with `strict: true` +- The `underscore` dependency has been removed (native ES2022 replacements) +- Errors are `OpenpayError` instances with `.statusCode`, `.description`, `.category`, `.requestId` +- Constructor now accepts `countryCode` as the **third** argument: + +```js +// v2.x +new Openpay(merchantId, privateKey, isProduction); // old v2 signature + +// v4.x +new Openpay(merchantId, privateKey, countryCode, isProduction); ``` -All methods accept an optional callback as last argument. +### What still works -The callback function should follow the format: function(error, body, response) {...}. -* error: null if the response status code is 200, 201, 204 -* body: null if the response status code is different from 200, 201, 204 +- All `require('@neo-cheems/openpay')` / `require('openpay')` calls (legacy compat) +- Every resource method and signature +- The `error, body, response` callback pattern +- `setMerchantId()`, `setPrivateKey()`, `setProductionReady()`, `setTimeout()` +- All three country codes: `'mx'`, `'pe'`, `'co'` + +## Development + +To run the tests you'll need your sandbox credentials from your +[Dashboard](https://sandbox-dashboard.openpay.mx/): + +```bash +npm install +npm run build # compile TypeScript β†’ JavaScript +npm test # run the mocha test suite +``` ## Examples @@ -87,36 +250,6 @@ openpay.payouts.create(payout, function (error, body, response){ }); ``` -## Configuration -Before use the library will be necessary to set up your Merchant ID and Private key. - -```js -var Openpay = require('openpay'); -var openpay = new Openpay('your merchant id', 'your private key', 'mx', false); -openpay.setTimeout(30000); -``` - -In addition, you can set the merchant id, private key, and the mode like this - -```js -openpay.setMerchantId(' your merchant id '); -openpay.setPrivateKey(' your private key '); -openpay.setProductionReady(true) -``` - -Once configured the library, you can use it to interact with Openpay API services. - -## Development - -To run the tests you'll need your sandbox credentials: merchant id and private key from your [Dashboard](https://sandbox-dashboard.openpay.mx/): - -```bash -$ npm install -g mocha -$ npm test -``` - -# Implementation - ## Usage for Mexico ### Bank accounts diff --git a/lib/openpay.js b/lib/openpay.js deleted file mode 100644 index 9481603..0000000 --- a/lib/openpay.js +++ /dev/null @@ -1,988 +0,0 @@ -const urllib = require('urllib'); -const _ = require('underscore'); -var urlUtils = require('./url-utils') - -Openpay.BASE_URL = 'https://api.openpay.mx'; -Openpay.API_VERSION = '/v1/'; -Openpay.SANDBOX_URL = 'https://sandbox-api.openpay.mx'; -Openpay.SANDBOX_API_VERSION = '/v1/'; - - -function Openpay(merchantId, privateKey, countryCode = 'mx', isProductionReady) { - this.merchantId = merchantId; - this.privateKey = privateKey; - this.isSandbox = isProductionReady ? false : true; - this.timeout = 90000; - this.define({ - isSandbox: this.isSandbox, - privateKey: this.privateKey, - merchantId: this.merchantId, - timeout: this.timeout - }); - this.setBaseUrl(countryCode); - - this.setMerchantId = function (merchantId) { - this.merchantId = merchantId; - this._reDefine(); - }; - - this.setPrivateKey = function (privateKey) { - this.privateKey = privateKey; - this._reDefine(); - }; - - this.setProductionReady = function (isProductionReady) { - this.isSandbox = !isProductionReady; - this._reDefine(); - }; - - this.setTimeout = function (timeout) { - this.timeout = timeout; - this._reDefine(); - }; - - this._reDefine = function () { - this.define({ - isSandbox: this.isSandbox, - privateKey: this.privateKey, - merchantId: this.merchantId, - timeout: this.timeout - }); - }; -} - -Openpay.prototype.define = function (baseData) { - this.groups = new Groups(baseData); - this.merchant = new Merchant(baseData); - this.charges = new Charges(baseData); - this.payouts = new Payouts(baseData); - this.fees = new Fees(baseData); - this.plans = new Plans(baseData); - this.cards = new Cards(baseData); - this.customers = new Customers(baseData); - this.webhooks = new Webhooks(baseData); - this.tokens = new Tokens(baseData); - this.checkouts = new Checkouts(baseData); - this.pse = new Pse(baseData); - this.stores = new Stores(baseData); -}; - -Openpay.prototype.setBaseUrl = function (countryCode) { - console.log('setting base url from country') - switch (countryCode) { - case 'pe': - console.log('Country Peru'); - Openpay.BASE_URL = "https://api.openpay.pe"; - Openpay.SANDBOX_URL = "https://sandbox-api.openpay.pe"; - break; - case 'co': - console.log('Country Colombia') - Openpay.BASE_URL = "https://api.openpay.co"; - Openpay.SANDBOX_URL = "https://sandbox-api.openpay.co"; - break - case 'mx': - console.log('Country Mexico'); - console.log('Default value'); - break - default: - console.error('Error country code, setting mx default.'); - } -} - -function Merchant(baseData) { - var baseUrl = baseData.merchantId; - - this.get = function (callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'GET'}, - callback: callback - })); - }; -} - -function Charges(baseData) { - var baseUrl = baseData.merchantId + '/charges'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.get = function (transactionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + transactionId, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.capture = function (transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + transactionId + '/capture', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.refund = function (transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + transactionId + '/refund', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; -} - - -function Payouts(baseData) { - var baseUrl = baseData.merchantId + '/payouts'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.get = function (transactionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + transactionId, - requestData: {method: 'GET'}, - callback: callback - })); - }; -} - - -function Fees(baseData) { - var baseUrl = baseData.merchantId + '/fees'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; -} - - -function Customers(baseData) { - var baseUrl = baseData.merchantId + '/customers'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.get = function (customerId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + customerId, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.update = function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + customerId, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - }; - - this.delete = function (customerId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + customerId, - requestData: {method: 'DELETE'}, - callback: callback - })); - }; - - this.charges = { - baseUrl: baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/charges', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/charges' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, transactionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/charges/' + transactionId, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - capture: function (customerId, transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/charges/' + transactionId + '/capture', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - refund: function (customerId, transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/charges/' + transactionId + '/refund', - requestData: {method: 'POST', json: data}, - callback: callback - })); - } - }; - - this.transfers = { - baseUrl: baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/transfers', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/transfers' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, transactionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/transfers/' + transactionId, - requestData: {method: 'GET'}, - callback: callback - })); - } - }; - - this.payouts = { - baseUrl: baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/payouts', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/payouts' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, transactionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/payouts/' + transactionId, - requestData: {method: 'GET'}, - callback: callback - })); - } - }; - - this.subscriptions = { - baseUrl: baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/subscriptions', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/subscriptions' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, subscriptionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/subscriptions/' + subscriptionId, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - update: function (customerId, subscriptionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/subscriptions/' + subscriptionId, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - }, - - delete: function (customerId, subscriptionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/subscriptions/' + subscriptionId, - requestData: {method: 'DELETE'}, - callback: callback - })); - } - }; - - this.cards = { - baseUrl: baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, cardId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards/' + cardId, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - delete: function (customerId, cardId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards/' + cardId, - requestData: {method: 'DELETE'}, - callback: callback - })); - }, - update: function (customerId, cardId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards/' + cardId, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - } - }; - - this.bankaccounts = { - baseUrl: baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/bankaccounts', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/bankaccounts' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, bankId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/bankaccounts/' + bankId, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - delete: function (customerId, bankId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/bankaccounts/' + bankId, - requestData: {method: 'DELETE'}, - callback: callback - })); - } - }; - - this.checkouts = { - baseUrl: baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/checkouts', - requestData: {method: 'POST', json: data}, - callback: callback - })); - } - }; - - this.pse = { - baseUrl: baseData.merchantId + '/customers/', - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/charges', - requestData: {method: 'POST', json: data}, - callback: callback - })); - } - } -} - - -function Cards(baseData) { - var baseUrl = baseData.merchantId + '/cards'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.get = function (cardId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + cardId, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.delete = function (cardId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + cardId, - requestData: {method: 'DELETE'}, - callback: callback - })); - }; - - this.update = function (cardId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + cardId, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - }; -} - -function Plans(baseData) { - var baseUrl = baseData.merchantId + '/plans'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.get = function (planId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + planId, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.update = function (planId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + planId, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - }; - - this.delete = function (planId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + planId, - requestData: {method: 'DELETE'}, - callback: callback - })); - }; - - this.listSubscriptions = function (planId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + planId + '/subscriptions' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; -} - - -function Webhooks(baseData) { - var baseUrl = baseData.merchantId + '/webhooks'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.verify = function (webhook_id, verification_code, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + webhook_id + '/verify' + '/' + verification_code, - requestData: {method: 'POST', json: '{}'}, - callback: callback - })); - }; - - this.get = function (webhook_id, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + webhook_id, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - - this.delete = function (webhook_id, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + webhook_id, - requestData: {method: 'DELETE'}, - callback: callback - })); - }; - - this.list = function (callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'GET'}, - callback: callback - })); - }; - -} - -function Tokens(baseData) { - var baseUrl = baseData.merchantId + '/tokens'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.get = function (token_id, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + token_id, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.list = function (callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'GET'}, - callback: callback - })); - }; - -} - -function Checkouts(baseData) { - var baseUrl = baseData.merchantId + '/checkouts'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; - - this.get = function (checkout_id, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + checkout_id, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; - - this.update = function (checkoutId, status, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl + '/' + checkoutId + "?status=" + status, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - }; -} - -function Stores(baseData) { - var baseUrl = 'stores'; - - this.list = function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendStoreRequest(_.extend(baseData, { - apiUrl: baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }; -} - -function Pse(baseData) { - var baseUrl = baseData.merchantId + '/charges'; - - this.create = function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }; -} - -function Groups(baseData) { - baseData.groupId = baseData.merchantId; - var baseUrl = 'groups' - this.customers = { - baseUrl: 'groups/' + baseData.merchantId + '/customers', - - create: function (data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl, - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + '/' + customerId, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - update: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + '/' + customerId, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - }, - - delete: function (customerId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + '/' + customerId, - requestData: {method: 'DELETE'}, - callback: callback - })); - }, - - cards: { - baseUrl: 'groups/' + baseData.merchantId + '/customers/', - - create: function (customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (customerId, cardId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards/' + cardId, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - delete: function (customerId, cardId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + customerId + '/cards/' + cardId, - requestData: {method: 'DELETE'}, - callback: callback - })); - } - }, - - charges: { - baseUrl: 'groups/' + baseData.merchantId + '/merchants/', - - create: function (merchantId, customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/charges', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - capture: function (merchantId, customerId, transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/charges/' + transactionId + '/capture', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - refund: function (merchantId, customerId, transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/charges/' + transactionId + '/refund', - requestData: {method: 'POST', json: data}, - callback: callback - })); - } - }, - - subscriptions: { - baseUrl: 'groups/' + baseData.merchantId + '/merchants/', - - create: function (merchantId, customerId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/subscriptions', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - list: function (merchantId, customerId, data, callback) { - var query = (data && _.isObject(data) && !_.isArray(data) && !_.isFunction(data) && !_.isEmpty(data)) ? stringifyParams(data) : ''; - var callback = _.isFunction(callback) ? callback : _.isFunction(data) ? data : null; - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/subscriptions' + query, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - get: function (merchantId, customerId, subscriptionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/subscriptions/' + subscriptionId, - requestData: {method: 'GET'}, - callback: callback - })); - }, - - update: function (merchantId, customerId, subscriptionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/subscriptions/' + subscriptionId, - requestData: {method: 'PUT', json: data}, - callback: callback - })); - }, - - delete: function (merchantId, customerId, subscriptionId, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/customers/' + customerId + '/subscriptions/' + subscriptionId, - requestData: {method: 'DELETE'}, - callback: callback - })); - } - } - }; - - this.charges = { - baseUrl: 'groups/' + baseData.merchantId + '/merchants/', - - create: function (merchantId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/charges', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - capture: function (merchantId, transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/charges/' + transactionId + '/capture', - requestData: {method: 'POST', json: data}, - callback: callback - })); - }, - - refund: function (merchantId, transactionId, data, callback) { - sendRequest(_.extend(baseData, { - apiUrl: this.baseUrl + merchantId + '/charges/' + transactionId + '/refund', - requestData: {method: 'POST', json: data}, - callback: callback - })); - } - }; - -} - - -var stringifyParams = function (params) { - return '?' + _.map(_.pairs(params), function (arr) { - return arr.join('='); - }).join('&'); -} - -var sendRequest = function (data) { - var baseUrl = data.isSandbox ? Openpay.SANDBOX_URL + Openpay.SANDBOX_API_VERSION : Openpay.BASE_URL + Openpay.API_VERSION; - const url = baseUrl + urlUtils.escapeBrackets(data.apiUrl); - const options = { - auth: data.privateKey + ':', - method: data.requestData.method || 'GET', - contentType: 'json', - timeout: data.timeout, - data: data.requestData.json, - dataType: 'json' - }; - - urllib.request(url, options, function (err, body, res) { - var resCode = res ? res.statusCode : null; - var error = resCode && (resCode != 200 && resCode != 201 && resCode != 204) ? body : null; - data.callback(err ? err : error, err || error ? null : body, res); - }); -} - -var sendStoreRequest = function (data) { - var baseUrl = data.isSandbox ? Openpay.SANDBOX_URL + "/" : Openpay.BASE_URL + "/"; - const url = baseUrl + urlUtils.escapeBrackets(data.apiUrl); - const options = { - auth: data.privateKey + ':', - method: data.requestData.method || 'GET', - contentType: 'json', - timeout: data.timeout, - data: data.requestData.json, - dataType: 'json' - }; - - urllib.request(url, options, function (err, body, res) { - var resCode = res ? res.statusCode : null; - var error = resCode && (resCode != 200 && resCode != 201 && resCode != 204) ? body : null; - data.callback(err ? err : error, err || error ? null : body, res); - }); -} - -module.exports = Openpay; diff --git a/lib/url-utils.js b/lib/url-utils.js deleted file mode 100644 index 14c6cd3..0000000 --- a/lib/url-utils.js +++ /dev/null @@ -1,8 +0,0 @@ -function escapeBrackets(url) { - url = url.replace(new RegExp('\\[', 'g'), encodeURI('[')) - url = url.replace(new RegExp('\]', 'g'), encodeURI(']')) - console.log('3:', url) - return url; -} - -exports.escapeBrackets = escapeBrackets; diff --git a/package-lock.json b/package-lock.json index bc269be..1eaa5b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,1697 +1,1375 @@ { - "name": "openpay", - "version": "1.0.5", - "lockfileVersion": 1, + "name": "@neo-cheems/openpay", + "version": "4.0.0", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" + "packages": { + "": { + "name": "@neo-cheems/openpay", + "version": "4.0.0", + "license": "Apache-2.0", + "devDependencies": { + "@types/node": "^26.1.1", + "mocha": "10.2.0", + "typescript": "^7.0.2" + }, + "engines": { + "node": ">=20.0.0" + } }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" + "node_modules/@types/node": { + "version": "26.1.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz", + "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" } }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "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==", + "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==", "dev": true, - "requires": { - "color-convert": "^1.9.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "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, - "requires": { - "sprintf-js": "~1.0.2" - } + "license": "Python-2.0" }, - "ast-types": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", - "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", - "requires": { - "tslib": "^2.0.1" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/brace-expansion": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "requires": { - "fill-range": "^7.0.1" + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "browser-stdout": { + "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "license": "MIT", + "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/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", "dependencies": { - "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" - } - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, - "requires": { - "anymatch": "~3.1.1", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "readdirp": "~3.6.0" }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "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==", + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "requires": { - "color-name": "1.1.3" + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "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==" - }, - "copy-to": { + "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", - "integrity": "sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "data-uri-to-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "default-user-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-user-agent/-/default-user-agent-1.0.0.tgz", - "integrity": "sha1-FsRu/cq6PtxF8k8r1IaLAbfCrcY=", - "requires": { - "os-name": "~1.0.3" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "degenerator": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", - "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", - "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" - }, + "license": "MIT", "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" - } - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "digest-header": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/digest-header/-/digest-header-0.0.1.tgz", - "integrity": "sha1-Ecz23uxXZqw3l0TZAcEsuklRS+Y=", - "requires": { - "utility": "0.1.11" + "color-name": "~1.1.4" }, - "dependencies": { - "utility": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/utility/-/utility-0.1.11.tgz", - "integrity": "sha1-/eYM+bTkdRlHoM9dEEzik2ciZxU=", - "requires": { - "address": ">=0.0.1" - } - } + "engines": { + "node": ">=7.0.0" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" }, - "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" - } - }, - "es-abstract": { - "version": "1.18.0-next.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", - "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.1", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.3", - "string.prototype.trimstart": "^1.0.3" - }, - "dependencies": { - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - } - } + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { + "node_modules/diff": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "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==", + "dev": true, + "license": "MIT" }, - "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" + "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, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "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==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "requires": { - "locate-path": "^3.0.0" + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "requires": { - "is-buffer": "~2.0.3" + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" } }, - "formstream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/formstream/-/formstream-1.1.0.tgz", - "integrity": "sha1-UfOXDyYTbrCtRDBN5M67UCB7RHk=", - "requires": { - "destroy": "^1.0.4", - "mime": "^1.3.4", - "pause-stream": "~0.0.11" - } - }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { + "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "get-uri": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.4.tgz", - "integrity": "sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==", - "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "~3.0.2", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, - "requires": { + "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" } }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "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==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, + "license": "MIT", "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "https-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", - "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "requires": { - "ms": "^2.0.0" + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "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" + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, - "is-binary-path": { + "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" } }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "dev": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { + "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=", - "dev": true + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "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==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { + "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==", - "dev": true - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" + "license": "MIT", + "engines": { + "node": ">=0.12.0" } }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "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, - "requires": { - "has-symbols": "^1.0.1" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "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==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "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, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "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==", "dev": true, - "requires": { - "brace-expansion": "^1.1.7" + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" + "node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "node_modules/mocha": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, - "requires": { - "ansi-colors": "3.2.3", + "license": "MIT", + "dependencies": { + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, - "netmask": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=" - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "node_modules/mocha/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", - "dev": true + "node_modules/mocha/node_modules/debug/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==", + "dev": true, + "license": "MIT" }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "node_modules/nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "object.getownpropertydescriptors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz", - "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==", + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { + "dev": true, + "dependencies": { "wrappy": "1" } }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "os-name": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", - "integrity": "sha1-GzefZINa98Wn9JizV8uVIVwVnt8=", - "requires": { - "osx-release": "^1.0.0", - "win-release": "^1.0.0" - } - }, - "osx-release": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", - "integrity": "sha1-8heRGigTaUmvG/kwiyQeJzfTzWw=", - "requires": { - "minimist": "^1.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "requires": { - "p-try": "^2.0.0" + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "requires": { - "p-limit": "^2.0.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 - }, - "pac-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz", - "integrity": "sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ==", - "requires": { - "agent-base": "^4.2.0", - "debug": "^4.1.1", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^3.0.0", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^4.0.1" - }, + "license": "MIT", "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "pac-resolver": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", - "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" + "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, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "requires": { - "through": "~2.3" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "proxy-agent": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.1.1.tgz", - "integrity": "sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw==", - "requires": { - "agent-base": "^4.2.0", - "debug": "4", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^3.0.0", - "lru-cache": "^5.1.1", - "pac-proxy-agent": "^3.0.1", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "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" - } - }, - "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" - }, - "raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.3", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } + "safe-buffer": "^5.1.0" } }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "requires": { - "picomatch": "^2.0.4" + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "safe-buffer": { + "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==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "smart-buffer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", - "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==" - }, - "socks": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", - "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", - "requires": { - "ip": "1.1.5", - "smart-buffer": "^4.1.0" - } - }, - "socks-proxy-agent": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", - "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", - "requires": { - "agent-base": "~4.2.1", - "socks": "~2.3.2" - }, - "dependencies": { - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "requires": { - "es6-promisify": "^5.0.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" } }, - "string.prototype.trimend": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", - "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "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==", "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "string.prototype.trimstart": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", - "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "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==", "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "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, - "requires": { - "ansi-regex": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "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==", "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "requires": { - "thenify": ">= 3.1.0 < 4" + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "thunkify": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", - "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=" - }, - "to-regex-range": { + "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==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "underscore": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.5.2.tgz", - "integrity": "sha1-EzXF5PXm0zu7SwBrqMhqAPVW3gg=" - }, - "unescape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unescape/-/unescape-1.0.1.tgz", - "integrity": "sha512-O0+af1Gs50lyH1nUu3ZyYS1cRh01Q/kUKatTOkSs7jukXE6/NebucDVxyiDsA9AQ4JC1V1jUH9EO8JX2nMDgGQ==", - "requires": { - "extend-shallow": "^2.0.1" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "urllib": { - "version": "2.36.1", - "resolved": "https://registry.npmjs.org/urllib/-/urllib-2.36.1.tgz", - "integrity": "sha512-g0Gh7bH5AwfPUzFetxPtJwumGHE6D7KQn0K68MwcJXPgO2K0AliwEIxLAwGMF+TpY75DYAsvz1h9ekagYoq33w==", - "requires": { - "any-promise": "^1.3.0", - "content-type": "^1.0.2", - "debug": "^2.6.9", - "default-user-agent": "^1.0.0", - "digest-header": "^0.0.1", - "ee-first": "~1.1.1", - "formstream": "^1.1.0", - "humanize-ms": "^1.2.0", - "iconv-lite": "^0.4.15", - "ip": "^1.1.5", - "proxy-agent": "^3.1.0", - "pump": "^3.0.0", - "qs": "^6.4.0", - "statuses": "^1.3.1", - "utility": "^1.16.1" }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "engines": { + "node": ">=8.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utility": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/utility/-/utility-1.17.0.tgz", - "integrity": "sha512-KdVkF9An/0239BJ4+dqOa7NPrPIOeQE9AGfx0XS16O9DBiHNHRJMoeU5nL6pRGAkgJOqdOu8R4gBRcXnAocJKw==", - "requires": { - "copy-to": "^2.0.1", - "escape-html": "^1.0.3", - "mkdirp": "^0.5.1", - "mz": "^2.7.0", - "unescape": "^1.0.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "win-release": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", - "integrity": "sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk=", - "requires": { - "semver": "^5.0.1" - } + "license": "MIT" }, - "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==" + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true, + "license": "Apache-2.0" }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "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==", "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, + "license": "MIT", "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "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" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "engines": { + "node": ">=10" } }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "license": "ISC", + "engines": { + "node": ">=10" } }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } } diff --git a/package.json b/package.json index beaa73e..ed536b5 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,45 @@ { - "name": "openpay", - "description": "Openpay library", - "version": "2.0.1", - "dependencies": { - "underscore": "1.13.6", - "urllib": "^2.36.1" + "name": "@neo-cheems/openpay", + "description": "Openpay API client for Node.js β€” typed, SOLID, and battle-tested", + "version": "5.0.0", + "license": "Apache-2.0", + "author": "neo-cheems", + "repository": { + "type": "git", + "url": "https://github.com/tesuser4444/openpay-node-ts" + }, + "bugs": { + "url": "https://github.com/tesuser4444/openpay-node-ts/issues" + }, + "homepage": "https://github.com/tesuser4444/openpay-node-ts#readme", + "keywords": [ + "openpay", + "payments", + "api", + "mexico", + "colombia", + "peru", + "typescript" + ], + "engines": { + "node": ">=24.0.0" + }, + "main": "./lib/index.js", + "types": "./lib/index.d.ts", + "files": [ + "lib/**/*" + ], + "publishConfig": { + "access": "public" }, - "main": "lib/openpay.js", "devDependencies": { - "mocha": "10.2.0" + "@types/node": "^26.1.1", + "mocha": "10.2.0", + "typescript": "^7.0.2" }, "scripts": { + "build": "tsc --project tsconfig.json", + "prepublishOnly": "npm run build", "test": "mocha" - }, - "engines": { - "node": ">=0.6.x" } } diff --git a/src/base-resource.ts b/src/base-resource.ts new file mode 100644 index 0000000..63e874e --- /dev/null +++ b/src/base-resource.ts @@ -0,0 +1,100 @@ +import type { Callback, HttpMethod, OpenpayConfig, QueryParams } from './types'; +import type { HttpClient } from './http-client'; +import { stringifyParams, isPlainObjectWithKeys } from './stringify-params'; + +/** + * Abstract base for every Openpay API resource. + * + * Provides: + * - `request()` helper for HTTP calls + * - `list()` overload helper (data-or-callback resolution) + * - Promise + callback support methods + */ +export abstract class BaseResource { + protected readonly config: OpenpayConfig; + protected readonly httpClient: HttpClient; + protected readonly baseUrl: string; + + constructor(config: OpenpayConfig, httpClient: HttpClient, baseUrl: string) { + this.config = config; + this.httpClient = httpClient; + this.baseUrl = baseUrl; + } + + /** Issue an HTTP request to the API. */ + protected request( + method: HttpMethod, + path: string, + body: unknown | undefined, + callback: Callback, + ): void { + this.httpClient.request(method, path, body, this.config, callback); + } + + /** + * Resolves the common `list(data, callback)` / `list(callback)` overload. + * + * Returns: + * - `query` β€” URL query string (with `?` prefix, or `''`) + * - `cb` β€” the resolved callback + */ + protected resolveListParams( + dataOrCb: QueryParams | Callback | undefined, + cb?: Callback, + ): { query: string; cb: Callback | undefined } { + if (typeof dataOrCb === 'function') { + return { query: '', cb: dataOrCb as Callback }; + } + if (typeof cb === 'function') { + const q = isPlainObjectWithKeys(dataOrCb) ? stringifyParams(dataOrCb) : ''; + return { query: q, cb }; + } + return { query: '', cb: undefined }; + } + + /** Build a sub-path under this resource's base URL. */ + protected url(segment = ''): string { + return segment ? `${this.baseUrl}/${segment}` : this.baseUrl; + } + + /** Build a URL with a query string appended. */ + protected urlWithQuery(segment: string, query: string): string { + return query ? `${this.baseUrl}/${segment}${query}` : `${this.baseUrl}/${segment}`; + } +} + +/** + * A collection nested one level under a parent id, e.g. + * `{merchantId}/customers/{customerId}/cards`. Covers the common + * create/list/get/delete shape shared by most customer sub-resources; + * extend it to add resource-specific methods (capture, refund, update…). + */ +export class NestedCollection extends BaseResource { + constructor( + config: OpenpayConfig, + httpClient: HttpClient, + parentBaseUrl: string, + protected readonly collection: string, + ) { + super(config, httpClient, parentBaseUrl); + } + + create(parentId: string, data: unknown, callback: Callback): void { + this.request('POST', this.url(`${parentId}/${this.collection}`), data, callback); + } + + list(parentId: string, callback: Callback): void; + list(parentId: string, data: QueryParams, callback: Callback): void; + list(parentId: string, dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.urlWithQuery(`${parentId}/${this.collection}`, query), undefined, resolvedCb!); + } + + get(parentId: string, childId: string, callback: Callback): void { + this.request('GET', this.url(`${parentId}/${this.collection}/${childId}`), undefined, callback); + } + + delete(parentId: string, childId: string, callback: Callback): void { + this.request('DELETE', this.url(`${parentId}/${this.collection}/${childId}`), undefined, callback); + } +} diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..c8d66e1 --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,51 @@ +// ── Custom Error Classes ─────────────────────────────────────────── + +export class OpenpayError extends Error { + public readonly statusCode: number; + public readonly body: unknown; + public readonly category?: string | undefined; + public readonly description?: string | undefined; + public readonly requestId?: string | undefined; + + constructor( + message: string, + statusCode: number, + body: unknown, + cause?: Error, + ) { + super(message, { cause }); + this.name = 'OpenpayError'; + this.statusCode = statusCode; + + // Extract details from the Openpay error body if possible + if (body !== null && typeof body === 'object') { + const b = body as Record; + this.body = body; + const cat = b['category']; + const desc = b['description']; + const reqId = b['request_id']; + if (typeof cat === 'string') this.category = cat; + if (typeof desc === 'string') this.description = desc; + if (typeof reqId === 'string') this.requestId = reqId; + } else { + this.body = body; + } + } + + /** Whether this is a client error (4xx). */ + get isClientError(): boolean { + return this.statusCode >= 400 && this.statusCode < 500; + } + + /** Whether this is a server error (5xx). */ + get isServerError(): boolean { + return this.statusCode >= 500; + } +} + +export class NetworkError extends OpenpayError { + constructor(cause: Error) { + super(`Network error: ${cause.message}`, 0, null, cause); + this.name = 'NetworkError'; + } +} diff --git a/src/http-client.ts b/src/http-client.ts new file mode 100644 index 0000000..e286944 --- /dev/null +++ b/src/http-client.ts @@ -0,0 +1,83 @@ +import type { HttpMethod, OpenpayConfig, Callback } from './types'; +import { OpenpayError, NetworkError } from './errors'; +import { escapeBrackets } from './url-utils'; + +// ── HTTP Client Interface (DIP: resources depend on this, not on fetch) ─ + +export interface HttpClient { + request( + method: HttpMethod, + url: string, + body: unknown | undefined, + config: OpenpayConfig, + callback: Callback, + ): void; +} + +/** Per-instance API host derived from country + sandbox flag. */ +export function hostFor(config: OpenpayConfig): string { + return `https://${config.isSandbox ? 'sandbox-api' : 'api'}.openpay.${config.countryCode}`; +} + +async function performRequest( + method: HttpMethod, + fullUrl: string, + body: unknown | undefined, + config: OpenpayConfig, + callback: Callback, +): Promise { + const auth = Buffer.from(config.privateKey + ':').toString('base64'); + + let res: Response; + try { + res = await fetch(fullUrl, { + method, + headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' }, + body: body === undefined ? undefined : JSON.stringify(body), + signal: AbortSignal.timeout(config.timeout), + }); + } catch (err) { + callback(new NetworkError(err as Error), null, null); + return; + } + + const headers = Object.fromEntries(res.headers.entries()); + const respBody = await res.json().catch(() => null); + + if (res.ok) { + callback(null, respBody, { statusCode: res.status, headers }); + } else { + callback(new OpenpayError(`HTTP ${res.status}`, res.status, respBody), null, { + statusCode: res.status, + headers, + }); + } +} + +// ── fetch-based Implementation ────────────────────────────────────── + +export class UrllibHttpClient implements HttpClient { + request( + method: HttpMethod, + url: string, + body: unknown | undefined, + config: OpenpayConfig, + callback: Callback, + ): void { + void performRequest(method, hostFor(config) + '/v1/' + escapeBrackets(url), body, config, callback); + } +} + +// ── Store HTTP Client (no /v1 prefix) ─────────────────────────────── + +export class StoreHttpClient implements HttpClient { + request( + method: HttpMethod, + url: string, + body: unknown | undefined, + config: OpenpayConfig, + callback: Callback, + ): void { + void performRequest(method, hostFor(config) + '/' + escapeBrackets(url), body, config, callback); + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..e81a2c1 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +import Openpay = require('./openpay'); +export = Openpay; diff --git a/src/openpay.ts b/src/openpay.ts new file mode 100644 index 0000000..e5d0165 --- /dev/null +++ b/src/openpay.ts @@ -0,0 +1,132 @@ +import type { OpenpayConfig, CountryCode } from './types'; +import { UrllibHttpClient, StoreHttpClient } from './http-client'; +import { MerchantResource } from './resources/merchant'; +import { ChargesResource } from './resources/charges'; +import { PayoutsResource } from './resources/payouts'; +import { FeesResource } from './resources/fees'; +import { PlansResource } from './resources/plans'; +import { CardsResource } from './resources/cards'; +import { CustomersResource } from './resources/customers'; +import { WebhooksResource } from './resources/webhooks'; +import { TokensResource } from './resources/tokens'; +import { CheckoutsResource } from './resources/checkouts'; +import { StoresResource } from './resources/stores'; +import { PseResource } from './resources/pse'; +import { GroupsResource } from './resources/groups'; + +/** + * Openpay API client. + * + * Usage (callback style, backward-compatible): + * ```js + * const openpay = new Openpay('merchantId', 'sk_xxx', 'mx', false); + * openpay.charges.create({ amount: 100, ... }, (err, body, res) => { ... }); + * ``` + */ +const COUNTRY_CODES: readonly CountryCode[] = ['mx', 'pe', 'co']; + +class Openpay { + // ── Instance State ─────────────────────────────────────────────── + + private config: OpenpayConfig; + private apiHttpClient: UrllibHttpClient; + private storeHttpClient: StoreHttpClient; + + // ── Resources (public API surface) ─────────────────────────────── + + public merchant!: MerchantResource; + public charges!: ChargesResource; + public payouts!: PayoutsResource; + public fees!: FeesResource; + public plans!: PlansResource; + public cards!: CardsResource; + public customers!: CustomersResource; + public webhooks!: WebhooksResource; + public tokens!: TokensResource; + public checkouts!: CheckoutsResource; + public stores!: StoresResource; + public pse!: PseResource; + public groups!: GroupsResource; + + // ── Constructor ────────────────────────────────────────────────── + + constructor( + merchantId: string, + privateKey: string, + countryCode: CountryCode = 'mx', + isProductionReady?: boolean, + ) { + const isSandbox = !isProductionReady; + + this.config = { + merchantId, + privateKey, + isSandbox, + timeout: 90_000, + countryCode: COUNTRY_CODES.includes(countryCode) ? countryCode : 'mx', + }; + + // Create HTTP clients (DIP: resources depend on these abstractions) + this.apiHttpClient = new UrllibHttpClient(); + this.storeHttpClient = new StoreHttpClient(); + + this.rebuildResources(); + } + + // ── Configuration Setters ──────────────────────────────────────── + + /** Change the merchant ID and rebuild resources. */ + setMerchantId(merchantId: string): void { + this.config = { ...this.config, merchantId }; + this.rebuildResources(); + } + + /** Change the private key and rebuild resources. */ + setPrivateKey(privateKey: string): void { + this.config = { ...this.config, privateKey }; + this.rebuildResources(); + } + + /** Toggle sandbox/production mode and rebuild resources. */ + setProductionReady(isProductionReady: boolean): void { + this.config = { ...this.config, isSandbox: !isProductionReady }; + this.rebuildResources(); + } + + /** Change the HTTP request timeout and rebuild resources. */ + setTimeout(timeout: number): void { + this.config = { ...this.config, timeout }; + this.rebuildResources(); + } + + /** Change the country (per instance) and rebuild resources. */ + setBaseUrl(countryCode: CountryCode): void { + this.config = { + ...this.config, + countryCode: COUNTRY_CODES.includes(countryCode) ? countryCode : 'mx', + }; + this.rebuildResources(); + } + + // ── Helpers ────────────────────────────────────────────────────── + + /** Rebuild all resources after a config change. */ + private rebuildResources(): void { + // Re-assign resource properties (same pattern as original's _reDefine) + this.merchant = new MerchantResource(this.config, this.apiHttpClient); + this.charges = new ChargesResource(this.config, this.apiHttpClient); + this.payouts = new PayoutsResource(this.config, this.apiHttpClient); + this.fees = new FeesResource(this.config, this.apiHttpClient); + this.plans = new PlansResource(this.config, this.apiHttpClient); + this.cards = new CardsResource(this.config, this.apiHttpClient); + this.customers = new CustomersResource(this.config, this.apiHttpClient); + this.webhooks = new WebhooksResource(this.config, this.apiHttpClient); + this.tokens = new TokensResource(this.config, this.apiHttpClient); + this.checkouts = new CheckoutsResource(this.config, this.apiHttpClient); + this.pse = new PseResource(this.config, this.apiHttpClient); + this.groups = new GroupsResource(this.config, this.apiHttpClient); + this.stores = new StoresResource(this.config, this.storeHttpClient); + } +} + +export = Openpay; diff --git a/src/resources/cards.ts b/src/resources/cards.ts new file mode 100644 index 0000000..2b555bd --- /dev/null +++ b/src/resources/cards.ts @@ -0,0 +1,28 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +export class CardsResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/cards`); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } + + get(cardId: string, callback: Callback): void { + this.request('GET', this.url(cardId), undefined, callback); + } + + delete(cardId: string, callback: Callback): void { + this.request('DELETE', this.url(cardId), undefined, callback); + } +} diff --git a/src/resources/charges.ts b/src/resources/charges.ts new file mode 100644 index 0000000..b4e7615 --- /dev/null +++ b/src/resources/charges.ts @@ -0,0 +1,37 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +export class ChargesResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/charges`); + } + + /** Create a new charge. */ + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + /** List charges with optional filters. */ + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } + + /** Get a charge by transaction ID. */ + get(transactionId: string, callback: Callback): void { + this.request('GET', this.url(transactionId), undefined, callback); + } + + /** Capture a previously uncaptured charge. */ + capture(transactionId: string, data: unknown, callback: Callback): void { + this.request('POST', this.url(`${transactionId}/capture`), data, callback); + } + + /** Refund a charge. */ + refund(transactionId: string, data: unknown, callback: Callback): void { + this.request('POST', this.url(`${transactionId}/refund`), data, callback); + } +} diff --git a/src/resources/checkouts.ts b/src/resources/checkouts.ts new file mode 100644 index 0000000..161855a --- /dev/null +++ b/src/resources/checkouts.ts @@ -0,0 +1,33 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +export class CheckoutsResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/checkouts`); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + get(checkoutId: string, callback: Callback): void { + this.request('GET', this.url(checkoutId), undefined, callback); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } + + update(checkoutId: string, status: string, data: unknown, callback: Callback): void { + this.request( + 'PUT', + this.url(`${checkoutId}?status=${status}`), + data, + callback, + ); + } +} diff --git a/src/resources/customers.ts b/src/resources/customers.ts new file mode 100644 index 0000000..fe39a52 --- /dev/null +++ b/src/resources/customers.ts @@ -0,0 +1,99 @@ +import { BaseResource, NestedCollection } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +// ── Customer Sub-Resources ───────────────────────────────────────── + +class CustomerCards extends NestedCollection { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/customers`, 'cards'); + } +} + +class CustomerCharges extends NestedCollection { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/customers`, 'charges'); + } + + capture(customerId: string, transactionId: string, data: unknown, callback: Callback): void { + this.request('POST', this.url(`${customerId}/charges/${transactionId}/capture`), data, callback); + } + + refund(customerId: string, transactionId: string, data: unknown, callback: Callback): void { + this.request('POST', this.url(`${customerId}/charges/${transactionId}/refund`), data, callback); + } +} + +class CustomerTransfers extends NestedCollection { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/customers`, 'transfers'); + } +} + +class CustomerPayouts extends NestedCollection { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/customers`, 'payouts'); + } +} + +class CustomerSubscriptions extends NestedCollection { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/customers`, 'subscriptions'); + } + + update(customerId: string, subscriptionId: string, data: unknown, callback: Callback): void { + this.request('PUT', this.url(`${customerId}/subscriptions/${subscriptionId}`), data, callback); + } +} + +class CustomerBankAccounts extends NestedCollection { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/customers`, 'bankaccounts'); + } +} + +// ── Main Customers Resource ──────────────────────────────────────── + +export class CustomersResource extends BaseResource { + public readonly cards: CustomerCards; + public readonly charges: CustomerCharges; + public readonly transfers: CustomerTransfers; + public readonly payouts: CustomerPayouts; + public readonly subscriptions: CustomerSubscriptions; + public readonly bankaccounts: CustomerBankAccounts; + + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/customers`); + + // Compose sub-resources (each shares the same config & http client) + this.cards = new CustomerCards(config, httpClient); + this.charges = new CustomerCharges(config, httpClient); + this.transfers = new CustomerTransfers(config, httpClient); + this.payouts = new CustomerPayouts(config, httpClient); + this.subscriptions = new CustomerSubscriptions(config, httpClient); + this.bankaccounts = new CustomerBankAccounts(config, httpClient); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } + + get(customerId: string, callback: Callback): void { + this.request('GET', this.url(customerId), undefined, callback); + } + + update(customerId: string, data: unknown, callback: Callback): void { + this.request('PUT', this.url(customerId), data, callback); + } + + delete(customerId: string, callback: Callback): void { + this.request('DELETE', this.url(customerId), undefined, callback); + } +} diff --git a/src/resources/fees.ts b/src/resources/fees.ts new file mode 100644 index 0000000..b1f0458 --- /dev/null +++ b/src/resources/fees.ts @@ -0,0 +1,20 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +export class FeesResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/fees`); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } +} diff --git a/src/resources/groups.ts b/src/resources/groups.ts new file mode 100644 index 0000000..18323a0 --- /dev/null +++ b/src/resources/groups.ts @@ -0,0 +1,214 @@ +import { BaseResource, NestedCollection } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +// ── Group Sub-Resources ──────────────────────────────────────────── + +class GroupCustomerCards extends NestedCollection { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `groups/${config.merchantId}/customers`, 'cards'); + } +} + +class GroupCustomerCharges extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `groups/${config.merchantId}/merchants`); + } + + create(merchantId: string, customerId: string, data: unknown, callback: Callback): void { + this.request( + 'POST', + this.url(`${merchantId}/customers/${customerId}/charges`), + data, + callback, + ); + } + + capture( + merchantId: string, + customerId: string, + transactionId: string, + data: unknown, + callback: Callback, + ): void { + this.request( + 'POST', + this.url(`${merchantId}/customers/${customerId}/charges/${transactionId}/capture`), + data, + callback, + ); + } + + refund( + merchantId: string, + customerId: string, + transactionId: string, + data: unknown, + callback: Callback, + ): void { + this.request( + 'POST', + this.url(`${merchantId}/customers/${customerId}/charges/${transactionId}/refund`), + data, + callback, + ); + } +} + +class GroupCustomerSubscriptions extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `groups/${config.merchantId}/merchants`); + } + + create(merchantId: string, customerId: string, data: unknown, callback: Callback): void { + this.request( + 'POST', + this.url(`${merchantId}/customers/${customerId}/subscriptions`), + data, + callback, + ); + } + + list(merchantId: string, customerId: string, callback: Callback): void; + list(merchantId: string, customerId: string, data: QueryParams, callback: Callback): void; + list( + merchantId: string, + customerId: string, + dataOrCb: QueryParams | Callback, + cb?: Callback, + ): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request( + 'GET', + this.urlWithQuery(`${merchantId}/customers/${customerId}/subscriptions`, query), + undefined, + resolvedCb!, + ); + } + + get( + merchantId: string, + customerId: string, + subscriptionId: string, + callback: Callback, + ): void { + this.request( + 'GET', + this.url(`${merchantId}/customers/${customerId}/subscriptions/${subscriptionId}`), + undefined, + callback, + ); + } + + update( + merchantId: string, + customerId: string, + subscriptionId: string, + data: unknown, + callback: Callback, + ): void { + this.request( + 'PUT', + this.url(`${merchantId}/customers/${customerId}/subscriptions/${subscriptionId}`), + data, + callback, + ); + } + + delete( + merchantId: string, + customerId: string, + subscriptionId: string, + callback: Callback, + ): void { + this.request( + 'DELETE', + this.url(`${merchantId}/customers/${customerId}/subscriptions/${subscriptionId}`), + undefined, + callback, + ); + } +} + +// ── Group Customers ───────────────────────────────────────────────── + +class GroupCustomers extends BaseResource { + public readonly cards: GroupCustomerCards; + public readonly charges: GroupCustomerCharges; + public readonly subscriptions: GroupCustomerSubscriptions; + + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `groups/${config.merchantId}/customers`); + + this.cards = new GroupCustomerCards(config, httpClient); + this.charges = new GroupCustomerCharges(config, httpClient); + this.subscriptions = new GroupCustomerSubscriptions(config, httpClient); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } + + get(customerId: string, callback: Callback): void { + this.request('GET', this.url(customerId), undefined, callback); + } + + update(customerId: string, data: unknown, callback: Callback): void { + this.request('PUT', this.url(customerId), data, callback); + } + + delete(customerId: string, callback: Callback): void { + this.request('DELETE', this.url(customerId), undefined, callback); + } +} + +// ── Group Charges ─────────────────────────────────────────────────── + +class GroupCharges extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `groups/${config.merchantId}/merchants`); + } + + create(merchantId: string, data: unknown, callback: Callback): void { + this.request('POST', this.url(`${merchantId}/charges`), data, callback); + } + + capture(merchantId: string, transactionId: string, data: unknown, callback: Callback): void { + this.request( + 'POST', + this.url(`${merchantId}/charges/${transactionId}/capture`), + data, + callback, + ); + } + + refund(merchantId: string, transactionId: string, data: unknown, callback: Callback): void { + this.request( + 'POST', + this.url(`${merchantId}/charges/${transactionId}/refund`), + data, + callback, + ); + } +} + +// ── Main Groups Resource ──────────────────────────────────────────── + +export class GroupsResource extends BaseResource { + public readonly customers: GroupCustomers; + public readonly charges: GroupCharges; + + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `groups/${config.merchantId}`); + + this.customers = new GroupCustomers(config, httpClient); + this.charges = new GroupCharges(config, httpClient); + } +} diff --git a/src/resources/merchant.ts b/src/resources/merchant.ts new file mode 100644 index 0000000..8871c34 --- /dev/null +++ b/src/resources/merchant.ts @@ -0,0 +1,16 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig } from '../types'; + +export class MerchantResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, config.merchantId); + } + + /** + * Get merchant information. + */ + get(callback: Callback): void { + this.request('GET', this.url(), undefined, callback); + } +} diff --git a/src/resources/payouts.ts b/src/resources/payouts.ts new file mode 100644 index 0000000..31e9e93 --- /dev/null +++ b/src/resources/payouts.ts @@ -0,0 +1,24 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +export class PayoutsResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/payouts`); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } + + get(transactionId: string, callback: Callback): void { + this.request('GET', this.url(transactionId), undefined, callback); + } +} diff --git a/src/resources/plans.ts b/src/resources/plans.ts new file mode 100644 index 0000000..cfc9641 --- /dev/null +++ b/src/resources/plans.ts @@ -0,0 +1,70 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +export class PlansResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/plans`); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + this.request('GET', this.url() + query, undefined, resolvedCb!); + } + + get(planId: string, callback: Callback): void { + this.request('GET', this.url(planId), undefined, callback); + } + + update(planId: string, data: unknown, callback: Callback): void { + this.request('PUT', this.url(planId), data, callback); + } + + delete(planId: string, callback: Callback): void { + this.request('DELETE', this.url(planId), undefined, callback); + } + + /** List subscriptions under a plan. */ + listSubscriptions(callback: Callback): void; + listSubscriptions(planId: string, callback: Callback): void; + listSubscriptions(planId: string, data: QueryParams, callback: Callback): void; + listSubscriptions( + planIdOrCb: string | Callback, + dataOrCb?: QueryParams | Callback | undefined, + cb?: Callback, + ): void { + let planId: string; + let query = ''; + let resolvedCb: Callback | undefined; + + if (typeof planIdOrCb === 'function') { + // listSubscriptions(callback) + planId = ''; + resolvedCb = planIdOrCb; + } else if (typeof dataOrCb === 'function') { + // listSubscriptions(planId, callback) + planId = planIdOrCb; + resolvedCb = dataOrCb; + } else if (typeof cb === 'function') { + // listSubscriptions(planId, data, callback) + planId = planIdOrCb; + query = this.resolveListParams(dataOrCb as QueryParams, cb).query; + resolvedCb = cb; + } else { + // listSubscriptions(planId, data) + planId = planIdOrCb; + resolvedCb = undefined; + } + + const urlPath = planId + ? `${this.url(planId)}/subscriptions${query}` + : `${this.url()}${query}`; + this.request('GET', urlPath, undefined, resolvedCb!); + } +} diff --git a/src/resources/pse.ts b/src/resources/pse.ts new file mode 100644 index 0000000..5b6ca92 --- /dev/null +++ b/src/resources/pse.ts @@ -0,0 +1,14 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig } from '../types'; + +export class PseResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/charges`); + } + + /** Create a PSE charge (Colombia). */ + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } +} diff --git a/src/resources/stores.ts b/src/resources/stores.ts new file mode 100644 index 0000000..598e53f --- /dev/null +++ b/src/resources/stores.ts @@ -0,0 +1,18 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig, QueryParams } from '../types'; + +export class StoresResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + // Stores uses a different base URL (no merchant prefix, no /v1/) + super(config, httpClient, 'stores'); + } + + list(callback: Callback): void; + list(data: QueryParams, callback: Callback): void; + list(dataOrCb: QueryParams | Callback, cb?: Callback): void { + const { query, cb: resolvedCb } = this.resolveListParams(dataOrCb, cb); + // Stores uses the StoreHttpClient which has different BASE_URL logic + this.httpClient.request('GET', this.url() + query, undefined, this.config, resolvedCb!); + } +} diff --git a/src/resources/tokens.ts b/src/resources/tokens.ts new file mode 100644 index 0000000..791fcbb --- /dev/null +++ b/src/resources/tokens.ts @@ -0,0 +1,21 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig } from '../types'; + +export class TokensResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/tokens`); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + get(tokenId: string, callback: Callback): void { + this.request('GET', this.url(tokenId), undefined, callback); + } + + list(callback: Callback): void { + this.request('GET', this.url(), undefined, callback); + } +} diff --git a/src/resources/webhooks.ts b/src/resources/webhooks.ts new file mode 100644 index 0000000..c8eee48 --- /dev/null +++ b/src/resources/webhooks.ts @@ -0,0 +1,34 @@ +import { BaseResource } from '../base-resource'; +import type { HttpClient } from '../http-client'; +import type { Callback, OpenpayConfig } from '../types'; + +export class WebhooksResource extends BaseResource { + constructor(config: OpenpayConfig, httpClient: HttpClient) { + super(config, httpClient, `${config.merchantId}/webhooks`); + } + + create(data: unknown, callback: Callback): void { + this.request('POST', this.url(), data, callback); + } + + verify(webhookId: string, verificationCode: string, callback: Callback): void { + this.request( + 'POST', + this.url(`${webhookId}/verify/${verificationCode}`), + '{}', + callback, + ); + } + + get(webhookId: string, callback: Callback): void { + this.request('GET', this.url(webhookId), undefined, callback); + } + + delete(webhookId: string, callback: Callback): void { + this.request('DELETE', this.url(webhookId), undefined, callback); + } + + list(callback: Callback): void { + this.request('GET', this.url(), undefined, callback); + } +} diff --git a/src/stringify-params.ts b/src/stringify-params.ts new file mode 100644 index 0000000..45a5d04 --- /dev/null +++ b/src/stringify-params.ts @@ -0,0 +1,32 @@ +import type { QueryParams } from './types'; + +/** + * Converts a plain object to a query string with `?` prefix. + * Returns an empty string when params is undefined, null, or empty. + */ +export function stringifyParams(params: QueryParams | undefined | null): string { + if (params == null || typeof params !== 'object' || Array.isArray(params)) { + return ''; + } + + const entries = Object.entries(params); + if (entries.length === 0) { + return ''; + } + + const parts = entries.map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`); + return '?' + parts.join('&'); +} + +/** + * Detect whether a value is a plain, non-array, non-null object + * with at least one key β€” used by list-method overload resolution. + */ +export function isPlainObjectWithKeys(value: unknown): value is Record { + return ( + typeof value === 'object' && + value !== null && + !Array.isArray(value) && + Object.keys(value as object).length > 0 + ); +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..1d1422f --- /dev/null +++ b/src/types.ts @@ -0,0 +1,237 @@ +// ── HTTP & Request Types ─────────────────────────────────────────── + +export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; + +export interface RequestSpec { + apiUrl: string; + requestData: { + method: HttpMethod; + json?: unknown; + }; +} + +// ── Configuration ────────────────────────────────────────────────── + +export interface OpenpayConfig { + merchantId: string; + privateKey: string; + isSandbox: boolean; + timeout: number; + countryCode: CountryCode; +} + +// ── Callback ─────────────────────────────────────────────────────── + +export type Callback = ( + error: Error | null, + body: T | null, + response: HttpResponse | null, +) => void; + +// ── HTTP Response ────────────────────────────────────────────────── + +export interface HttpResponse { + statusCode: number; + headers: Record; +} + +// ── Country Code ─────────────────────────────────────────────────── + +export type CountryCode = 'mx' | 'pe' | 'co'; + +// ── Query Params ─────────────────────────────────────────────────── + +export type QueryParams = Record; + +// ── API Response (generic resource) ──────────────────────────────── + +export interface OpenpayResource { + id: string; + [key: string]: unknown; +} + +// ── Charge ───────────────────────────────────────────────────────── + +export interface ChargeRequest { + method: 'card' | 'bank_account' | 'store'; + amount: number; + description: string; + card?: CardRequest; + source_id?: string; + capture?: boolean; + currency?: string; + device_session_id?: string; + customer?: CustomerRef; + confirm?: boolean; + send_email?: boolean; + redirect_url?: string; + use_3d_secure?: boolean; + metadata?: Record; +} + +export interface CardRequest { + card_number: string; + holder_name: string; + expiration_year: string; + expiration_month: string; + cvv2: string; +} + +export interface CustomerRef { + id?: string; + name: string; + email?: string; + phone_number?: string; + requires_account?: boolean; + address?: Address; +} + +export interface Address { + city?: string; + country_code?: string; + line1?: string; + line2?: string; + line3?: string; + postal_code?: string; + state?: string; +} + +export interface CaptureRequest { + amount?: number; +} + +export interface RefundRequest { + description?: string; + amount?: number; +} + +// ── Payout ───────────────────────────────────────────────────────── + +export interface PayoutRequest { + method: 'card' | 'bank_account'; + destination_id?: string; + amount: number; + description: string; + card?: CardRequest; + bank_account?: BankAccountRequest; +} + +export interface BankAccountRequest { + clabe: string; + holder_name: string; + bank_code?: string; + bank_name?: string; +} + +// ── Customer ─────────────────────────────────────────────────────── + +export interface CustomerRequest { + name: string; + email?: string; + phone_number?: string; + requires_account?: boolean; + address?: Address; + external_id?: string; + status?: string; +} + +// ── Card ─────────────────────────────────────────────────────────── + +export interface CardCreateRequest { + card_number: string; + holder_name: string; + expiration_year: string; + expiration_month: string; + cvv2: string; +} + +// ── Bank Account ─────────────────────────────────────────────────── + +export interface BankAccountCreateRequest { + clabe: string; + holder_name: string; + bank_code?: string; + bank_name?: string; + alias?: string; +} + +// ── Plan ─────────────────────────────────────────────────────────── + +export interface PlanRequest { + name: string; + amount: number; + repeat_every: number; + repeat_unit: 'day' | 'week' | 'month' | 'year'; + retry_times?: number; + status_after_retry?: 'cancelled' | 'unpaid'; + trial_days?: number; + currency?: string; +} + +// ── Subscription ─────────────────────────────────────────────────── + +export interface SubscriptionRequest { + plan_id: string; + card_id?: string; + token_id?: string; + trial_days?: number; + trial_end_date?: string; + coupon_id?: string; +} + +// ── Webhook ──────────────────────────────────────────────────────── + +export interface WebhookRequest { + url: string; + event_types: string[]; +} + +// ── Token ────────────────────────────────────────────────────────── + +export interface TokenRequest { + card_number: string; + holder_name: string; + expiration_year: string; + expiration_month: string; + cvv2: string; + address?: Address; +} + +// ── Checkout ─────────────────────────────────────────────────────── + +export interface CheckoutRequest { + amount: number; + description: string; + order_id?: string; + currency?: string; + customer?: CustomerRef; + send_email?: boolean; + redirect_url?: string; + confirm?: boolean; + iva?: number; + metadata?: Record; + expires_at?: string; + needs_shipping_contact?: boolean; + type?: 'redirect' | 'modal' | 'integration'; +} + +// ── PSE ──────────────────────────────────────────────────────────── + +export interface PseRequest { + method: ' bank_account'; + amount: number; + description: string; + customer?: CustomerRef; + bank_code: string; + redirect_url?: string; +} + +// ── Store ────────────────────────────────────────────────────────── + +export interface StoreListParams { + lte?: string; + gte?: string; + limit?: number; + offset?: number; + [key: string]: string | number | undefined; +} diff --git a/src/url-utils.ts b/src/url-utils.ts new file mode 100644 index 0000000..51fb84d --- /dev/null +++ b/src/url-utils.ts @@ -0,0 +1,9 @@ +/** + * Escapes square brackets in URLs so they're safe for Openpay's API + * (which uses bracket notation in query params, e.g. creation[gte]). + */ +export function escapeBrackets(url: string): string { + let result = url.replace(/\[/g, encodeURI('[')); + result = result.replace(/\]/g, encodeURI(']')); + return result; +} diff --git a/test/bank-accounts.test.js b/test/bank-accounts.test.js index c818470..999b0cb 100644 --- a/test/bank-accounts.test.js +++ b/test/bank-accounts.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); @@ -30,7 +29,7 @@ describe('Get all bank_account with creation filter', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/cards.test.js b/test/cards.test.js index 6537ec0..50d26bb 100644 --- a/test/cards.test.js +++ b/test/cards.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -24,7 +23,7 @@ describe('Get cards list with creation[lte] filter', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/charges_test.js b/test/charges_test.js index 0236118..ef18b15 100644 --- a/test/charges_test.js +++ b/test/charges_test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -25,7 +24,7 @@ describe('Get charges list with amount[lte] filter', function () { function printLog(code, body, error){ if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if(code>=300){ console.log(' '); diff --git a/test/colombia/cards.test.colombia.js b/test/colombia/cards.test.colombia.js index eb199d0..d1aceb3 100644 --- a/test/colombia/cards.test.colombia.js +++ b/test/colombia/cards.test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -201,7 +200,7 @@ describe('Testing cards', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/charges_test.colombia.js b/test/colombia/charges_test.colombia.js index 0ded2e8..61244fa 100644 --- a/test/colombia/charges_test.colombia.js +++ b/test/colombia/charges_test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -193,7 +192,7 @@ describe('Testing charges', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/clients_test.colombia.js b/test/colombia/clients_test.colombia.js index 97750c8..d0c378e 100644 --- a/test/colombia/clients_test.colombia.js +++ b/test/colombia/clients_test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -69,7 +68,7 @@ describe('Customer testing', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/plans.test.colombia.js b/test/colombia/plans.test.colombia.js index c9548d6..b270502 100644 --- a/test/colombia/plans.test.colombia.js +++ b/test/colombia/plans.test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -72,7 +71,7 @@ describe('Plans testing', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/pse_test.colombia.js b/test/colombia/pse_test.colombia.js index 15f047d..87c84ae 100644 --- a/test/colombia/pse_test.colombia.js +++ b/test/colombia/pse_test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -78,7 +77,7 @@ describe('Testing pse', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/stores_test.colombia.js b/test/colombia/stores_test.colombia.js index 12d42d7..ab8b6d7 100644 --- a/test/colombia/stores_test.colombia.js +++ b/test/colombia/stores_test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -27,7 +26,7 @@ describe('List stores', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/subscriptions.test.colombia.js b/test/colombia/subscriptions.test.colombia.js index dc26ec1..83c389a 100644 --- a/test/colombia/subscriptions.test.colombia.js +++ b/test/colombia/subscriptions.test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); @@ -117,7 +116,7 @@ describe('Plans testing', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/tokens_test.colombia.js b/test/colombia/tokens_test.colombia.js index d8b8389..918bc5f 100644 --- a/test/colombia/tokens_test.colombia.js +++ b/test/colombia/tokens_test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -46,7 +45,7 @@ describe('Token testing', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/colombia/webhooks_test.colombia.js b/test/colombia/webhooks_test.colombia.js index 6f728b1..f817438 100644 --- a/test/colombia/webhooks_test.colombia.js +++ b/test/colombia/webhooks_test.colombia.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -63,7 +62,7 @@ describe('Webhook testing', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/customers_test.js b/test/customers_test.js index 7154196..c3b830c 100644 --- a/test/customers_test.js +++ b/test/customers_test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -24,7 +23,7 @@ describe('Get customers list with creation[gte] filter', function() { function printLog(code, body, error){ if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if(code>=300){ console.log(' '); diff --git a/test/fees.test.js b/test/fees.test.js index 8202aef..e32505f 100644 --- a/test/fees.test.js +++ b/test/fees.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -24,7 +23,7 @@ describe('Get fees list with creation[lte] filter', function() { function printLog(code, body, error){ if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if(code>=300){ console.log(' '); diff --git a/test/group_test.js b/test/group_test.js index 0aead65..a31b075 100644 --- a/test/group_test.js +++ b/test/group_test.js @@ -1,7 +1,5 @@ var assert = require('assert'); -var _ = require('underscore'); // var request = require('request'); -var urllib = require('urllib'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -337,7 +335,7 @@ describe('Testing group API', function(){ function printLog(code, body, error){ if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if(code>=300){ console.log(' '); @@ -347,15 +345,21 @@ function printLog(code, body, error){ } function getVerificationCode(url, callback) { - urllib.request(url, function(err, body, res){ - var resCode = res.statusCode; - var error = (resCode!=200 && resCode!=201 && resCode!=204) ? body : null; - var verification_code = null; - console.info('error: ' + error); - if (!error) { - verification_code = body.toString().substring(body.indexOf('verification_code') + 28 , body.indexOf('verification_code') + 28 + 8); - console.info('verification_code: ' + verification_code); - } - callback(error, verification_code); - }); + fetch(url) + .then(function(res) { + var resCode = res.status; + var error = (resCode != 200 && resCode != 201 && resCode != 204) ? res.statusText : null; + return res.text().then(function(body) { + console.info('error: ' + error); + var verification_code = null; + if (!error) { + verification_code = body.substring(body.indexOf('verification_code') + 28 , body.indexOf('verification_code') + 28 + 8); + console.info('verification_code: ' + verification_code); + } + callback(error, verification_code); + }); + }) + .catch(function(err) { + callback(err, null); + }); } diff --git a/test/host.test.js b/test/host.test.js new file mode 100644 index 0000000..1bb2488 --- /dev/null +++ b/test/host.test.js @@ -0,0 +1,19 @@ +'use strict'; + +const assert = require('assert'); +const { hostFor } = require('../lib/http-client'); + +describe('hostFor', function () { + it('builds per-country, per-mode hosts', function () { + const base = { merchantId: 'm', privateKey: 'k', timeout: 1 }; + assert.equal(hostFor({ ...base, isSandbox: true, countryCode: 'mx' }), 'https://sandbox-api.openpay.mx'); + assert.equal(hostFor({ ...base, isSandbox: false, countryCode: 'pe' }), 'https://api.openpay.pe'); + assert.equal(hostFor({ ...base, isSandbox: true, countryCode: 'co' }), 'https://sandbox-api.openpay.co'); + }); + + it('constructor falls back to mx on bad country code', function () { + const Openpay = require('../lib/index'); + const op = new Openpay('m', 'k', 'xx'); + assert.equal(hostFor(op['config']), 'https://sandbox-api.openpay.mx'); + }); +}); diff --git a/test/payouts_test.js b/test/payouts_test.js index 35a8055..a431b07 100644 --- a/test/payouts_test.js +++ b/test/payouts_test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -25,7 +24,7 @@ describe('Get all payouts with filters creation and amount', function(){ function printLog(code, body, error){ if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if(code>=300){ console.log(' '); diff --git a/test/peru/cards.pe.test.js b/test/peru/cards.pe.test.js index 5c1e9a4..d1b2ae9 100644 --- a/test/peru/cards.pe.test.js +++ b/test/peru/cards.pe.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -156,7 +155,7 @@ describe('delete card', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/peru/charges.pe.test.js b/test/peru/charges.pe.test.js index 29bed50..6db89eb 100644 --- a/test/peru/charges.pe.test.js +++ b/test/peru/charges.pe.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -198,7 +197,7 @@ describe('Get charges', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/peru/checkouts.pe.test.js b/test/peru/checkouts.pe.test.js index 8eff18c..e72f694 100644 --- a/test/peru/checkouts.pe.test.js +++ b/test/peru/checkouts.pe.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -132,7 +131,7 @@ describe('Update checkouts', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/peru/customers.pe.test.js b/test/peru/customers.pe.test.js index fb950e5..9103399 100644 --- a/test/peru/customers.pe.test.js +++ b/test/peru/customers.pe.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -107,7 +106,7 @@ describe("delete customer", function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/peru/tokens.pe.test.js b/test/peru/tokens.pe.test.js index 54a146b..de28317 100644 --- a/test/peru/tokens.pe.test.js +++ b/test/peru/tokens.pe.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -53,7 +52,7 @@ describe('Get Token', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); console.log(body) } if (code >= 300) { diff --git a/test/peru/webhooks.pe.test.js b/test/peru/webhooks.pe.test.js index 3cc658a..0aa5537 100644 --- a/test/peru/webhooks.pe.test.js +++ b/test/peru/webhooks.pe.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../../lib/openpay'); /*Sandbox*/ @@ -69,7 +68,7 @@ describe('Eliminar Webhook', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/plans.test.js b/test/plans.test.js index f02e9b6..7af4c17 100644 --- a/test/plans.test.js +++ b/test/plans.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -24,7 +23,7 @@ describe('Get plans list with creation[lte] filter', function() { function printLog(code, body, error){ if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if(code>=300){ console.log(' '); diff --git a/test/subscriptions.test.js b/test/subscriptions.test.js index e4b093d..80720bf 100644 --- a/test/subscriptions.test.js +++ b/test/subscriptions.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); @@ -29,7 +28,7 @@ describe('Get all subscriptions with creation filter', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/test/test.js b/test/test.js index 973dca6..d8dd058 100644 --- a/test/test.js +++ b/test/test.js @@ -1,6 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); -var urllib = require('urllib'); var Openpay = require('../lib/openpay'); /*Sandbox*/ @@ -903,7 +901,7 @@ describe('Testing whole API', function(){ function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); @@ -913,15 +911,21 @@ function printLog(code, body, error) { } function getVerificationCode(url, callback) { - urllib.request(url, function(err, body, res){ - var resCode = res.statusCode; - var error = (resCode!=200 && resCode!=201 && resCode!=204) ? body : null; - var verification_code = null; - console.info('error: ' + error); - if (!error) { - verification_code = body.toString().substring(body.indexOf('verification_code') + 28 , body.indexOf('verification_code') + 28 + 8); - console.info('verification_code: ' + verification_code); - } - callback(error, verification_code); - }); + fetch(url) + .then(function(res) { + var resCode = res.status; + var error = (resCode != 200 && resCode != 201 && resCode != 204) ? res.statusText : null; + return res.text().then(function(body) { + console.info('error: ' + error); + var verification_code = null; + if (!error) { + verification_code = body.substring(body.indexOf('verification_code') + 28 , body.indexOf('verification_code') + 28 + 8); + console.info('verification_code: ' + verification_code); + } + callback(error, verification_code); + }); + }) + .catch(function(err) { + callback(err, null); + }); } diff --git a/test/transfers.test.js b/test/transfers.test.js index c18481b..d1f5eb3 100644 --- a/test/transfers.test.js +++ b/test/transfers.test.js @@ -1,5 +1,4 @@ var assert = require('assert'); -var _ = require('underscore'); var Openpay = require('../lib/openpay'); /*Sandbox*/ var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); @@ -33,7 +32,7 @@ describe('Get all transfers with creation filter', function () { function printLog(code, body, error) { if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); + console.log(code, body == null ? '' : Array.isArray(body) ? body.map(x => x.id) : body.id); } if (code >= 300) { console.log(' '); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e5bf98e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "outDir": "./lib", + "rootDir": "./src", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "types": ["node"], + "forceConsistentCasingInFileNames": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "exactOptionalPropertyTypes": false + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "test"] +}