diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c338b28 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +OPENPAY_MERCHANT_ID = "yourmarchantid" +OPENPAY_PRIVATE_KEY = "sk_yourprivatekey" +OPENPAY_DEVICE_SESSION_ID = "session_id_for_testing_charges" +OPENPAY_WEBHOOK_TEST_URL = "https://webhook.site/CREATE-YOUR-TOKEN" diff --git a/.gitignore b/.gitignore index 60b6509..7a3130f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + node_modules -/npm-debug.log -.settings/org.eclipse.wst.jsdt.ui.superType.container -.settings/org.eclipse.wst.jsdt.ui.superType.name -package-lock.json +dist +dist-ssr +*.local +*.tgz +*.zip +.env +.env.testing + +# Editor directories and files +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? 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/.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/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..699ed73 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["biomejs.biome"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..da331b8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + } +} \ No newline at end of file diff --git a/README.md b/README.md index c52d8f1..65768cb 100644 --- a/README.md +++ b/README.md @@ -1,1502 +1,246 @@ -![Openpay nodejs](https://www.openpay.mx/img/github/nodejs.jpg) +![Logo Openpay](https://public.openpay.mx/images/logos/openpay/logo_login.png) -## Installation +# Openpay Node.js -`npm install openpay` +The official SDK for integrating Openpay into your Node.js apps. -## Documentation +## API Documentation -Full API documentation available at http://docs.openpay.mx/. +Full API documentation available at: -## Overview +- México: https://documents.openpay.mx/docs/api/ +- Colombia: https://documents.openpay.co/api/ +- Perú: https://documents.openpay.pe/api-v2/ -```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 >( ... ) -``` - -All methods accept an optional callback as last argument. +## 🚀 Quick Start -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 +Install: -## Examples +```bash +# npm +npm i openpay -### Creating a customer -```js -var newCustomer = { - "name":"John", - "email":"johndoe@example.com", - "last_name":"Doe", - "address":{ - "city":"Queretaro", - "state":"Queretaro", - "line1":"Calle Morelos no 10", - "line2":"col. san pablo", - "postal_code":"76000", - "country_code":"MX" - }, - "phone_number":"44209087654" -}; +# pnpm +pnpm i openpay -openpay.customers.create(newCustomer, function(error, body, response) { - error; // null if no error occurred (status code != 200||201||204) - body; // contains the object returned if no error occurred (status code == 200||201||204) - response; // contains the complete response including the status, statusCode, statusMessage, and more information -}); +# yarn +yarn add openpay ``` -### Charging -```js -var newCharge = { - "method": "card", - "card": { - "card_number": "4111111111111111", - "holder_name": "John Doe", - "expiration_year": "20", - "expiration_month": "12", - "cvv2": "110", - }, - "amount" : 200.00, - "description" : "Service Charge", - "order_id" : "oid-00721" -}; -openpay.charges.create(testCreateCharge, function (error, body, response){ - // ... -}); -``` +Instantiate: -### Payout -```js -var payout = { - "method": "bank_account", - "bank_account":{ - "clabe":"012298026516924616", - "holder_name": "John Doe" - }, - "amount" : 10.50, - "description" : "Monthly payment" -}; -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. +```ts +// ESM / Typescript +import { Openpay } from "openpay"; -```js -var Openpay = require('openpay'); -var openpay = new Openpay('your merchant id', 'your private key', 'mx', false); -openpay.setTimeout(30000); -``` +// CommonJS +const { Openpay } = require("openpay"); -In addition, you can set the merchant id, private key, and the mode like this +const openpay = new Openpay({ + merchantId: process.env.OPENPAY_MERCHANT_ID ?? '', + privateKey: process.env.OPENPAY_PRIVATE_KEY ?? '', + isProductionReady: false, + clientIP: '127.0.0.1', // Public IP address of the client + countryCode: 'mx', +}); -```js -openpay.setMerchantId(' your merchant id '); -openpay.setPrivateKey(' your private key '); -openpay.setProductionReady(true) +// Use the API +await openpay..(); ``` -Once configured the library, you can use it to interact with Openpay API services. +## ✔️ Features -## Development +- ESM and Typescript support +- Async/await support +- Production/Sandbox environments +- Only 1 dependency. Uses [`ofetch`](https://github.com/unjs/ofetch) for simple data fetching +- API errors are thrown by `ofetch`. Use try/catch to handle them gracefully -To run the tests you'll need your sandbox credentials: merchant id and private key from your [Dashboard](https://sandbox-dashboard.openpay.mx/): +> [!IMPORTANT] +> Make sure to review the [official documentation for your country](#api-documentation) to know exactly which API methods are available and country-specific fields that might be required. -```bash -$ npm install -g mocha -$ npm test -``` +## ✔️ Compatibility -# Implementation +This SDK is built for Node.js v14.0.0 and above, but might be compatible with older versions. -## Usage for Mexico +## ⚙️ Configuration -### Bank accounts +To instantiate the Openpay SDK, yo need to pass the following configurations: -#### Creating a bank account -```js -var customerId = 'customer ID'; -var newBankAccount = { - "clabe": "111111111111111111", - "holder_name": "Juan H", - "alias": "Alias" -}; -openpay.customers.bankaccounts.create( - customerId, - newBankAccount, - function (error, body, response) { - // ... - }); -``` +```ts +import { Openpay } from "openpay"; -#### Get bank account: - -```js -var customerId = 'Customer ID'; -var bankAccountId = 'Bank Account Id'; -openpay.customers.bankaccounts.get( - customerId, - bankAccountId, - function (error, body, response) { - // ... - }); +const openpay = new Openpay({ + // Options +}); ``` -#### Delete bank account: -```js -var customerId = 'Customer ID'; -var bankAccountId = 'Bank Account Id'; -openpay.customers.bankaccounts.delete( - customerId, - bankAccountId, - function (error, body, response) { - // ... - }); -``` +| Option | Type | Description | +| ----------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| merchantId | `string` | Your unique merchant ID from the Openpay dashboard | +| privateKey | `string` | Your unique private key from the Openpay dashboard | +| isProductionReady | `boolean` | If `false`, all methods will call the Sandbox API. Otherwise, the Production API will be used. | +| countryCode? | `"mx"` \| `"co"` \| `"pe"` | The country to use the API from. Only México (`mx`), Colombia (`co`) and Perú (`pe`) are supported. Defaults to `mx`. | +| clientIP | `string` | The IP address of the client making the request. Required for charges anti-fraud system. | -#### List bank accounts: -```js -var customerId = 'Customer ID'; -var data = { - "creation": "2021-10-22", // Format yyyy-mm-dd - "offset": "", - "limit": "" -} -openpay.customers.bankaccounts.list( - customerId, - data, - function (error, body, response) { - // ... - }); -``` +If your application supports multiple countries, or you have multiple merchant accounts, we recommend creating an `Openpay` instance for each country/merchant to avoid accidentally using the wrong API. -Instead of the 'creation' field in the 'data' object, you can use: -* "creation[gte]" : "2021-10-22" to find bank accounts created after the given date -* "creation[lte]" : "2021-10-22" to find bank accounts created before the given date +However, if you need to change any of these configurations after instantiation, you can do so with the following methods: -### Cards +```ts +openpay.setMerchantId("new-merchant-id"); +openpay.setPrivateKey("new-private-key"); +openpay.setClientIP("127.0.0.1"); +openpay.setProductionReady(true); +openpay.setCountryCode("co"); +``` -#### Create a card +## ✔️ Error Handling -```js -var newCard = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez", - "expiration_year": 2021, - "expiration_month": "12", - "cvv2": "111" -}; -openpay.cards.create( - newCard, - function (error, body, response) { - // ... - }); -``` -Other way to create a card is through a customer - -```js -var customerId = 'Customer ID'; -var newCard = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez", - "expiration_year": 2021, - "expiration_month": "12", - "cvv2": "111" -}; -openpay.customers.cards.create( - customerId, newCard, - function (error, body, response) { - // ... - }); -``` +Whenever the API returns an error or the SDK is unable to communicate with the API, `Openpay` will throw a `FetchError` from `ofetch`. You can handle any error by wrapping the API call inside of a `try`/`catch` block: -#### Get a card +```ts +import { FetchError } from "ofetch"; -```js -var cardId = 'Card ID'; -openpay.cards.get( - cardId, - function (error, body, response) { - // ... - }); +try { + const customer = await openpay.customers.create(input); +} catch (error) { + if (error instanceof FetchError) { + console.error("Openpay API error:", error.data); + } +} ``` -Just as the method to create a new card, you can get a card through a customer, as is shown below: - -```js -var cardId = 'Card ID'; -var customerId = 'Customer ID'; -openpay.customers.cards.get( - cardId, - customerId, - function (error, body, response) { - // ... - }); -``` +If the `FetchError` was created by the Openpay API, `error.data` will have this shape: -### Charges +| Property | Type | +| ----------------------- | ------------------------------------------ | +| error.data.category | `"request"` \| `"internal"` \| `"gateway"` | +| error.data.error_code | `number` | +| error.data.description | `boolean` | +| error.data.http_code | `number` | +| error.data.request_id | `string` | +| error.data.fraud_rules? | `string[]` \| `undefined` | -### Customers +Any other error that was not caused by the Openpay API, such as connection errors, won't have the same `error.data` shape and must be handled as an `ofetch` `FetchError`. -### Fees +For detailed descriptions and possible error codes, check out [the official documentation](#api-documentation). -### Groups +## ✔️ Examples -### Payouts +### Creating a customer -### Plans +```ts +// Optional. Use type safety +import type { IOpenpay } from "openpay"; -### Subscriptions +const input: IOpenpay.Customers.CreateInput = { + name: "John", + last_name: "Doe", + email: "john.doe@example.com", + phone_number: "1234567890", +}; -### Tests +try { + const customer = await openpay.customers.create(input); + console.log("The newly created customer:", customer); +} catch (error) { + console.error("Openpay API error:", error); +} +``` -### Transfers +### Creating a charge -## Usage for Colombia +```ts +// Optional. Use type safety +import type { IOpenpay } from "openpay"; -### Cards -#### Create a card -There are three ways to create a card, the first one is with a token. -```js -var data = { - "token_id": "Token ID", - "device_session_id": "Device session ID" -}; -openpay.cards.create( - data, - function (error, body, response) { - // ... - }); -``` -The second one is with the card information only. -```js -var newCard = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez", - "expiration_year": '28', - "expiration_month": "12", - "cvv2": "111" -}; -openpay.cards.create(newCard, - function (error, body, response) { - // ... - }); -``` -And the last one is through a customer. -```js -var customerId = 'Customer ID'; -var newCard = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez", - "expiration_year": '28', - "expiration_month": "12", - "cvv2": "111" +const input: IOpenpay.Charge.CreateFromCard = { + amount: 50, + method: "card", + description: "Test existing card charges", + device_session_id: "fraud-protection-token", // Token from client used for fraud prevention + customer: { + name: "John", + last_name: "Doe", + email: "john.doe@example.com", + phone_number: "1234567890", + }, + card: { + card_number: "4111111111111111", + holder_name: "John Doe", + expiration_year: "29", + expiration_month: "1", + cvv2: "110", + }, }; -openpay.customers.cards.create( - customerId, - newCard, - function (error, body, response) { - // ... - }); -``` -#### Get a card -###### Without customer -```js -var cardId = 'Card ID'; -openpay.cards.get( - cardId, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var cardId = 'Card ID'; -openpay.customers.cards.get( - customerId, - cardId, - function (error, body, response) { - // ... - }); -``` -#### Delete a card -###### Without customer -```js -var cardId = 'Card ID'; -openpay.cards.delete( - cardId, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var cardId = 'Card ID'; -openpay.customers.cards.delete( - customerId, - cardId, - function (error, body, response) { - // ... - }); -``` -#### List cards -###### Without customer -```js -var searchParams = { - "creation": "2021-10-22", // Format yyyy-mm-dd - "offset": "", - "limit": "" -} -openpay.cards.list( - searchParams, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var searchParams = { - "creation": "2021-10-22", // Format yyyy-mm-dd - "offset": "", - "limit": "" -} -openpay.customers.cards.list( - customerId, - searchParams, - function (error, body, response) { - // ... - }); -``` -Instead of the 'creation' field in the 'searchParams' object, you can use: -* "creation[gte]" : "2021-10-22" to find bank accounts created after the given date -* "creation[lte]" : "2021-10-22" to find bank accounts created before the given date - -### Charges -#### Create a charge -###### With customer -```js -var customerId = 'Customer ID'; -var newCharge = { - "method": "card", - "source_id": "", - "amount": 20, - "description": "Test Charge", - "currency": "COP", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f" +try { + const transaction = await openpay.charges.create(input); + console.log("The newly created transaction:", transaction); +} catch (error) { + console.error("Openpay API error:", error); } -openpay.customers.charges.create( - customerId, - newCharge, - function (error, body, response) { - // ... - }); ``` -###### Without customer -```js -var newCharge = { - "source_id": "kdx205scoizh93upqbte", - "method": "card", - "amount": 200, - "currency": "COP", - "iva": "10", - "description": "Cargo inicial a mi cuenta", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f", - "customer": { - "name": "Cliente Colombia", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.co" - } -} +> [!TIP] +> For more detailed examples, take a look at the [tests folder](/tests/) and the [API documentation for your country](#api-documentation). -penpay.charges.create( - newCharge, - function (error, body, response) { - // ... - }); -``` -#### Create a store charge -###### With customer -```js -var customerId = 'Customer ID'; -var newCharge = { - "method": "store", - "source_id": "", - "amount": 20, - "description": "Test Charge", - "currency": "COP", - "device_session_id": null -} -openpay.customers.charges.create( - customerId, - newCharge, - function (error, body, response) { - // ... - }); -``` -###### Without customer -```js -var newCharge = { - "source_id": null, - "method": "store", - "amount": 200, - "currency": "COP", - "iva": "10", - "description": "Cargo inicial a mi cuenta", - "device_session_id": null, - "customer": { - "name": "Cliente Colombia", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.co" - } -} +## 🔧 Contributions -penpay.charges.create( - newCharge, - function (error, body, response) { - // ... - }); +To contribute to this project, fork this repository and install the dependencies with pnpm: + +```bash +pnpm i ``` -#### Refund a charge -Only card charges can be refunded. +The project uses [Biome](https://biomejs.dev/) for linting and formatting. If you are using VS Code, we recommend installing the `biomejs.biome` extension and to disable Prettier (`esbenp.prettier-vscode`) if enabled. -```js -var chargeId = 'Charge ID'; -var data = { - "description": "testing refound", - "amount": 200 -} -openpay.charges.refund( - chargeId, - data, - function (error, body, response) { - // ... - }); -``` -#### Get a charge - -###### Without customer -```js -var chargeId = 'Charge ID'; -openpay.charges.get( - chargeId, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var chargeId = 'Charge ID'; -openpay.customers.charges.get( - customerId, - chargeId, - function (error, body, response) { - // ... - }); -``` -#### List charges -###### Without customer -```js -var searchParams = { - 'order_id': 'Order ID', - 'creation': 'yyyy-mm-dd', - 'offset': 1, - 'limit': 1, - 'amount': 100, - 'status': 'IN_PROGRESS' -} -openpay.charges.list(searchParams, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var searchParams = { - 'order_id': 'Order ID', - 'creation': 'yyyy-mm-dd', - 'offset': 1, - 'limit': 1, - 'amount': 100, - 'status': 'IN_PROGRESS' -} -openpay.customers.charges.list( - customerId, - searchParams, - function (error, body, response) { - // ... - }); -``` +### 🧪 Tests -Instead of the 'creation' field in the 'searchParams' object, you can use: -* "creation[gte]" : "2021-10-22" to find charges created after the given date -* "creation[lte]" : "2021-10-22" to find charges created before the given date - -Instead of the 'amount' field in the 'searchParams' object, you can use: -* "amount[gte]" : 100 to find charges with amount bigger than the amount given -* "amount[lte]" : 100 to find charges with amount smaller than the amount given - -Allowed statuses: -* IN_PROGRESS -* COMPLETED -* REFUNDED -* CHARGEBACK_PENDING -* CHARGEBACK_ACCEPTED -* CHARGEBACK_ADJUSTMENT -* CHARGE_PENDING -* CANCELLED -* FAILED -### Customers - -####Create a customer -```js -var newCustomer = { - 'external_id' : '', - "name": "Pedro Diego", - "last_name": "Alatorre Martínez", - "email": "pedro.alatorre@comercio.com", - "phone_number" : "5744484951", - "customer_address": { - "department":"Medellín", - "city":"Antioquía", - "additional":"Avenida 7f bis # 138-58 Apartamento 942" - } -}; -openpay.customers.create( - newCustomer, - function (error, body, response) { - // ... - }); -``` -#### Update a customer -```js -var customerId = 'Customer ID'; -var newData = { - "name": "Pedro Diego", - "last_name": "Alatorre Martínez", - "email": "pedro.alatorre@comercio.com", - "phone_number": "5744484951", - "customer_address": { - "department": "Medellín", - "city": "Antioquía", - "additional": "Avenida 7f bis # 138-58 Apartamento 942" - } -}; -openpay.customers.update( - customerId, - newData, - function (error, body, response) { - // ... - }); -``` -#### Get a customer -```js -var customerId = 'Customer ID'; -openpay.customers.get( - customerId, - function (error, body, response) { - // ... - }); -``` -#### Delete a customer -```js -var customerId = 'Customer ID'; -openpay.customers.delete( - customerId, - function (error, body, response) { - // ... - }); -``` +This project runs tests using [Vitest](https://vitest.dev/) with Typescript. -#### List clients -```js -const searchParams = { - 'external_id': 'External ID', - 'creation': 'yyyy-mm-dd', - 'offset': 1, - 'limit': 1 -} -openpay.customers.list( - searchParams, - function (error, body, response) { - // ... - }); -``` -Instead of the 'creation' field in the 'searchParams' object, you can use: -* "creation[gte]" : "2021-10-22" to find customers created after the given date -* "creation[lte]" : "2021-10-22" to find customers created before the given date - -### Plans -#### Create a plan -```js -var newPlan = { - "amount": 150, - "status_after_retry": "CANCELLED", - "retry_times": 2, - "name": "Curso de ingles", - "repeat_unit": "month", - "trial_days": "30", - "repeat_every": "1" -}; -openpay.plans.create( - newPlan, - function (error, body, response) { - // ... - }); -``` -Allowed values for 'status_after_retry': -* UNPAID -* CANCELLED +There are 3 test files available: +- [`tests/colombia.spec.ts`](/tests/colombia.spec.ts) +- [`tests/mexico.spec.ts`](/tests/mexico.spec.ts) +- [`tests/peru.spec.ts`](/tests/peru.spec.ts) -#### Update a plan -```js -var planId = 'Plan ID'; -var newData = { - "name": "New name", - "trial_days": 1 -} -openpay.plans.update( - planId, - newData, - function (error, body, response) { - // ... - }); -``` -#### Get a plan -```js -var planId = 'Plan ID'; -openpay.plans.get( - planId, - function (error, body, response) { - // ... - }); -``` -#### Delete a plan -```js -var planId = 'Plan ID'; -openpay.plans.delete( - planId, - function (error, body, response) { - // ... - }); -``` +Each one of them tests specific methods that are available to their specific country. However, the one with most of the SDK functionality is [`tests/mexico.spec.ts`](/tests/mexico.spec.ts) since it supports most of the API features. -#### List plans -```js -var searchParams = { - 'creation': 'yyyy-mm-dd', - 'limit': 10, - 'offset': 1 -}; -openpay.plans.list(searchParams, function (error, body, response) { - // ... -}); -``` -Instead of the 'creation' field in the 'searchParams' object, you can use: -* "creation[gte]" : "2021-10-22" to find plans created after the given date -* "creation[lte]" : "2021-10-22" to find plans created before the given date - -### PSE -#### Create PSE -###### Without a client -```js -var newPse = { - "method": "bank_account", - "amount": 10000, - "currency": "COP", - "description": "Cargo inicial a mi cuenta", - "iva": "1900", - "redirect_url": "/", - "customer": { - "name": "Cliente Colombia", - "last_name": "Vazquez Juarez", - "email": "juan.vazquez@empresa.co", - "phone_number": "4448936475", - "requires_account": false, - "customer_address": { - "department": "Medellín", - "city": "Antioquía", - "additional": "Avenida 7m bis #174-25 Apartamento 637" - } - } -} -openpay.pse.create( - newPse, - function (error, body, response) { - // ... - }); -``` -###### With existing client -```js -var customerId = 'Customer ID'; -var newPse = { - "method": "bank_account", - "amount": 10000, - "currency": "COP", - "description": "Cargo inicial a mi cuenta", - "iva": "1900", - "redirect_url": "/" -} -openpay.customers.pse.create( - customerId, - newPse, - function (error, body, response) { - // ... - }); -``` -### Subscriptions -#### Create a subscription -```js -var customerId = 'Customer ID'; -var newSubscription = { - "card": { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "20", - "expiration_month": "12", - "cvv2": "110", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f" - }, - "plan_id": "pbi4kb8hpb64x0uud2eb", - "trial_end_date": "yyyy-mm-dd", - "source_id": "pbiskbfhps64f0uudgeb" -} -openpay.customers.subscriptions.create( - customerId, - newSubscription, - function (error, body, response) { - // ... - }); -``` -#### Update subscription -```js -var subscriptionId = 'Subscription ID'; -const newData = { - "trial_end_date": "2021-12-12", - "cancel_at_period_end": true, - "source_id": "pbiskbfhps64f0uudgeb", - "card": { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "20", - "expiration_month": "12", - "cvv2": "110", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f" - } -} -openpay.customers.subscriptions.update( - subscriptionId, - newData, - function (error, body, response) { - // ... - }); -``` -#### Get a subscription -```js -var customerId = 'Customer ID'; -var subscriptionId = 'Subscription ID'; -openpay.customers.subscriptions.get( - customerId, - subscriptionId, - function (error, body, response) { - // ... - }); -``` -#### Cancel a subscription -```js -var subscriptionId = 'Subscription ID'; -openpay.customers.subscriptions.delete( - subscriptionId, - function (error, body, response) { - // ... - }); -``` -#### List subscriptions -```js -var searchParams = { - 'creation': 'yyyy-mm-dd', - 'limit': 10, - 'offset': 1 -}; -openpay.customers.subscriptions.list( - searchParams, - function (error, body, response) { - // ... - }); -``` -Instead of the 'creation' field in the 'searchParams' object, you can use: -* "creation[gte]" : "2021-10-22" to find subscriptions created after the given date -* "creation[lte]" : "2021-10-22" to find subscriptions created before the given date - -### Webhooks -#### Create a webhook -```js -var newWebhook = { - "url": "https://my-site.com/my-webhook", - "user": "juanito", - "password": "passjuanito", - "event_types": [ - "charge.refunded", - "charge.failed", - "charge.cancelled", - "charge.created", - "chargeback.accepted" - ] -} -openpay.webhooks.create( - newWebhook, - function (error, body, response) { - // ... - }); -``` -#### Get a webhook -```js -var webhookId = 'Webhook ID'; -openpay.webhooks.get( - webhookId, - function (error, body, response) { - // ... - }); -``` +To run the tests, you must create a `.env.testing` file. Use [`.env.example`](/.env.example) as reference. It must contain the following: -#### Delete a webhook -```js -var webhookId = 'Webhook ID'; -openpay.webhooks.delete( - webhookId, - function (error, body, response) { - // ... - }); -``` -#### List webhooks -```js -openpay.webhooks.list( - function (error, body, response) { - // ... - }); -``` +| Variable | Description | +| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| OPENPAY_MERCHANT_ID | Your own unique `merchantId` from the Openpay Sandbox Dashboard | +| OPENPAY_PRIVATE_KEY | Your own unique `privateKey` from the Openpay Sandbox Dashboard | +| OPENPAY_DEVICE_SESSION_ID | A session ID generated by the Openpay.js client for fraud protection | +| OPENPAY_WEBHOOK_TEST_URL | To test webhooks, you must pass a valid endpoint that would reply with status `200`. We recommend creating a free test url from https://webhook.site | -### Tokens -#### Create a token -```js -var newToken = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "29", - "expiration_month": "12", - "cvv2": "110", - "address": { - "city": "Bogotá", - "country_code": "CO", - "postal_code": "110511", - "line1": "Av 5 de Febrero", - "line2": "Roble 207", - "line3": "col carrillo", - "state": "Bogota" - } -}; -openpay.tokens.create( - tokenNew, - function (error, body, response) { - // ... - }); -``` -#### Get a token -```js -var tokenId = 'Token ID'; -openpay.tokens.get( - tokenId, - function (error, body, response) { - // ... - }); -``` -### Stores -#### List stores -```js -var location = { - "latitud": 4.65589142889691, - "longitud": -74.11335673251888, - "kilometers": 10, - "amount": 1 -} -openpay.stores.list( - location, - function (error, body, response) { - // ... - }); -``` +> [!NOTE] +> Please make sure you use your merchant ID and private key for a **SANDBOX** environment. All tests will run on sandbox mode, so passing production values will cause every test to fail. -## Usage for Peru -### Charges -####Create a charge -###### With customer -```js -var customerId = 'Customer ID'; -const newCharge = { - "source_id": "kdx205scoizh93upqbte", - "method": "card", - "amount": 716, - "currency": "PEN", - "description": "Cargo inicial a mi cuenta", - "order_id": "oid-65584", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f" -} -openpay.customers.charges.create( - customerId, - newCharge, - function (error, body, response) { - // ... - }); -``` -###### Without customer -```js -var newCharge = { - "source_id": "kdx205scoizh93upqbte", - "method": "card", - "amount": 100, - "currency": "PEN", - "description": "Cargo inicial a mi cuenta", - "order_id": "oid-65584", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f", - "customer": { - "name": "Cliente Perú", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.pe" - } -}; -openpay.charges.create( - newCharge, - function (error, body, response) { - // ... - }); -``` -###### Store charge -```js -var newCharge = { - "source_id": null, - "method": "store", - "amount": 100, - "currency": "PEN", - "description": "Cargo inicial a mi cuenta", - "order_id": "oid-65584", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f", - "customer": { - "name": "Cliente Perú", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.pe" - } -}; -openpay.charges.create( - newCharge, - function (error, body, response) { - // ... - }); -``` -#### Get a charge -###### Without customer -```js -var chargeId = 'Charge ID'; -openpay.charges.get( - chargeId, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var chargeId = 'Charge ID'; -openpay.customers.charges.get( - customerId, - chargeId, - function (error, body, response) { - // ... - }); -``` -#### List charges -###### Without customer -```js -var searchParams = { - 'order_id': 'Order ID', - 'creation': 'yyyy-mm-dd', - 'offset': 1, - 'limit': 1, - 'amount': 100, - 'status': 'IN_PROGRESS' -} -openpay.charges.list( - searchParams, - function (error, body, response) { - // ... - }); -``` -######With customer -```js -var customerId = 'Customer ID'; -var searchParams = { - 'order_id': 'Order ID', - 'creation': 'yyyy-mm-dd', - 'offset': 1, - 'limit': 1, - 'amount': 100, - 'status': 'IN_PROGRESS' -}; +Before running the tests, you must build the package: -openpay.customers.charges.list( - customerId, - searchParams, - function (error, body, response) { - // ... - }); -``` -Instead of the 'creation' field in the 'searchParams' object, you can use: - -* "creation[gte]" : "2021-10-22" to find charges created after the given date -* "creation[lte]" : "2021-10-22" to find charges created before the given date - -Instead of the 'amount' field in the 'searchParams' object, you can use: - -* "amount[gte]" : 100 to find charges with amount bigger than the amount given -* "amount[lte]" : 100 to find charges with amount smaller than the amount given - -Allowed statuses: -* IN_PROGRESS -* COMPLETED -* REFUNDED -* CHARGEBACK_PENDING -* CHARGEBACK_ACCEPTED -* CHARGEBACK_ADJUSTMENT -* CHARGE_PENDING -* CANCELLED -* FAILED - - -### Checkouts -#### Create a checkout -###### Without customer -```js -var newCheckout = { - "amount": 250, - "currency": "PEN", - "description": "Cargo cobro con link", - "redirect_url": "https://misitioempresa.pe", - "order_id": "oid-66393", - "expiration_date": "2021-08-31 12:50", - "send_email": "true", - "customer": { - "name": "Cliente Perú", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.pe" - } -} -openpay.checkouts.create( - newCheckout, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var newCheckout = { - "amount": 250, - "currency": "PEN", - "description": "Cargo cobro con link cliente", - "redirect_url": "https://misitioempresa.pe", - "order_id": "oid-87491", - "send_email": "true" -} -openpay.customers.checkouts.create( - customerId, - newCheckout, - function (error, body, response) { - // ... - }); -``` -#### List checkouts -```js -var searchParams = { - "limit": 2, - "startDate": "20211001", // Format: yyyymmdd - "endDate": "20211011" // Format: yyyymmdd -}; -openpay.checkouts.list( - searchParams, - function (error, body, response) { - // ... - }); +```bash +pnpm build ``` -#### Update checkout -```js -var checkoutId = 'Checkout ID'; -var newStatus = "available"; -var newData = { - "expiration_date": "2021-10-26 13:43" //Format: yyyy-mm-dd HH:mm -} +Now, you can run the tests for a specific country with their own script: -openpay.checkouts.update( - checkoutId, - newStatus, - newData, - function (error, body, response) { - // ... - }); -``` -Allowed statuses: -* available -* other -* other - -#### Get checkout -```js -var checkoutId = 'Checkout ID'; -openpay.checkouts.get( - checkoutId, - function (error, body, response) { - // ... - }); -``` -### Customers -#### Create a customer -```js -var newCustomer = { - "name": "Juan", - "last_name": "Perez", - "email": "juan.perez.@email.com", - "phone_number": "1234567890", - "address": { - "country_code": "PE", - "postal_code": "12345", - "city": "Lima", - "state": "Lima", - "line1": "Perú", - "line2": "Perú", - "line3": "Perú" - } -}; -openpay.customers.create( - newCustomer, - function (error, body, response) { - // ... - }); -``` -#### Update a customer -```js -var customerId = 'Customer ID'; -var newData = { - "name": "Juan", - "last_name": "Perez", - "email": "juan.perez.@email.com", - "phone_number": "1234567890", - "address": { - "country_code": "PE", - "postal_code": "12345", - "city": "Lima", - "state": "Lima", - "line1": "Perú", - "line2": "Perú", - "line3": "Perú" - } -} -openpay.customers.update( - customerId, - newData, - function (error, body, response) { - // ... - }); -``` -#### Get a customer -```js -var customerId = 'Customer ID'; -openpay.customers.get( - customerId, - function (error, body, respose) { - // ... - }); -``` -#### Delete a customer -```js -var customerId = 'Customer ID'; -openpay.customers.delete( - customerId, - function (error, body, respose) { - // ... - }); -``` -#### List clients -```js -var searchParams = { - 'external_id': 'External ID', - 'creation': 'yyyy-mm-dd', - 'offset': 1, - 'limit': 1 -}; -openpay.customers.list( - searchParams, - function (error, body, response) { - // ... - }); -``` -Instead of the 'creation' field in the 'searchParams' object, you can use: -* "creation[gte]" : "2021-10-22" to find customers created after the given date -* "creation[lte]" : "2021-10-22" to find customers created before the given date -### Cards -#### Create a card -###### With customer - -```js -var customerId = 'Customer ID'; -var newCard = { - "holder_name": "Juan Perez", - "card_number": "4111111111111111", - "cvv2": "651", - "expiration_month": "09", - "expiration_year": "25" -}; -openpay.customers.cards.create( - customerId, - newCard, - function (error, body, response) { - // ... - }); -``` -###### Without customer -```js -var newCard = { - "holder_name": "Juan Perez", - "card_number": "4111111111111111", - "cvv2": "651", - "expiration_month": "09", - "expiration_year": "25" -}; -openpay.cards.create( - newCard, - function (error, body, response) { - // ... - }); -``` -###### With Token -```js -var data = { - "token_id": "Token ID", - "device_session_id": "Device session ID" -}; -openpay.customers.cards.create( - data, - function (error, body, response) { - // ... - }); -``` -###### With Token and customer -```js -var data = { - "token_id": "Token ID", - "device_session_id": "Device session ID" -}; -var customerId = 'Customer ID'; -openpay.customers.cards.create( - customerId, - data, - function (error, body, response) { - // ... - }); -``` -#### Get a card -###### Without customer -```js -var cardId = 'Card ID'; -openpay.cards.get( - cardId, - function (error, body, response) { - // ... - }); -``` -###### With customer -```js -var customerId = 'Customer ID'; -var cardId = 'Card ID'; -openpay.customers.cards.get( - customerId, - cardId, - function (error, body, response) { - // ... - }); -``` -#### Delete a card -###### With customer -```js -var customerId = 'Customer ID'; -var cardId = 'Card ID'; -openpay.customers.cards.delete( - customerId, - cardId, - function (error, body, response) { - // ... - }); -``` -###### Without customer -```js -var cardId = 'Card ID'; -openpay.cards.delete( - cardId, - function (error, body, response) { - // ... - }); -``` -#### List cards -###### With customer -```js -var customerId = 'Customer ID'; -var searchParams = { - 'creation': '2021-01-01', // Format yyyy-mm-dd - 'offset': 10, - 'limit': 1 -}; -openpay.customers.cards.list( - customerId, - searchParams, - function (error, body, response) { - // ... - }); -``` -###### Without customer -```js -var searchParams = { - 'creation': '2021-01-01', // Format yyyy-mm-dd - 'offset': 10, - 'limit': 1 -}; -openpay.cards.list( - searchParams, - function (error, body, response) { - // ... - }); -``` -Instead of the 'creation' field in the 'searchParams' object, you can use: -* "creation[gte]" : "2021-10-22" to find cards created after the given date -* "creation[lte]" : "2021-10-22" to find cards created before the given date -### Webhooks -#### Create a webhook -```js -var webhook = { - "url": "https://mysite.com/myWebhook", - "user": "juanito", - "password": "passjuanito", - "event_types": [ - "charge.failed", - "charge.cancelled", - "charge.created", - "chargeback.accepted" - ] -} -openpay.webhooks.create(webhook, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 201, ''); - done(); - }); -``` -The allowed values fot the field *event_types* are: -* charge.refunded -* charge.failed -* charge.cancelled -* charge.created -* charge.succeeded -* charge.rescored.to.decline -* subscription.charge.failed -* payout.created -* payout.succeeded -* payout.failed -* transfer.succeeded -* fee.succeeded -* fee.refund.succeeded -* spei.received -* chargeback.created -* chargeback.rejected -* chargeback.accepted -* order.created -* order.activated -* order.payment.received -* order.completed -* order.expired -* order.cancelled -* order.payment.cancelled -#### Get a webhook -```js -var webhookId = 'Webhook ID'; -openpay.webhooks.get(webhookId, - function (error, body, response) { - // ... - }); -``` -#### Delete a webhook -```js -var webhookId = 'Webhook ID'; -openpay.webhooks.delete( - webhookId, - function (error, body, response) { - // ... - }); -``` -#### List webhooks -```js -openpay.webhooks.list( - function (error, body, response) { - // ... - }); -``` -### Tokens -#### Create a token -```js -const newToken = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "21", - "expiration_month": "12", - "cvv2": "110", - "address": { - "city": "Lima", - "country_code": "PE", - "postal_code": "110511", - "line1": "Av 5 de Febrero", - "line2": "Roble 207", - "line3": "col carrillo", - "state": "Lima" - } -} -openpay.tokens.create( - newToken, - function (error, body, response) { - // ... - }); -``` -#### Get a token -```js -var tokenId = 'Token ID'; -openpay.tokens.get( - tokenId, - function (error, body, response) { - // ... - }); +```bash +# For México +pnpm test:mx + +# For Colombia +pnpm test:co + +# For Perú +pnpm test:pe ``` + +> [!IMPORTANT] +> The tests depend on having `OPENPAY_MERCHANT_ID` and `OPENPAY_PRIVATE_KEY` from an account created in the country you're running the tests on. For example: if you want to run `pnpm test:co`, you must use a merchant ID and private key from an account created in Openpay Colombia. Otherwise the tests will fail. + +> [!NOTE] +> For México tests, the transfers and fees API's might fail since they require the customer to have funds, but the account created during the test won't have any. If you get a different error, please check your implementation. diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..64fd327 --- /dev/null +++ b/biome.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "files": { + "ignore": ["./lib/**", "./dist/**", "./test/**"] + }, + "formatter": { + "indentStyle": "space", + "indentWidth": 2 + }, + "javascript": { + "formatter": { + "lineWidth": 110, + "quoteStyle": "single", + "semicolons": "always" + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noExplicitAny": "off" + } + } + }, + "organizeImports": { + "enabled": true + } +} 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 deleted file mode 100644 index bc269be..0000000 --- a/package-lock.json +++ /dev/null @@ -1,1698 +0,0 @@ -{ - "name": "openpay", - "version": "1.0.5", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" - }, - "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" - } - }, - "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 - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "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 - }, - "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 - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "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==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "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==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "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" - } - } - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "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" - }, - "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" - } - } - } - }, - "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==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "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": { - "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==", - "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" - }, - "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" - }, - "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" - } - } - } - }, - "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 - }, - "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" - } - } - } - }, - "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==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "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": { - "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" - } - }, - "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 - }, - "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" - } - }, - "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" - } - }, - "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==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "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": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "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" - } - } - } - }, - "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": { - "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" - } - }, - "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==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "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==", - "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" - }, - "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=" - } - } - }, - "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" - } - }, - "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" - } - }, - "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" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "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=" - }, - "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": { - "binary-extensions": "^2.0.0" - } - }, - "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": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "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 - }, - "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==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "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": { - "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" - } - }, - "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==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "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==", - "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" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "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==", - "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" - } - }, - "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==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "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" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "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", - "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" - } - }, - "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==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "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 - }, - "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 - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "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==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "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==", - "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" - }, - "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==" - } - } - }, - "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" - } - }, - "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": { - "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" - } - }, - "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" - }, - "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==" - } - } - }, - "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" - }, - "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" - } - } - } - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "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 - }, - "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=", - "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==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.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==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "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=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "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==", - "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" - } - }, - "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": { - "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": { - "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=" - } - } - }, - "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==", - "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==", - "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" - } - }, - "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==" - }, - "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==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.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" - } - } - } - }, - "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==", - "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", - "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" - }, - "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" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - } - } - } -} diff --git a/package.json b/package.json index beaa73e..b01de27 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,41 @@ { "name": "openpay", "description": "Openpay library", - "version": "2.0.1", - "dependencies": { - "underscore": "1.13.6", - "urllib": "^2.36.1" + "version": "3.0.0", + "repository": "https://github.com/open-pay/openpay-node", + "type": "module", + "sideEffects": false, + "main": "./dist/openpay.cjs", + "module": "./dist/openpay.js", + "types": "./dist/openpay.d.cts", + "exports": { + ".": { + "types": "./dist/openpay.d.ts", + "require": "./dist/openpay.cjs", + "import": "./dist/openpay.js" + } + }, + "files": ["dist"], + "scripts": { + "build": "rimraf dist && tsup src/openpay.ts --format cjs,esm --dts --no-splitting", + "lint": "biome lint ./src", + "test:mx": "vitest run mexico", + "test:co": "vitest run colombia", + "test:pe": "vitest run peru" }, - "main": "lib/openpay.js", "devDependencies": { - "mocha": "10.2.0" + "@biomejs/biome": "^1.9.4", + "@types/node": "^22.9.1", + "dotenv": "^16.4.5", + "rimraf": "^6.0.1", + "tsup": "^8.3.5", + "typescript": "^5.7.2", + "vitest": "^2.1.5" }, - "scripts": { - "test": "mocha" + "dependencies": { + "ofetch": "^1.4.1" }, "engines": { - "node": ">=0.6.x" + "node": ">=14.0.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..c7130f8 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1847 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + ofetch: + specifier: ^1.4.1 + version: 1.4.1 + devDependencies: + '@biomejs/biome': + specifier: ^1.9.4 + version: 1.9.4 + '@types/node': + specifier: ^22.9.1 + version: 22.9.1 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 + tsup: + specifier: ^8.3.5 + version: 8.3.5(postcss@8.4.49)(typescript@5.7.2)(yaml@2.4.2) + typescript: + specifier: ^5.7.2 + version: 5.7.2 + vitest: + specifier: ^2.1.5 + version: 2.1.5(@types/node@22.9.1) + +packages: + + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@rollup/rollup-android-arm-eabi@4.27.3': + resolution: {integrity: sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.27.3': + resolution: {integrity: sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.27.3': + resolution: {integrity: sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.27.3': + resolution: {integrity: sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.27.3': + resolution: {integrity: sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.27.3': + resolution: {integrity: sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.27.3': + resolution: {integrity: sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.27.3': + resolution: {integrity: sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.27.3': + resolution: {integrity: sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.27.3': + resolution: {integrity: sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': + resolution: {integrity: sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.27.3': + resolution: {integrity: sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.27.3': + resolution: {integrity: sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.27.3': + resolution: {integrity: sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.27.3': + resolution: {integrity: sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.27.3': + resolution: {integrity: sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.27.3': + resolution: {integrity: sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.27.3': + resolution: {integrity: sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==} + cpu: [x64] + os: [win32] + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/node@22.9.1': + resolution: {integrity: sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==} + + '@vitest/expect@2.1.5': + resolution: {integrity: sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==} + + '@vitest/mocker@2.1.5': + resolution: {integrity: sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.5': + resolution: {integrity: sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==} + + '@vitest/runner@2.1.5': + resolution: {integrity: sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==} + + '@vitest/snapshot@2.1.5': + resolution: {integrity: sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==} + + '@vitest/spy@2.1.5': + resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==} + + '@vitest/utils@2.1.5': + resolution: {integrity: sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + bundle-require@5.0.0: + resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@11.0.0: + resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} + engines: {node: 20 || >=22} + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jackspeak@4.0.2: + resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} + engines: {node: 20 || >=22} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.0.2: + resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} + engines: {node: 20 || >=22} + + magic-string@0.30.13: + resolution: {integrity: sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==} + + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + rimraf@6.0.1: + resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} + engines: {node: 20 || >=22} + hasBin: true + + rollup@4.27.3: + resolution: {integrity: sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsup@8.3.5: + resolution: {integrity: sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + vite-node@2.1.5: + resolution: {integrity: sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.5: + resolution: {integrity: sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.5 + '@vitest/ui': 2.1.5 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + yaml@2.4.2: + resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} + engines: {node: '>= 14'} + hasBin: true + +snapshots: + + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.24.0': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.24.0': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.24.0': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.24.0': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.24.0': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.24.0': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.24.0': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.24.0': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.24.0': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.24.0': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.24.0': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.24.0': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.24.0': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.24.0': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.24.0': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.24.0': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.24.0': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.24.0': + optional: true + + '@esbuild/openbsd-arm64@0.24.0': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.24.0': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.24.0': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.24.0': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.24.0': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.24.0': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@rollup/rollup-android-arm-eabi@4.27.3': + optional: true + + '@rollup/rollup-android-arm64@4.27.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.27.3': + optional: true + + '@rollup/rollup-darwin-x64@4.27.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.27.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.27.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.27.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.27.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.27.3': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.27.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.27.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.27.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.27.3': + optional: true + + '@types/estree@1.0.6': {} + + '@types/node@22.9.1': + dependencies: + undici-types: 6.19.8 + + '@vitest/expect@2.1.5': + dependencies: + '@vitest/spy': 2.1.5 + '@vitest/utils': 2.1.5 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.5(vite@5.4.11(@types/node@22.9.1))': + dependencies: + '@vitest/spy': 2.1.5 + estree-walker: 3.0.3 + magic-string: 0.30.13 + optionalDependencies: + vite: 5.4.11(@types/node@22.9.1) + + '@vitest/pretty-format@2.1.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.5': + dependencies: + '@vitest/utils': 2.1.5 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.5': + dependencies: + '@vitest/pretty-format': 2.1.5 + magic-string: 0.30.13 + pathe: 1.1.2 + + '@vitest/spy@2.1.5': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.5': + dependencies: + '@vitest/pretty-format': 2.1.5 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + assertion-error@2.0.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + bundle-require@5.0.0(esbuild@0.24.0): + dependencies: + esbuild: 0.24.0 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + + check-error@2.1.1: {} + + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@4.1.1: {} + + consola@3.2.3: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + + destr@2.0.3: {} + + dotenv@16.4.5: {} + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + es-module-lexer@1.5.4: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.24.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + + expect-type@1.1.0: {} + + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@11.0.0: + dependencies: + foreground-child: 3.3.0 + jackspeak: 4.0.2 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + + is-fullwidth-code-point@3.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jackspeak@4.0.2: + dependencies: + '@isaacs/cliui': 8.0.2 + + joycon@3.1.1: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lodash.sortby@4.7.0: {} + + loupe@3.1.2: {} + + lru-cache@10.4.3: {} + + lru-cache@11.0.2: {} + + magic-string@0.30.13: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.7: {} + + node-fetch-native@1.6.4: {} + + object-assign@4.1.1: {} + + ofetch@1.4.1: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.4 + + package-json-from-dist@1.0.1: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.2 + minipass: 7.1.2 + + pathe@1.1.2: {} + + pathval@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@4.0.2: {} + + pirates@4.0.6: {} + + postcss-load-config@6.0.1(postcss@8.4.49)(yaml@2.4.2): + dependencies: + lilconfig: 3.1.2 + optionalDependencies: + postcss: 8.4.49 + yaml: 2.4.2 + + postcss@8.4.49: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + punycode@2.3.1: {} + + readdirp@4.0.2: {} + + resolve-from@5.0.0: {} + + rimraf@6.0.1: + dependencies: + glob: 11.0.0 + package-json-from-dist: 1.0.1 + + rollup@4.27.3: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.27.3 + '@rollup/rollup-android-arm64': 4.27.3 + '@rollup/rollup-darwin-arm64': 4.27.3 + '@rollup/rollup-darwin-x64': 4.27.3 + '@rollup/rollup-freebsd-arm64': 4.27.3 + '@rollup/rollup-freebsd-x64': 4.27.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.27.3 + '@rollup/rollup-linux-arm-musleabihf': 4.27.3 + '@rollup/rollup-linux-arm64-gnu': 4.27.3 + '@rollup/rollup-linux-arm64-musl': 4.27.3 + '@rollup/rollup-linux-powerpc64le-gnu': 4.27.3 + '@rollup/rollup-linux-riscv64-gnu': 4.27.3 + '@rollup/rollup-linux-s390x-gnu': 4.27.3 + '@rollup/rollup-linux-x64-gnu': 4.27.3 + '@rollup/rollup-linux-x64-musl': 4.27.3 + '@rollup/rollup-win32-arm64-msvc': 4.27.3 + '@rollup/rollup-win32-ia32-msvc': 4.27.3 + '@rollup/rollup-win32-x64-msvc': 4.27.3 + fsevents: 2.3.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + source-map-js@1.2.1: {} + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + stackback@0.0.2: {} + + std-env@3.8.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinybench@2.9.0: {} + + tinyexec@0.3.1: {} + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + + tsup@8.3.5(postcss@8.4.49)(typescript@5.7.2)(yaml@2.4.2): + dependencies: + bundle-require: 5.0.0(esbuild@0.24.0) + cac: 6.7.14 + chokidar: 4.0.1 + consola: 3.2.3 + debug: 4.3.7 + esbuild: 0.24.0 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(postcss@8.4.49)(yaml@2.4.2) + resolve-from: 5.0.0 + rollup: 4.27.3 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.1 + tinyglobby: 0.2.10 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.4.49 + typescript: 5.7.2 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + typescript@5.7.2: {} + + ufo@1.5.4: {} + + undici-types@6.19.8: {} + + vite-node@2.1.5(@types/node@22.9.1): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 5.4.11(@types/node@22.9.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.11(@types/node@22.9.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.27.3 + optionalDependencies: + '@types/node': 22.9.1 + fsevents: 2.3.3 + + vitest@2.1.5(@types/node@22.9.1): + dependencies: + '@vitest/expect': 2.1.5 + '@vitest/mocker': 2.1.5(vite@5.4.11(@types/node@22.9.1)) + '@vitest/pretty-format': 2.1.5 + '@vitest/runner': 2.1.5 + '@vitest/snapshot': 2.1.5 + '@vitest/spy': 2.1.5 + '@vitest/utils': 2.1.5 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.13 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@22.9.1) + vite-node: 2.1.5(@types/node@22.9.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.9.1 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + webidl-conversions@4.0.2: {} + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + yaml@2.4.2: + optional: true diff --git a/src/openpay.ts b/src/openpay.ts new file mode 100644 index 0000000..0c3a1ce --- /dev/null +++ b/src/openpay.ts @@ -0,0 +1,411 @@ +import type { FetchOptions } from 'ofetch'; +import type { IOpenpay } from './types'; + +import { ofetch } from 'ofetch'; + +const OPEN_PAY_MX_BASE_URL = 'https://api.openpay.mx'; +const OPEN_PAY_MX_SANDBOX_URL = 'https://sandbox-api.openpay.mx'; +const OPEN_PAY_API_VERSION = 'v1'; +const OPEN_PAY_SANDBOX_API_VERSION = 'v1'; + +export { IOpenpay } from './types'; + +export class Openpay { + private merchantId = ''; + private privateKey = ''; + private isSandbox = true; + private clientIP = ''; + private timeout = 9000; // 9 seconds in milliseconds + + private baseUrl = OPEN_PAY_MX_BASE_URL; + private sandboxUrl = OPEN_PAY_MX_SANDBOX_URL; + + constructor(options: IOpenpay.Options) { + this.setMerchantId(options.merchantId); + this.setPrivateKey(options.privateKey); + this.setProductionReady(options.isProductionReady); + this.setClientIP(options.clientIP); + this.setCountryCode(options.countryCode ?? 'mx'); + } + + public setTimeout(ms: number) { + this.timeout = ms; + } + + public setMerchantId(merchantId: string) { + this.merchantId = merchantId; + } + + public setPrivateKey(privateKey: string) { + this.privateKey = privateKey; + } + + public setProductionReady(isProductionReady: boolean) { + this.isSandbox = !isProductionReady; + } + + public setCountryCode(code: IOpenpay.Countries) { + this.setBaseUrl(code); + } + + public setClientIP(ipAddress: string) { + const isValid = new RegExp(/^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/).test(ipAddress); + if (!isValid) { + console.error('(Openpay): Invalid client IP address'); + throw new Error('(Openpay): Invalid client IP address'); + } + + this.clientIP = ipAddress; + } + + private setBaseUrl(countryCode: IOpenpay.Countries) { + switch (countryCode) { + case 'pe': + this.baseUrl = 'https://api.openpay.pe'; + this.sandboxUrl = 'https://sandbox-api.openpay.pe'; + break; + case 'co': + this.baseUrl = 'https://api.openpay.co'; + this.sandboxUrl = 'https://sandbox-api.openpay.co'; + break; + default: + if (countryCode !== 'mx') console.error('(Openpay): Invalid country code. Setting MX as default.'); + this.baseUrl = OPEN_PAY_MX_BASE_URL; + this.sandboxUrl = OPEN_PAY_MX_SANDBOX_URL; + break; + } + } + + private async sendRequest(apiPath: string, options?: FetchOptions<'json'>): Promise { + const url = this.isSandbox + ? `${this.sandboxUrl}/${OPEN_PAY_SANDBOX_API_VERSION}/${apiPath}` + : `${this.baseUrl}/${OPEN_PAY_API_VERSION}/${apiPath}`; + + return await ofetch(url, { + ...options, + timeout: this.timeout, + method: options?.method || 'GET', + headers: { + 'X-Forwarded-For': this.clientIP, + Authorization: `Basic ${Buffer.from(`${this.privateKey}:`).toString('base64')}`, + }, + }); + } + + private async sendStoreRequest(apiPath: string, options: FetchOptions<'json'>): Promise { + const url = this.isSandbox ? `${this.sandboxUrl}/${apiPath}` : `${this.baseUrl}/${apiPath}`; + + return await ofetch(url, { + ...options, + timeout: this.timeout, + method: options.method || 'GET', + headers: { + Authorization: `Basic ${Buffer.from(`${this.privateKey}:`).toString('base64')}`, + }, + }); + } + + public charges: IOpenpay.SDK.Charges = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/charges`, { + method: 'POST', + body: data, + }), + + capture: async (txnId, data) => + await this.sendRequest(`${this.merchantId}/charges/${txnId}/capture`, { + method: 'POST', + body: data, + }), + + get: async (txnId) => await this.sendRequest(`${this.merchantId}/charges/${txnId}`), + + list: async (query) => await this.sendRequest(`${this.merchantId}/charges`, { query }), + + refund: async (txnId, data) => + await this.sendRequest(`${this.merchantId}/charges/${txnId}/refund`, { + method: 'POST', + body: data, + }), + }; + + public payouts: IOpenpay.SDK.Payouts = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/payouts`, { + method: 'POST', + body: data, + }), + + list: async (query) => await this.sendRequest(`${this.merchantId}/payouts`, { query }), + + get: async (txnId) => await this.sendRequest(`${this.merchantId}/payouts/${txnId}`), + }; + + public fees: IOpenpay.SDK.Fees = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/fees`, { + method: 'POST', + body: data, + }), + + list: async (query) => await this.sendRequest(`${this.merchantId}/fees`, { query }), + }; + + public customers: IOpenpay.SDK.Customers = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/customers`, { + method: 'POST', + body: data, + }), + + list: async (query) => await this.sendRequest(`${this.merchantId}/customers`, { query }), + + get: async (customerId) => await this.sendRequest(`${this.merchantId}/customers/${customerId}`), + + delete: async (customerId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}`, { method: 'DELETE' }), + + update: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}`, { + method: 'PUT', + body: data, + }), + + charges: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/charges`, { + method: 'POST', + body: data, + }), + + capture: async (customerId, txnId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/charges/${txnId}/capture`, { + method: 'POST', + body: data, + }), + + get: async (customerId, txnId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/charges/${txnId}`), + + list: async (customerId, query) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/charges`, { query }), + + refund: async (customerId, txnId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/charges/${txnId}/refund`, { + method: 'POST', + body: data, + }), + }, + + transfers: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/transfers`, { + method: 'POST', + body: data, + }), + + get: async (customerId, txnId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/transfers/${txnId}`), + + list: async (customerId, query) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/transfers`, { query }), + }, + + payouts: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/payouts`, { + method: 'POST', + body: data, + }), + + get: async (customerId, txnId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/payouts/${txnId}`), + + list: async (customerId, query) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/payouts`, { query }), + }, + + subscriptions: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/subscriptions`, { + method: 'POST', + body: data, + }), + + get: async (customerId, subId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/subscriptions/${subId}`), + + list: async (customerId, query) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/subscriptions`, { query }), + + update: async (customerId, subId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/subscriptions/${subId}`, { + method: 'PUT', + body: data, + }), + + delete: async (customerId, subId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/subscriptions/${subId}`, { + method: 'DELETE', + }), + }, + + cards: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/cards`, { + method: 'POST', + body: data, + }), + + get: async (customerId, cardId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/cards/${cardId}`), + + list: async (customerId, query) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/cards`, { query }), + + update: async (customerId, cardId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/cards/${cardId}`, { + method: 'PUT', + body: data, + }), + + delete: async (customerId, cardId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/cards/${cardId}`, { + method: 'DELETE', + }), + }, + + bankaccounts: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/bankaccounts`, { + method: 'POST', + body: data, + }), + + get: async (customerId, bankId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/bankaccounts/${bankId}`), + + list: async (customerId, query) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/bankaccounts`, { query }), + + delete: async (customerId, bankId) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/bankaccounts/${bankId}`, { + method: 'DELETE', + }), + }, + + pse: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/charges`, { + method: 'POST', + body: data, + }), + }, + + checkouts: { + create: async (customerId, data) => + await this.sendRequest(`${this.merchantId}/customers/${customerId}/checkouts`, { + method: 'POST', + body: data, + }), + }, + }; + + public cards: IOpenpay.SDK.Cards = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/cards`, { + method: 'POST', + body: data, + }), + + list: async (query) => await this.sendRequest(`${this.merchantId}/cards`, { query }), + + get: async (cardId) => await this.sendRequest(`${this.merchantId}/cards/${cardId}`), + + delete: async (cardId) => + await this.sendRequest(`${this.merchantId}/cards/${cardId}`, { method: 'DELETE' }), + + update: async (cardId, data) => + await this.sendRequest(`${this.merchantId}/cards/${cardId}`, { + method: 'PUT', + body: data, + }), + }; + + public plans: IOpenpay.SDK.Plans = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/plans`, { + method: 'POST', + body: data, + }), + + list: async (query) => await this.sendRequest(`${this.merchantId}/plans`, { query }), + + get: async (planId) => await this.sendRequest(`${this.merchantId}/plans/${planId}`), + + delete: async (planId) => + await this.sendRequest(`${this.merchantId}/plans/${planId}`, { method: 'DELETE' }), + + update: async (planId, data) => + await this.sendRequest(`${this.merchantId}/plans/${planId}`, { + method: 'PUT', + body: data, + }), + }; + + public webhooks: IOpenpay.SDK.Webhooks = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/webhooks`, { + method: 'POST', + body: data, + }), + + list: async () => await this.sendRequest(`${this.merchantId}/webhooks`), + + get: async (webhookId) => await this.sendRequest(`${this.merchantId}/webhooks/${webhookId}`), + + delete: async (webhookId) => + await this.sendRequest(`${this.merchantId}/webhooks/${webhookId}`, { method: 'DELETE' }), + }; + + public tokens: IOpenpay.SDK.Tokens = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/tokens`, { + method: 'POST', + body: data, + }), + + get: async (tokenId) => await this.sendRequest(`${this.merchantId}/tokens/${tokenId}`), + }; + + public stores: IOpenpay.SDK.Stores = { + list: async (query) => await this.sendStoreRequest('stores', { query }), + }; + + public pse: IOpenpay.SDK.Pse = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/charges`, { + method: 'POST', + body: data, + }), + }; + + public checkouts: IOpenpay.SDK.Checkouts = { + create: async (data) => + await this.sendRequest(`${this.merchantId}/checkouts`, { + method: 'POST', + body: data, + }), + + list: async (query) => await this.sendRequest(`${this.merchantId}/checkouts`, { query }), + + get: async (checkoutId) => await this.sendRequest(`${this.merchantId}/checkouts/${checkoutId}`), + + update: async (checkoutId, status, data) => + await this.sendRequest(`${this.merchantId}/checkouts/${checkoutId}`, { + method: 'PUT', + body: data, + query: { status }, + }), + }; +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..70aa811 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,648 @@ +export namespace IOpenpay { + export type Countries = 'mx' | 'co' | 'pe'; + export type Currency = 'MXN' | 'USD' | 'COP' | 'PEN'; + export type PaymentMonths = 3 | 6 | 9 | 12 | 18; + + export interface Error { + category: 'request' | 'internal' | 'gateway'; + error_code: number; + description: string; + http_code: number; + request_id: string; + fraud_rules?: string[]; + } + + export interface Options { + merchantId: string; + privateKey: string; + isProductionReady: boolean; + clientIP: string; + countryCode?: Countries; + } + + export interface Address { + line1: string; + line2: string | null; + line3: string | null; + postal_code: string; + state: string; + city: string; + country_code: string; + } + + export interface BasicListQuery { + creation?: string; + 'creation[gte]'?: string; + 'creation[lte]'?: string; + offset?: number; + limit?: number; + } + + export interface Customer { + id: string; + creation_date: string; + name: string; + last_name: string; + email: string; + phone_number: string; + status: 'active' | 'deleted'; + balance: number; + clabe: string | null; + address: Address | null; + external_id: string | null; + store: { + reference: string; + barcode_url: string; + }; + /** COLOMBIA ONLY */ + customer_address?: { + department: string; + city: string; + additional: string; + }; + } + + export namespace Customer { + export interface CreateInput { + name: string; + email: string; + address?: Address; + last_name?: string; + phone_number?: string; + requires_account?: boolean; + external_id?: string | null; + /** COLOMBIA ONLY */ + customer_address?: Customer['customer_address']; + } + + export interface ListQuery extends BasicListQuery { + external_id?: string; + } + + export type UpdateInput = Omit; + } + + export interface Card { + id: string; + creation_date: string; + holder_name: string; + card_number: string; + cvv2: string; + expiration_month: string; + expiration_year: string; + address: Address | null; + allows_charges: boolean; + allows_payouts: boolean; + brand: string; + type: string; + bank_name: string; + bank_code: string; + customer_id?: string; + points_card?: boolean; + } + + export namespace Card { + export type CreateInput = + | { + holder_name: string; + card_number: string; + cvv2: string; + expiration_month: string; + expiration_year: string; + device_session_id?: string; + address?: Address; + } + | { + token_id: string; + device_session_id: string; + }; + + export interface UpdateInput { + holder_name?: string; + cvv2?: string; + expiration_month?: string; + expiration_year?: string; + merchant_id?: string; + } + + export type ListQuery = BasicListQuery; + } + + export namespace Transaction { + export type Method = 'card' | 'bank' | 'customer' | 'store'; + export type TransactionType = 'fee' | 'charge' | 'payout' | 'transfer'; + export type OperationType = 'in' | 'out'; + export type Status = 'completed' | 'in_progress' | 'failed'; + } + + export interface Transaction { + id: string; + authorization: string | null; + transaction_type: Transaction.TransactionType; + operation_type: Transaction.OperationType; + method: Transaction.Method; + creation_date: string; + operation_date: string; + order_id: string | null; + status: Transaction.Status; + amount: number; + description: string; + conciliated: boolean; + error_message: string | null; + customer_id: string | null; + currency: Currency; + bank_account?: BankAccount; + card?: Card; + card_points?: CardPoints; + gateway_card_present?: string; + due_date?: string; + payment_method?: { + type: string; + url?: string; + reference?: string; + barcode_url?: string; + paybin_reference?: string; + barcode_paybin_url?: string; + }; + fee?: { + amount: number; + tax: number; + currency: Currency; + }; + /** COLOMBIA ONLY */ + iva?: string | null; + } + + export interface Token { + id: string; + card: Card; + } + + export namespace Token { + export interface CreateInput { + holder_name: string; + card_number: string; + cvv2: string; + expiration_month: string; + expiration_year: string; + address: Address; + } + } + + export interface CardPoints { + used: number; + remaining: number; + amount: number; + caption?: string; + } + + export namespace Charge { + export interface CreateBase { + amount: number; + description: string; + order_id?: string; + customer?: Customer.CreateInput; + currency?: Currency; + redirect_url?: string; + /** COLOMBIA ONLY */ + iva?: string; + } + + export interface CreateFromCard extends CreateBase { + method: 'card'; + source_id: string; + device_session_id?: string; + capture?: boolean; + payment_plan?: { payments: PaymentMonths }; + metadata?: Record; + use_card_points?: 'NONE' | 'MIXED' | 'ONLY_POINTS'; + confirm?: boolean; + send_email?: boolean; + use_3d_secure?: boolean; + } + + export interface CreateFromStore extends CreateBase { + method: 'store'; + due_date?: string; + } + + export interface CreateFromBank extends CreateBase { + method: 'bank_account'; + due_date?: string; + } + + export interface CreateFromAlipay extends CreateBase { + method: 'alipay'; + due_date?: string; + } + + export interface CreateFromIVR extends CreateBase { + method: 'card'; + confirm: 'ivr'; + currency?: Currency; + metadata?: Record; + send_email?: boolean; + } + + export type CreateInput = + | CreateFromCard + | CreateFromStore + | CreateFromBank + | CreateFromAlipay + | CreateFromIVR; + + export type CaptureInput = { + amount?: number; + } | null; + + export interface RefundInput { + description?: string; + amount?: number; + } + + export interface ListQuery extends BasicListQuery { + order_id?: string; + amount?: number; + 'amount[gte]'?: number; + 'amount[lte]'?: number; + status?: + | 'IN_PROGRESS' + | 'COMPLETED' + | 'REFUNDED' + | 'CHARGEBACK_PENDING' + | 'CHARGEBACK_ACCEPTED' + | 'CHARGEBACK_ADJUSTMENT' + | 'CHARGE_PENDING' + | 'CANCELLED' + | 'FAILED'; + } + } + + export namespace Payout { + export interface CreateInput { + method: 'bank_account' | 'card'; + amount: number; + description: string; + order_id?: string; + destination_id?: string; + card?: { + card_number: string; + holder_name: string; + bank_code: string; + }; + bank_account?: { + clabe: string; + holder_name: string; + }; + } + + export interface ListQuery extends BasicListQuery { + amount?: number; + 'amount[gte]'?: number; + 'amount[lte]'?: number; + payout_type?: 'ALL' | 'AUTOMATIC' | 'MANUAL'; + } + } + + export namespace Fee { + export interface CreateInput { + customer_id: string; + amount: number; + description: string; + order_id?: string; + } + + export type ListQuery = BasicListQuery; + } + + export interface Store { + id_store: string; + id: string; + name: string; + last_update: string; + geolocation: { lng: number; lat: number; place_id: string }; + address: Address; + paynet_chain: { + name: string; + logo: string; + thumb: string; + max_amount: number; + }; + } + + export namespace Store { + export interface ListQuery { + latitud: number; + longitud: number; + kilometers: number; + amount: number; + } + } + + export interface Webhook { + id: string; + url: string; + user?: string; + password?: string; + force_host_ssl?: boolean; + allow_redirects?: boolean; + event_types: Webhook.EventTypes[]; + status: 'verified' | 'unverified'; + } + + export namespace Webhook { + export type EventTypes = + | 'charge.refunded' + | 'charge.failed' + | 'charge.cancelled' + | 'charge.created' + | 'charge.succeeded' + | 'charge.rescored.to.decline' + | 'subscription.charge.failed' + | 'payout.created' + | 'payout.succeeded' + | 'payout.failed' + | 'transfer.succeeded' + | 'fee.succeeded' + | 'fee.refund.succeeded' + | 'spei.received' + | 'chargeback.created' + | 'chargeback.rejected' + | 'chargeback.accepted' + | 'order.created' + | 'order.activated' + | 'order.payment.received' + | 'order.completed' + | 'order.expired' + | 'order.cancelled' + | 'order.payment.cancelled'; + + export type CreateInput = Pick; + } + + export interface Plan { + id: string; + creation_date: string; + name: string; + amount: number; + currency: Currency; + repeat_every: number; + repeat_unit: 'week' | 'month' | 'year'; + retry_times: number; + status: 'active' | 'deleted'; + status_after_retry: 'unpaid' | 'cancelled'; + trial_days: number; + iva?: string | null; + default_charge_quantity?: any | null; + } + + export namespace Plan { + export interface CreateInput { + name: string; + amount: number; + repeat_every: number; + repeat_unit: 'week' | 'month' | 'year'; + retry_times?: number; + status_after_retry: 'unpaid' | 'cancelled'; + trial_days: number; + /** @default MXN */ + currency?: Currency; + } + + export interface UpdateInput { + name?: string; + trial_days?: number; + } + + export type ListQuery = BasicListQuery; + } + + export namespace Transfers { + export interface CreateInput { + customer_id: string; + amount: number; + description: string; + order_id?: string; + } + + export type ListQuery = BasicListQuery; + } + + export interface Subscription { + id: string; + creation_date: string; + cancel_at_period_end: boolean; + charge_date: string; + current_period_number: number; + period_end_date: string; + trial_end_date: string; + plan_id: string; + status: 'active' | 'trial' | 'past_due' | 'unpaid' | 'cancelled'; + customer_id: string; + card: Card; + default_charge_quantity?: any | null; + } + + export namespace Subscription { + export interface CreateInput { + plan_id: string; + trial_end_date?: string; + source_id?: string; + card?: Card; + card_id?: string; + device_session_id?: string; + } + + export interface UpdateInput { + cancel_at_period_end?: boolean; + trial_end_date?: string; + source_id?: string; + card?: Card; + } + + export type ListQuery = BasicListQuery; + } + + export interface BankAccount { + id: string; + rfc: string | null; + holder_name: string; + alias: string | null; + clabe: string; + bank_name: string; + bank_code: string; + creation_date: string; + } + + export namespace BankAccount { + export interface CreateInput { + holder_name: string; + alias?: string; + clabe: string; + } + + export type ListQuery = BasicListQuery; + } + + export interface Checkout { + id: string; + amount: number; + description: string; + order_id: string; + currency: Currency; + iva: string; + status: Checkout.Status; + checkout_link: string; + creation_date: string; + expiration_date: string | null; + customer: { + name: string; + email: string; + last_name: string; + phone_number: string; + external_id?: string | null; + }; + } + + export namespace Checkout { + export type Status = 'available' | 'other'; + + export interface CreateInput { + amount: number; + description: string; + order_id: string; + currency: Currency; + redirect_url: string; + expiration_date?: string; + send_email?: boolean; + customer: Checkout['customer']; + } + } + + export namespace SDK { + export interface Charges { + create(data: Charge.CreateInput): Promise; + list(query?: Charge.ListQuery): Promise; + get(transactionId: string): Promise; + capture(transactionId: string, data: Charge.CaptureInput): Promise; + refund(transactionId: string, data: Charge.RefundInput): Promise; + } + + export interface Payouts { + create(data: Payout.CreateInput): Promise; + list(query?: Payout.ListQuery): Promise; + get(transactionId: string): Promise; + } + + export interface Fees { + create(data: Fee.CreateInput): Promise; + list(query?: Fee.ListQuery): Promise; + } + + export interface Cards { + create(data: Card.CreateInput): Promise; + list(query?: Card.ListQuery): Promise; + get(cardId: string): Promise; + delete(cardId: string): Promise; + update(cardId: string, data: Card.UpdateInput): Promise; + } + + export interface Tokens { + create(data: Token.CreateInput): Promise; + get(tokenId: string): Promise; + } + + export interface Stores { + list(query?: Store.ListQuery): Promise; + } + + export interface Pse { + create(data: Charge.CreateInput): Promise; + } + + export interface Webhooks { + create(data: Webhook.CreateInput): Promise; + list(): Promise; + get(webhookId: string): Promise; + delete(webhookId: string): Promise; + } + + export interface Plans { + create(data: Plan.CreateInput): Promise; + list(query?: Plan.ListQuery): Promise; + get(planId: string): Promise; + update(planId: string, data: Plan.UpdateInput): Promise; + delete(planId: string): Promise; + } + + export interface Customers { + create(data: Customer.CreateInput): Promise; + list(query?: Customer.ListQuery): Promise; + get(customerId: string): Promise; + update(customerId: string, data: Customer.UpdateInput): Promise; + delete(customerId: string): Promise; + + charges: { + create(customerId: string, data: Charge.CreateInput): Promise; + list(customerId: string, query?: Charge.ListQuery): Promise; + get(customerId: string, transactionId: string): Promise; + capture(customerId: string, transactionId: string, data: Charge.CaptureInput): Promise; + refund(customerId: string, transactionId: string, data: Charge.RefundInput): Promise; + }; + + transfers: { + create(customerId: string, data: Transfers.CreateInput): Promise; + list(customerId: string, query?: Transfers.ListQuery): Promise; + get(customerId: string, transactionId: string): Promise; + }; + + payouts: { + create(customerId: string, data: Payout.CreateInput): Promise; + list(customerId: string, query?: Payout.ListQuery): Promise; + get(customerId: string, transactionId: string): Promise; + }; + + subscriptions: { + create(customerId: string, data: Subscription.CreateInput): Promise; + list(customerId: string, query?: Subscription.ListQuery): Promise; + get(customerId: string, subscriptionId: string): Promise; + update( + customerId: string, + subscriptionId: string, + data: Subscription.UpdateInput, + ): Promise; + delete(customerId: string, subscriptionId: string): Promise; + }; + + cards: { + create(customerId: string, data: Card.CreateInput): Promise; + list(customerId: string, query?: Card.ListQuery): Promise; + get(customerId: string, cardId: string): Promise; + delete(customerId: string, cardId: string): Promise; + update(customerId: string, cardId: string, data: Card.UpdateInput): Promise; + }; + + bankaccounts: { + create(customerId: string, data: BankAccount.CreateInput): Promise; + list(customerId: string, query?: BankAccount.ListQuery): Promise; + get(customerId: string, bankId: string): Promise; + delete(customerId: string, bankId: string): Promise; + }; + + pse: { + create(customerId: string, data: Charge.CreateInput): Promise; + }; + + checkouts: { + create(customerId: string, data: Checkout.CreateInput): Promise; + }; + } + + export interface Checkouts { + create(data: Checkout.CreateInput): Promise; + list(query?: BasicListQuery): Promise; + get(checkoutId: string): Promise; + update(checkoutId: string, status: Checkout.Status, data: any): Promise; + } + } +} diff --git a/test/bank-accounts.test.js b/test/bank-accounts.test.js deleted file mode 100644 index c818470..0000000 --- a/test/bank-accounts.test.js +++ /dev/null @@ -1,40 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(20000); -var enableLogging = true; -var customerId = ''; -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com" -}; - -describe('Get all bank_account with creation filter', function () { - this.timeout(0); - it('should return statusCode 200', function (done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit':1 - }; - openpay.customers.create(testCreateCustomer, function (error, body) { - openpay.customers.bankaccounts.list(body.id, searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code != 400'); - done(); - }); - }); - }); -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/cards.test.js b/test/cards.test.js deleted file mode 100644 index 6537ec0..0000000 --- a/test/cards.test.js +++ /dev/null @@ -1,34 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(30000); -var enableLogging = true; - -describe('Get cards list with creation[lte] filter', function () { - this.timeout(0); - it('should return cards list and 200 status code', function (done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit': 1 - }; - openpay.cards.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/charges_test.js b/test/charges_test.js deleted file mode 100644 index 0236118..0000000 --- a/test/charges_test.js +++ /dev/null @@ -1,35 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(30000); -var enableLogging = true; - -describe('Get charges list with amount[lte] filter', function () { - this.timeout(0); - it('should return charges list and 200 status code', function(done) { - var searchParams = { - 'amount[lte]': 10000, - 'creation[gte]': '2021-01-01', - 'limit':1 - }; - openpay.charges.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - -function printLog(code, body, error){ - if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if(code>=300){ - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/cards.test.colombia.js b/test/colombia/cards.test.colombia.js deleted file mode 100644 index eb199d0..0000000 --- a/test/colombia/cards.test.colombia.js +++ /dev/null @@ -1,211 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(30000); -var enableLogging = true; - -var testCard = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez", - "expiration_year": '28', - "expiration_month": "12", - "cvv2": "111" -}; - -var newToken = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "28", - "expiration_month": "12", - "cvv2": "110", - "address": { - "city": "Bogotá", - "country_code": "CO", - "postal_code": "110511", - "line1": "Av 5 de Febrero", - "line2": "Roble 207", - "line3": "col carrillo", - "state": "Bogota" - } -} -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com", - "requires_account": false -}; - -var cardCreated; -var tokenCreated; -var customerCreated; - -describe('Testing cards', function () { - this.timeout(0); - describe('Testing Merchant cards', function () { - describe('create card', function () { - it('should return statusCode 200||201', function (done) { - openpay.cards.create(testCard, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - describe('create card with token', function () { - it('should return statusCode 200||201', function (done) { - openpay.tokens.create(newToken, function (error, body, response) { - tokenCreated = body; - openpay.cards.create({ - token_id: tokenCreated.id, - device_session_id: tokenCreated.id - }, function (error, body, response) { - cardCreated = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - }); - - describe('get card', function () { - it('should return statusCode 200||201', function (done) { - openpay.cards.get(cardCreated.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('List cards', function () { - var searchParams = { - 'limit': 1 - }; - it('should return statusCode 200||201', function (done) { - openpay.cards.list(searchParams, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('update card', function () { - it('should return statusCode 200||201', function (done) { - openpay.cards.update(cardCreated.id, {holder_name: 'new holder_name'}, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('delete card', function () { - it('should return statusCode 200||201', function (done) { - openpay.cards.delete(cardCreated.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - - }); - - describe("Testing Customer cards", function () { - describe('create customer', function () { - it('', function (done) { - openpay.customers.create(testCreateCustomer, function (error, body, response) { - customerCreated = body; - done(); - }); - }); - - }); - - describe('create card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.cards.create(customerCreated.id, testCard, function (error, body, response) { - cardCreated = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('create card with token', function () { - it('should return statusCode 200||201', function (done) { - openpay.tokens.create(newToken, function (error, body, response) { - tokenCreated = body; - openpay.customers.cards.create(customerCreated.id, { - token_id: tokenCreated.id, - device_session_id: tokenCreated.id - }, function (error, body, response) { - cardCreated = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - }); - - describe('get card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.cards.get(customerCreated.id, cardCreated.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('List cards', function () { - var searchParams = { - 'limit': 1 - }; - it('should return statusCode 200||201', function (done) { - openpay.customers.cards.list(customerCreated.id, searchParams, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('update card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.cards.update(customerCreated.id, cardCreated.id, {holder_name: 'new holder_name'}, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('delete card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.cards.delete(customerCreated.id, cardCreated.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 204, true, ''); - done(); - }) - }); - }); - - describe('delete customer', function () { - it('delete customer', function (done) { - openpay.customers.delete(customerCreated.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 204, true, ''); - done(); - }); - }); - - }); - }) - -}) - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/charges_test.colombia.js b/test/colombia/charges_test.colombia.js deleted file mode 100644 index 0ded2e8..0000000 --- a/test/colombia/charges_test.colombia.js +++ /dev/null @@ -1,203 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(30000); -var enableLogging = true; - - -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com", - "requires_account": false -}; - -var newCard = { - "holder_name": "DinnersClub", - "card_number": 4111111111111111, - "cvv2": "651", - "expiration_month": 11, - "expiration_year": 28 -} - -var chargeCreated; -var cardCreated; -var testCard = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez", - "expiration_year": 28, - "expiration_month": "12", - "cvv2": "111" -}; - -var newCharge = { - "source_id": "kdx205scoizh93upqbte", - "method": "card", - "amount": 200, - "currency": "COP", - "iva": "10", - "description": "Cargo inicial a mi cuenta", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f", - "customer": { - "name": "Cliente Colombia", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.co" - } -} - -var testCreateCharge = { - "method": "card", - "source_id": "", - "amount": 20, - "description": "Test Charge", - "currency": "COP", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f" - -} - -describe('Testing charges', function () { - this.timeout(0); - describe('Merchant charges', function () { - describe('Create charge with existing card', function () { - it('should return statusCode 200||201', function (done) { - openpay.cards.create(newCard, function (error, body, response) { - cardCreated = body; - newCharge.source_id = body.id; - openpay.charges.create(newCharge, function (error, body, response) { - chargeCreated = body; - printLog(response.statusCode, body, error); - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, 'Status code == 200'); - done(); - }); - }); - - - }); - }); - describe('Refund merchant charge', function () { - it('should return statusCode 200', function (done) { - openpay.charges.create(newCharge, function (error, body, response) { - openpay.charges.refund(body.id, { - description: "testing refound", - amount: 200 - }, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - - }); - }); - describe('Create store charge', function () { - it('should return statusCode 200||201', function (done) { - newCharge.method = "store"; - newCharge.source_id = null; - openpay.charges.create(newCharge, function (error, body, response) { - chargeCreated = newCharge; - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) - }); - - describe('Get charge', function () { - it('should return statusCode 200||201', function (done) { - openpay.charges.get(chargeCreated.id, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - done(); - }) - }) - }); - - describe('Get All charges', function () { - it('should return statusCode 200||201', function (done) { - openpay.charges.list({}, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - done(); - }) - }) - }); - }); - - describe('customer charges', function () { - var customer; - var cardCreated; - var chargeCreated; - describe('Create customer charge with existing card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.create(testCreateCustomer, function (error, body, response) { - customer = body; - openpay.customers.cards.create(customer.id, testCard, function (error, body, response) { - testCreateCharge.source_id = body.id; - cardCreated = body; - openpay.customers.charges.create(customer.id, testCreateCharge, function (error, body, response) { - chargeCreated = body; - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }) - }); - - }); - }); - }); - describe('Refund customer charge', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.charges.refund(customer.id, chargeCreated.id, { - description: "testing refound", - amount: 20 - }, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) - }); - - describe('Create store charge', function () { - it('should return statusCode 200||201', function (done) { - newCharge.method = "store"; - newCharge.source_id = null; - newCharge.customer = null; - openpay.customers.charges.create(customer.id, newCharge, function (error, body, response) { - chargeCreated = body; - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) - }); - - describe('Get charge', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.charges.get(customer.id, chargeCreated.id, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - done(); - }) - }) - }); - describe('Get All charges', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.charges.list(customer.id, {}, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - done(); - }) - }) - }); - }) - - -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/clients_test.colombia.js b/test/colombia/clients_test.colombia.js deleted file mode 100644 index 97750c8..0000000 --- a/test/colombia/clients_test.colombia.js +++ /dev/null @@ -1,79 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(10000); -var enableLogging = true; - -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com", - "requires_account": false -}; - -describe('Customer testing', function () { - var customer; - describe('Create customer', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.create(testCreateCustomer, function (error, body, response) { - customer = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Update customer', function () { - it('should return statusCode 200||201', function (done) { - testCreateCustomer.name = "Client update"; - openpay.customers.update(customer.id, testCreateCustomer, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('Get customer', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.get(customer.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Customer List', function () { - it('should return statusCode 200||201', function (done) { - var searchParams = { - 'limit': 10 - }; - openpay.customers.list(searchParams, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Delete customer', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.delete(customer.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201 || response.statusCode === 204, true, ''); - done(); - }); - }); - }); - -}) - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/plans.test.colombia.js b/test/colombia/plans.test.colombia.js deleted file mode 100644 index c9548d6..0000000 --- a/test/colombia/plans.test.colombia.js +++ /dev/null @@ -1,82 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(20000); -var enableLogging = true; - -var newPlan = { - "amount": 150, - "status_after_retry": "cancelled", - "retry_times": 2, - "name": "Curso de ingles", - "repeat_unit": "month", - "trial_days": "30", - "repeat_every": "1" -} -describe('Plans testing', function () { - var plan; - describe('Create plan', function () { - it('should return statusCode 200||201', function (done) { - openpay.plans.create(newPlan, function (error, body, response) { - plan = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Update plan', function () { - it('should return statusCode 200||201', function (done) { - const updatePlan = {name:"plan updated"} - openpay.plans.update(plan.id, updatePlan, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('Get plan', function () { - it('should return statusCode 200||201', function (done) { - openpay.plans.get(plan.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Plan List', function () { - it('should return statusCode 200||201', function (done) { - var searchParams = { - 'limit': 10 - }; - openpay.plans.list(searchParams, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Delete plan', function () { - it('should return statusCode 200||201', function (done) { - openpay.plans.delete(plan.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201 || response.statusCode === 204, true, ''); - done(); - }); - }); - }); - -}) - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/pse_test.colombia.js b/test/colombia/pse_test.colombia.js deleted file mode 100644 index 15f047d..0000000 --- a/test/colombia/pse_test.colombia.js +++ /dev/null @@ -1,88 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(30000); -var enableLogging = true; - -var newPse = { - "method": "bank_account", - "amount": 10000, - "currency": "COP", - "description": "Cargo inicial a mi cuenta", - "iva": "1900", - "redirect_url": "/", - "customer": { - "name": "Cliente Colombia", - "last_name": "Vazquez Juarez", - "email": "juan.vazquez@empresa.co", - "phone_number": "4448936475", - "requires_account": false, - "customer_address": { - "department": "Medellín", - "city": "Antioquía", - "additional": "Avenida 7m bis #174-25 Apartamento 637" - } - } -} - -var newPseWithCustomer = { - "method": "bank_account", - "amount": 10000, - "currency": "COP", - "description": "Cargo inicial a mi cuenta", - "iva": "1900", - "redirect_url": "/" -} - -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com", - "requires_account": false -}; - - -describe('Testing pse', function () { - this.timeout(0); - - - describe('create pse with existing client', function () { - it('should return statusCode 200||201', function (done) { - openpay.pse.create(newPse, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('create pse with new client', function () { - var customerCreated; - it('create customer', function (done) { - openpay.customers.create(testCreateCustomer, function (error, body, response) { - customerCreated = body; - done(); - }); - }); - - it('should return statusCode 200||201', function (done) { - openpay.customers.pse.create(customerCreated.id, newPseWithCustomer, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - - }); -}) - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/stores_test.colombia.js b/test/colombia/stores_test.colombia.js deleted file mode 100644 index 12d42d7..0000000 --- a/test/colombia/stores_test.colombia.js +++ /dev/null @@ -1,37 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('', '', 'co', false); -openpay.setTimeout(30000); -var enableLogging = true; - -const location = { - "latitud": 4.65589142889691, - "longitud": -74.11335673251888, - "kilometers": 10, - "amount": 1 -} - -describe('List stores', function () { - it('List stores by location', function (done) { - openpay.stores.list(location, function (error, body, response) { - printLog(response.statusCode, body, error); - - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/subscriptions.test.colombia.js b/test/colombia/subscriptions.test.colombia.js deleted file mode 100644 index dc26ec1..0000000 --- a/test/colombia/subscriptions.test.colombia.js +++ /dev/null @@ -1,127 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(30000); -var enableLogging = true; - - -var newPlan = { - "amount": 150, - "status_after_retry": "cancelled", - "retry_times": 2, - "name": "Curso de ingles", - "repeat_unit": "month", - "trial_days": "30", - "repeat_every": "1" -} - -var subscription = { - "card": { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "20", - "expiration_month": "12", - "cvv2": "110", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f" - }, - "plan_id": "pbi4kb8hpb64x0uud2eb" -} - -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com", - "requires_account": false -}; - -describe('Plans testing', function () { - var plan; - var customer; - var subscription; - - describe('Create plan', function () { - it('should return statusCode 200||201', function (done) { - openpay.plans.create(newPlan, function (error, body, response) { - plan = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Create customer', function () { - it('create customer for test', function (done) { - openpay.customers.create(testCreateCustomer, function (error, body, response) { - customer = body; - done(); - }); - }); - }); - - - describe('Create subscription', function () { - subscription.plan_id = plan?.id; - it('should return statusCode 200||201', function (done) { - openpay.customers.subscriptions.create(customer.id, subscription, function (error, body, response) { - subscription = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Update subscription', function () { - it('should return statusCode 200||201', function (done) { - const updateSubscription = {trial_end_date: "2021-12-12"} - openpay.customers.subscriptions.update(subscription.id, updateSubscription, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }) - }); - }); - - describe('Get subscription', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.subscriptions.get(customer.id, subscription.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - - describe('subscription List', function () { - it('should return statusCode 200||201', function (done) { - var searchParams = { - 'limit': 10 - }; - openpay.customers.subscriptions.list(searchParams, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Cancell subscription', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.subscriptions.delete(subscription.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201 || response.statusCode === 204, true, ''); - done(); - }); - }); - - }); - -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/tokens_test.colombia.js b/test/colombia/tokens_test.colombia.js deleted file mode 100644 index d8b8389..0000000 --- a/test/colombia/tokens_test.colombia.js +++ /dev/null @@ -1,56 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(20000); -var enableLogging = true; - -const tokenNew = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "29", - "expiration_month": "12", - "cvv2": "110", - "address": { - "city": "Bogotá", - "country_code": "CO", - "postal_code": "110511", - "line1": "Av 5 de Febrero", - "line2": "Roble 207", - "line3": "col carrillo", - "state": "Bogota" - } -} -describe('Token testing', function () { - var token; - describe('Create Token', function () { - it('should return statusCode 200||201', function (done) { - openpay.tokens.create(tokenNew, function (error, body, response) { - token = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - describe('Get Token', function () { - it('should return statusCode 200||201', function (done) { - openpay.tokens.get(token.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); -}) - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/colombia/webhooks_test.colombia.js b/test/colombia/webhooks_test.colombia.js deleted file mode 100644 index 6f728b1..0000000 --- a/test/colombia/webhooks_test.colombia.js +++ /dev/null @@ -1,73 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('mwf7x79goz7afkdbuyqd', 'sk_94a89308b4d7469cbda762c4b392152a', 'co', false); -openpay.setTimeout(20000); -var enableLogging = true; - -const newWebhook = { - "url": "https://webhook.site/ab854ec2-2ac1-423b-9c0b-8502fd056cc9", - "user": "juanito", - "password": "passjuanito", - "event_types": [ - "charge.refunded", - "charge.failed", - "charge.cancelled", - "charge.created", - "chargeback.accepted" - ] -} -describe('Webhook testing', function () { - var webhook; - describe('Create webhook', function () { - it('should return statusCode 200||201', function (done) { - openpay.webhooks.create(newWebhook, function (error, body, response) { - webhook = body; - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - - describe('Get webhook', function () { - it('should return statusCode 200||201', function (done) { - openpay.webhooks.get(webhook.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Webhook List', function () { - it('should return statusCode 200||201', function (done) { - openpay.webhooks.list(function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201, true, ''); - done(); - }); - }); - }); - - describe('Delete webhook', function () { - it('should return statusCode 200||201', function (done) { - openpay.webhooks.delete(webhook.id, function (error, body, response) { - assert.equal(response.statusCode === 200 || response.statusCode === 201 || response.statusCode === 204, true, ''); - done(); - }); - }); - }); - -}) - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/customers_test.js b/test/customers_test.js deleted file mode 100644 index 7154196..0000000 --- a/test/customers_test.js +++ /dev/null @@ -1,34 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('gdntnaxvkcdviesgaxem', 'sk_b97e606487d34b44ab66e03d5bd14747'); -openpay.setTimeout(10000); -var enableLogging = true; - -describe('Get customers list with creation[gte] filter', function() { - this.timeout(0); - it('should return customer list and 200 status code', function(done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit':1 - }; - openpay.groups.customers.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - -function printLog(code, body, error){ - if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if(code>=300){ - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/fees.test.js b/test/fees.test.js deleted file mode 100644 index 8202aef..0000000 --- a/test/fees.test.js +++ /dev/null @@ -1,34 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(2000); -var enableLogging = true; - -describe('Get fees list with creation[lte] filter', function() { - this.timeout(0); - it('should return fees list and 200 status code', function(done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit':1 - }; - openpay.fees.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - -function printLog(code, body, error){ - if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if(code>=300){ - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/group_test.js b/test/group_test.js deleted file mode 100644 index 0aead65..0000000 --- a/test/group_test.js +++ /dev/null @@ -1,361 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); -// var request = require('request'); -var urllib = require('urllib'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('gdntnaxvkcdviesgaxem', 'sk_b97e606487d34b44ab66e03d5bd14747'); -openpay.setTimeout(10000); - -var enableLogging = true; -var testCreateCharges = true; - -// Defining a valid expiration year for cards, adding 5 years to the current one -var validExpirationYear = (new Date().getFullYear() + 5).toString().substr(2, 2); - -describe('Testing group API', function(){ - this.timeout(0); - - var testCreateCustomer = { - "name":"Juan", - "email":"juan@nonexistantdomain.com", - "requires_account":false - }; - var testUpdateCustomer = { - "name":"Juan", - "email":"juan@nonexistantdomain.com", - "phone_number":"123456789" - }; - - var newlyCreatedCustomerId = ''; - describe('Testing customers', function(){ - describe('Create customer', function(){ - it('should return statusCode 200||201', function (done){ - openpay.groups.customers.create(testCreateCustomer, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedCustomerId = body.id; - done(); - }); - }); - }); - describe('Get all customers without constraints', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.list({}, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get customer', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.get(newlyCreatedCustomerId, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Update customer', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.update(newlyCreatedCustomerId, testUpdateCustomer, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get all customers with constraints', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.list({'creation':'2013-12-10'}, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - var testCard ={ - "card_number":"4111111111111111", - "holder_name":"Juan Perez", - "expiration_year": validExpirationYear, - "expiration_month":"12", - "cvv2":"111" - }; - var newlyCreatedCardId = ''; - var newlyCreatedCustomerCardId = ''; - - describe('Testing cards API', function(){ - - describe('Add customer card', function(){ - it('should return statusCode 200||201', function (done){ - openpay.groups.customers.cards.create(newlyCreatedCustomerId, testCard, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedCustomerCardId = body.id; - newlyCreatedCardId = body.id; - done(); - }); - }); - }); - describe('Get all customer cards without constraints', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.cards.list(newlyCreatedCustomerId, {}, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get customer card', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.cards.get(newlyCreatedCustomerId, newlyCreatedCustomerCardId, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - //var testGetCharge = 'tlogyahn68d2qurjqhqt'; - var testExistingCardCharge = { - "source_id" : '', - "method" : "card", - "amount" : 50, - "description" : "Test existing card charge" - }; - var testCreateCharge = { - "method": "card", - "card": { - "card_number": "4111111111111111", - "holder_name": "Aa Bb", - "expiration_year": validExpirationYear, - "expiration_month": "12", - "cvv2": "110", - }, - "amount" : 20, - "description" : "Test Charge" - }; - var testCreateChargeWithoutCapture = { - "method": "card", - "card": { - "card_number": "4111111111111111", - "holder_name": "Aa Bb", - "expiration_year": validExpirationYear, - "expiration_month": "12", - "cvv2": "110", - }, - "amount" : 20, - "description" : "Test Charge", - "capture" : false - }; - var testCreateBankAccountCharge = { - "method" : "bank_account", - "amount" : 50, - "description" : "Test bank account charge" - }; - var testCreateStoreCharge = { - "method" : "store", - "amount" : 60.01, - "description" : "Test store charge" - }; - var testRefundData = {"description":"Testing refund"}; - - var merchantId = 'm1qp3av1ymcfufkuuoah'; - - describe('Testing charges', function(){ - if(testCreateCharges){ - describe('Create charge with existing card', function(){ - it('should return statusCode 200||201', function (done){ - testExistingCardCharge.source_id = newlyCreatedCardId; - //console.log(testExistingCardCharge); - openpay.groups.charges.create(merchantId, testExistingCardCharge, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - var newlyCreatedTransactionId = ''; - describe('Create charge with new card', function(){ - it('should return statusCode 200||201', function (done){ - openpay.groups.charges.create(merchantId, testCreateCharge, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Refund merchant charge', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.charges.refund(merchantId, newlyCreatedTransactionId, testRefundData, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Create charge without capture', function(){ - it('should return statusCode 200||201', function (done){ - openpay.groups.charges.create(merchantId, testCreateChargeWithoutCapture, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Capture charge', function(){ - it('should return statusCode 200||201', function (done){ - openpay.groups.charges.capture(merchantId, newlyCreatedTransactionId, null, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - } - - describe('Create customer charge with existing card', function(){ - it('should return statusCode 200||201', function (done){ - testExistingCardCharge.source_id = newlyCreatedCustomerCardId; //fails if use merchant card - //console.log(testExistingCardCharge); - openpay.groups.customers.charges.create(merchantId, newlyCreatedCustomerId, testExistingCardCharge, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - var newlyCreatedCustomerTransactionId = ''; - describe('Create customer charge with new card', function(){ - it('should return statusCode 200||201', function (done){ - openpay.groups.customers.charges.create(merchantId, newlyCreatedCustomerId, testCreateCharge, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedCustomerTransactionId = body.id; - done(); - }); - }); - }); - }); - describe('Testing subscriptions', function(){ - newlyCreatedPlanId = 'pdusfyuqsdze2sejn7qy'; - var newlyCreatedSubscriptionId = ''; - describe('Create subscription', function(){ - it('should return statusCode 200||201', function (done){ - var testSubscription = {"plan_id": newlyCreatedPlanId, "card_id": newlyCreatedCustomerCardId, "trial_days": "30"}; - openpay.groups.customers.subscriptions.create(merchantId, newlyCreatedCustomerId, testSubscription, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedSubscriptionId = body.id; - done(); - }); - }); - }); - describe('Get all subscriptions without constraints', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.subscriptions.list(merchantId, newlyCreatedCustomerId, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - describe('Get subscription', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.subscriptions.get(merchantId, newlyCreatedCustomerId, newlyCreatedSubscriptionId, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Update subscription', function(){ - it('should return statusCode 200', function (done){ - openpay.groups.customers.subscriptions.update(merchantId, newlyCreatedCustomerId, newlyCreatedSubscriptionId, {"trial_end_date": "2022-02-11"}, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Delete subscription', function(){ - it('should return statusCode 204', function (done){ - openpay.groups.customers.subscriptions.delete(merchantId, newlyCreatedCustomerId, newlyCreatedSubscriptionId, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - }); - describe('Create and delete customer', function(){ - it('should return statusCode 200||201', function (done){ - openpay.groups.customers.create(testCreateCustomer, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedCustomerId = body.id; - done(); - }); - }); - - it('should return statusCode 200||201', function (done){ - openpay.groups.customers.cards.create(newlyCreatedCustomerId, testCard, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedCustomerCardId = body.id; - done(); - }); - }); - - it('should return statusCode 204', function (done){ - openpay.groups.customers.cards.delete(newlyCreatedCustomerId, newlyCreatedCustomerCardId, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - describe('Delete customer', function(){ - it('should return statusCode 204', function (done){ - openpay.groups.customers.delete(newlyCreatedCustomerId, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - -}); - - -function printLog(code, body, error){ - if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if(code>=300){ - console.log(' '); - console.log(error); - console.log(' '); - } -} - -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); - }); -} diff --git a/test/payouts_test.js b/test/payouts_test.js deleted file mode 100644 index 35a8055..0000000 --- a/test/payouts_test.js +++ /dev/null @@ -1,35 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(20000); -var enableLogging = true; - -describe('Get all payouts with filters creation and amount', function(){ - this.timeout(0); - it('should return statusCode 200', function (done){ - var searchParams = { - 'amount[lte]': 1000, - 'creation[gte]': '2020-01-01', - 'limit':1 - }; - openpay.payouts.list(searchParams, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); -}); - -function printLog(code, body, error){ - if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if(code>=300){ - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/peru/cards.pe.test.js b/test/peru/cards.pe.test.js deleted file mode 100644 index 5c1e9a4..0000000 --- a/test/peru/cards.pe.test.js +++ /dev/null @@ -1,166 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m3cji4ughukthjcsglv0', 'sk_f934dfe51645483e82106301d985a4f6', 'pe',false); -openpay.setTimeout(30000); -var enableLogging = true; -const card = { - "holder_name": "DinnersClub", - "card_number": "4111111111111111", - "cvv2": "651", - "expiration_month": "09", - "expiration_year": "25" -}; -const customer = { - "name": "Marco", - "last_name": "Morales Perez", - "email": "marco.mp@qrsof.com", - "phone_number": "5744484951", - "address": { - "country_code": "PE", - "postal_code": "12345", - "city": "Lima", - "state": "Lima", - "line1": "Perú", - "line2": "Perú", - "line3": "Perú" - } -}; - -var cardId = ''; - -describe('Get cards list with creation[lte] filter', function () { - this.timeout(0); - it('should return cards list and 200 status code', function (done) { - var searchParams = { - 'creation[lte]': '2021-01-01', - 'limit': 1 - }; - openpay.cards.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - - -describe('Create cards', function () { - this.timeout(0); - describe('create customer card', function () { - it('should return card 201 status code', function (done) { - openpay.customers.create(customer, function (error, body, response) { - const customerId = response.data.id; - openpay.customers.cards.create(customerId, card, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 201, ''); - done(); - }); - }); - }) - - }); - - describe('create merchant card', function () { - it('should return card 201 status code', function (done) { - openpay.cards.create(card, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 201, ''); - done(); - }); - }); - - }); - -}); - - -describe('get cards', function () { - - describe('get card by id', function () { - it("should return card and 200 status code", function () { - openpay.cards.create(card, function (error, body, response) { - const cardId = response.data.id; - openpay.cards.get(cardId, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - assert.equal(response.data.id, cardId, ''); - done(); - }); - }); - }); - }); - - describe('get customer cards', function () { - it('should customer card list', function () { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit': 1 - }; - openpay.customers.list(searchParams, function (error, body, response) { - const customer = response.data[0]; - console.log('response', response.data[0]); - openpay.customers.cards.list(customer.id, {}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - assert(response.data.size >= 1); - done(); - }); - }); - }); - }); - - describe('get customer card id', function () { - it("should card response and 200 status code", function () { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit': 1 - }; - openpay.customers.list(searchParams, function (error, body, response) { - const customer = response.data[0]; - openpay.customers.cards.create(customer.id, card, function (error, body, response) { - const cardCreated = response.data; - openpay.customers.cards.get(customer.id, cardCreated.id, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - assert.equal(cardCreated.id, response.data.id, ''); - done(); - }); - }); - }); - }); - }); - -}); - - -describe('delete card', function () { - it('create customer', function (done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit': 1 - }; - openpay.customers.list(searchParams, function (error, body, response) { - const customerGet = response.data[0]; - openpay.customers.cards.create(customerGet.id, card, function (error, body, response) { - const cardCreated = response.data; - openpay.customers.cards.delete(customerGet.id, cardCreated.id, function (error, body, response) { - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - }); -}); - - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/peru/charges.pe.test.js b/test/peru/charges.pe.test.js deleted file mode 100644 index 29bed50..0000000 --- a/test/peru/charges.pe.test.js +++ /dev/null @@ -1,208 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m3cji4ughukthjcsglv0', 'sk_f934dfe51645483e82106301d985a4f6', 'pe',false); -openpay.setTimeout(30000); -var enableLogging = true; - -const merchantCharge = { - "source_id": "kdx205scoizh93upqbte", - "method": "card", - "amount": 716, - "currency": "PEN", - "description": "Cargo inicial a mi cuenta", - "order_id": "oid-65584", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f", - "customer": { - "name": "Cliente Perú", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.pe" - } -} - -const customerCharge = { - "source_id": "kdx205scoizh93upqbte", - "method": "card", - "amount": 716, - "currency": "PEN", - "description": "Cargo inicial a mi cuenta", - "order_id": "oid-65584", - "device_session_id": "kR1MiQhz2otdIuUlQkbEyitIqVMiI16f" -} - -const token = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "21", - "expiration_month": "12", - "cvv2": "110", - "address": { - "city": "Lima", - "country_code": "PE", - "postal_code": "110511", - "line1": "Av 5 de Febrero", - "line2": "Roble 207", - "line3": "col carrillo", - "state": "Lima" - } -} - -describe('Get charges list', function () { - this.timeout(0); - describe('Get charges list with creation[gte] filter', function () { - it('should return charges list and 200 status code', function (done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit': 1 - }; - openpay.charges.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get charges list with no filter', function () { - it('should return charges list and 200 status code', function (done) { - openpay.charges.list({}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get customer charges list with creation[gte] filter', function () { - it('should return charges list and 200 status code', function (done) { - openpay.customers.list({}, function (error, body, response) { - const customer = response.data[0]; - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit': 1 - }; - openpay.customers.charges.list(customer.id, searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) - }); - }); - describe('Get customer charges list with no filter', function () { - it('should return charges list and 200 status code', function (done) { - openpay.customers.list({}, function (error, body, response) { - const customer = response.data[0]; - openpay.customers.charges.list(customer.id, {}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) - }); - }); -}); - -describe('Create charges', function () { - this.timeout(0); - describe('create customer charge', function () { - it('should return card 200 status code', function (done) { - openpay.tokens.create(token, function (error, body, response) { - const token = response.data; - customerCharge.source_id = token.id; - customerCharge.order_id = 'oid-65784'; - openpay.customers.list({}, function(error, body, response) { - const customer = response.data[0]; - openpay.customers.charges.create(customer.id, customerCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - }); - - describe('create merchant charge', function () { - it('should return charge 200 status code', function (done) { - openpay.tokens.create(token, function (error, body, response) { - const token = response.data; - merchantCharge.source_id = token.id; - openpay.charges.create(merchantCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - describe('create merchant store charge', function () { - it('should return charge 200 status code', function (done) { - merchantCharge.source_id = ''; - merchantCharge.order_id = 'oid-63384'; - merchantCharge.method = 'store'; - openpay.charges.create(merchantCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); -}); - -describe('Get charges', function () { - - describe('Get charge by id', function () { - it("should return card and 200 status code", function () { - openpay.tokens.create(token, function (error, body, response) { - const token = response.data; - merchantCharge.source_id = token.id; - merchantCharge.order_id = 'oid-65539'; - openpay.charges.create(merchantCharge, function (error, body, response) { - const charge = response.data; - openpay.charges.get(charge.id, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - assert.equal(response.data.id, charge.id, ''); - done(); - }); - }); - }); - }); - }); - - describe('Get customer charge by id', function () { - it('should customer card list', function () { - openpay.tokens.create(token, function (error, body, response) { - const token = response.data; - customerCharge.source_id = token.id; - customerCharge.order_id = 'oid-25784' - openpay.customers.list({}, function(error, body, response) { - const customer = response.data[0]; - openpay.customers.charges.create(customer.id, customerCharge, function (error, body, response) { - const charge = response.data; - openpay.customers.charges.get(customer.id, charge.id, function(error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - assert.equal(response.data.id, charge.id, ''); - done(); - }); - }); - }); - }); - }); - }); -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/peru/checkouts.pe.test.js b/test/peru/checkouts.pe.test.js deleted file mode 100644 index 8eff18c..0000000 --- a/test/peru/checkouts.pe.test.js +++ /dev/null @@ -1,142 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m3cji4ughukthjcsglv0', 'sk_f934dfe51645483e82106301d985a4f6', 'pe',false); -openpay.setTimeout(30000); -var enableLogging = true; - -const customer = { - "name": "Marco", - "last_name": "Morales Perez", - "email": "marco.mp@qrsof.com", - "phone_number": "5744484951", - "address": { - "country_code": "PE", - "postal_code": "12345", - "city": "Lima", - "state": "Lima", - "line1": "Perú", - "line2": "Perú", - "line3": "Perú" - } -}; - -const customerCheckout = { - "amount": 250, - "currency": "PEN", - "description": "Cargo cobro con link cliente", - "redirect_url": "https://misitioempresa.pe", - "order_id": "oid-87491", // Cambiar por un OID nuevo - "send_email": "true" -} - -const merchantCheckout = { - "amount": 250, - "currency": "PEN", - "description": "Cargo cobro con link", - "redirect_url": "https://misitioempresa.pe", - "order_id": "oid-66393", // Cambiar por un OID nuevo - "expiration_date": "2021-08-31 12:50", - "send_email": "true", - "customer": { - "name": "Cliente Perú", - "last_name": "Vazquez Juarez", - "phone_number": "4448936475", - "email": "juan.vazquez@empresa.pe" - } -} - -describe('List checkouts', function () { - this.timeout(0); - describe('List merchant checkouts', function () { - it('should return checkout list and 200 status code', function (done) { - const searchParams = { - "limit": 2, - "startDate": "20211001", - "endDate": "20211011" - }; - openpay.checkouts.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); -}) - - -describe('Create checkouts', function () { - this.timeout(0); - describe('create customer checkout', function () { - it('should return checkout 200 status code', function (done) { - openpay.customers.create(customer, function (error, body, response) { - const customerId = response.data.id; - openpay.customers.checkouts.create(customerId, customerCheckout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }) - }); - - describe('create merchant checkout', function () { - it('should return checkout 200 status code', function (done) { - openpay.checkouts.create(merchantCheckout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); -}); - - -describe('Get checkouts', function () { - this.timeout(0); - describe('get checkout by id', function () { - it("should return checkout and 200 status code", function () { - openpay.checkouts.create(merchantCheckout, function (error, body, response) { - const checkoutId = response.data.id; - openpay.checkouts.get(checkoutId, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - assert.equal(response.data.id, checkoutId, ''); - done(); - }); - }); - }); - }); -}); - -describe('Update checkouts', function () { - this.timeout(0); - it('should return checkouts status 200', function () { - openpay.checkouts.create(merchantCheckout, function (error, body, reponse) { - const checkout = reponse.data; - const expirationDate = "2021-10-26 13:43" - const status = "available"; - const data = {"expiration_date": expirationDate} - - openpay.checkouts.update(checkout.id, status, data, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - assert.equal(response.data.id, checkout.id, ''); - assert.equal(response.data.status, status, ''); - assert.equal(response.data.expiration_date, expirationDate.replace(' ','T') + ':00.000-050', ''); - }); - }); - }); -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/peru/customers.pe.test.js b/test/peru/customers.pe.test.js deleted file mode 100644 index fb950e5..0000000 --- a/test/peru/customers.pe.test.js +++ /dev/null @@ -1,117 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m3cji4ughukthjcsglv0', 'sk_f934dfe51645483e82106301d985a4f6', 'pe',false); -openpay.setTimeout(10000); -var enableLogging = true; -const customer = { - "name": "Marco", - "last_name": "Morales Perez", - "email": "marco.mp@qrsof.com", - "phone_number": "5744484951", - "address": { - "country_code": "PE", - "postal_code": "12345", - "city": "Lima", - "state": "Lima", - "line1": "Perú", - "line2": "Perú", - "line3": "Perú" - } -}; -describe('Get customers list with creation[gte] filter', function () { - this.timeout(0); - it('should return customer list and 200 status code', function (done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit': 1 - }; - openpay.customers.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - -describe('Create customer ', function () { - this.timeout(0); - it('should return customer 201 status code', function (done) { - openpay.customers.create(customer, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 201, ''); - done(); - }); - }) -}); - - -describe('Actualizar customer ', function () { - this.timeout(0); - const customerUpdateRequest = { - "name": "Marco Update", - "last_name": "Morales Perez", - "email": "marco.mp.update@qrsof.com", - "phone_number": "5744484951", - "address": { - "country_code": "PE", - "postal_code": "12345", - "city": "Lima", - "state": "Lima", - "line1": "Perú", - "line2": "Perú", - "line3": "Perú" - } - } - it('should return customer 200 status code', function (done) { - openpay.customers.create(customer, function (error, body, response) { - console.log('response: ', response); - openpay.customers.update(response.data.id, customerUpdateRequest, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }) -}); - - -describe("get client", function () { - it("should return a customer", function (done) { - openpay.customers.create(customer, function (error, body, response) { - const customerId = response.data.id; - openpay.customers.get(customerId, function (error, body, respose) { - assert.equal(respose.data.id, customerId, ''); - assert.equal(respose.data.name, 'Marco', ''); - done() - }); - }); - }); - -}); - - -describe("delete customer", function () { - it("should return a 200", function (done) { - openpay.customers.create(customer, function (error, body, response) { - const customerId = response.data.id; - openpay.customers.delete(customerId, function (error, body, respose) { - assert.equal(respose.statusCode, 204, ''); - done() - }); - }); - }); -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/peru/tokens.pe.test.js b/test/peru/tokens.pe.test.js deleted file mode 100644 index 54a146b..0000000 --- a/test/peru/tokens.pe.test.js +++ /dev/null @@ -1,64 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m3cji4ughukthjcsglv0', 'sk_f934dfe51645483e82106301d985a4f6', 'pe',false); -openpay.setTimeout(30000); -var enableLogging = true; - -const token = { - "card_number": "4111111111111111", - "holder_name": "Juan Perez Ramirez", - "expiration_year": "21", - "expiration_month": "12", - "cvv2": "110", - "address": { - "city": "Lima", - "country_code": "PE", - "postal_code": "110511", - "line1": "Av 5 de Febrero", - "line2": "Roble 207", - "line3": "col carrillo", - "state": "Lima" - } -} - -describe('Create Token', function () { - this.timeout(0); - it('should return token 201 status code', function (done) { - openpay.tokens.create(token, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 201, ''); - done(); - }); - }); -}); - -describe('Get Token', function () { - - describe('Get Token by ID', function () { - it("should return token and 200 status code", function () { - openpay.tokens.create(token, function (error, body, response) { - const tokenId = response.data.id; - openpay.tokens.get(tokenId, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - assert.equal(response.data.id, tokenId, ''); - done(); - }); - }); - }); - }); -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - console.log(body) - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/peru/webhooks.pe.test.js b/test/peru/webhooks.pe.test.js deleted file mode 100644 index 3cc658a..0000000 --- a/test/peru/webhooks.pe.test.js +++ /dev/null @@ -1,79 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m3cji4ughukthjcsglv0', 'sk_f934dfe51645483e82106301d985a4f6', 'pe',false); -openpay.setTimeout(30000); -var enableLogging = true; -const webhook = { - "url": "https://webhook.site/dffe8335-b0bb-493f-a38d-3e61b711bd6a", // Cambiar por URL válida - "user": "juanito", - "password": "passjuanito", - "event_types": [ - "charge.failed", - "charge.cancelled", - "charge.created", - "chargeback.accepted" - ] -} - -describe('Create Webhooks', function () { - this.timeout(0); - it('should return webhook 201 status code', function (done) { - openpay.webhooks.create(webhook, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 201, ''); - done(); - }); - }); -}); - -describe('Get webhooks list', function () { - this.timeout(0); - it('should return webhooks list and 200 status code', function (done) { - openpay.webhooks.list(function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - - -describe('Get wehbook by ID', function () { - it("should return card and 200 status code", function () { - openpay.webhooks.create(webhook, function (error, body, response) { - const webhookId = response.data.id; - openpay.webhooks.get(webhookId, function (error, body, response) { - assert.equal(response.statusCode, 200, ''); - assert.equal(response.data.id, webhookId, ''); - done(); - }); - }); - }); -}); - -describe('Eliminar Webhook', function () { - it("should return card and 204 status code", function () { - openpay.webhooks.list(function (error, body, response) { - const webhookGet = response.data[0]; - openpay.webhooks.delete(webhookGet.id, function (error, body, response) { - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); -}); - - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/plans.test.js b/test/plans.test.js deleted file mode 100644 index f02e9b6..0000000 --- a/test/plans.test.js +++ /dev/null @@ -1,34 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(20000); -var enableLogging = true; - -describe('Get plans list with creation[lte] filter', function() { - this.timeout(0); - it('should return plans list and 200 status code', function(done){ - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit':1 - }; - openpay.plans.list(searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }) -}) - -function printLog(code, body, error){ - if(enableLogging){ - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if(code>=300){ - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/subscriptions.test.js b/test/subscriptions.test.js deleted file mode 100644 index e4b093d..0000000 --- a/test/subscriptions.test.js +++ /dev/null @@ -1,39 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(30000); -var enableLogging = true; -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com" -}; - -describe('Get all subscriptions with creation filter', function () { - this.timeout(0); - it('should return statusCode 200', function (done) { - var searchParams = { - 'creation[gte]': '2021-01-01', - 'limit':1 - }; - openpay.customers.create(testCreateCustomer, function (error, body) { - openpay.customers.subscriptions.list(body.id, searchParams, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code != 400'); - done(); - }); - }); - }); -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/test/test.js b/test/test.js deleted file mode 100644 index 973dca6..0000000 --- a/test/test.js +++ /dev/null @@ -1,927 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); -var urllib = require('urllib'); - -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(10000); - -var enableLogging = true; -var testCreateCharges = true; -var testCreatePayouts = false; -var testBankAccountId = 'bmopptj5st1hx8ddouha'; - -// IMPORTANT NOTE ABOUT WEBHOOKS -// !! Future contributors, please read: !! -// -// The webhook url requires opening a new requestbin in https://opey-requestbin.herokuapp.com -// and entering the id as a parameter further down; otherwise the webhook check will fail. -// The current one will remain open for 60 days, according to the docs (starting Feb 3, 2021) -// If you test again after 60 days have passed, please update the url and the date -// in both comments, here and down below. -// (There should be a better way to do this) - -// Defining a valid expiration year for cards, adding 5 years to the current one -var validExpirationYear = (new Date().getFullYear() + 5).toString().substr(2, 2); - -describe('Testing whole API', function(){ - this.timeout(0); - - var testCreateCustomer = { - "name":"Juan", - "email":"juan@nonexistantdomain.com", - // The customer requires an account to charge fees and receive transfers - "requires_account": true - }; - var testUpdateCustomer = { - "name":"Juan", - "email":"juan@nonexistantdomain.com", - "phone_number":"123456789" - }; - - describe('Testing Webhook', function() { - var webhook; - var webhook_params = { - // Update the requestbin url here. Last change: Feb 3, 2021 - 'url' : 'https://opey-requestbin.herokuapp.com/12i2q011', - 'event_types' : [ - 'charge.refunded', - 'charge.failed', - 'charge.cancelled', - 'charge.created', - 'chargeback.accepted' - ] - }; - - describe('Create Webhook', function() { - it('Should return statusCode 201', function(done) { - openpay.webhooks.create(webhook_params, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 201, ''); - webhook = body; - done(); - }); - }); - }); - - describe('Get webhook by id and status verified', function () { - it('Should return status code 200', function (done) { - openpay.webhooks.get(webhook.id, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - assert.equal(body.status, 'verified', ''); - done(); - }); - }); - }); - /* - describe('Verify webhook code', function() { - it('Should return statusCode 204', function(done) { - console.info(webhook.url + '?inspect'); - getVerificationCode(webhook.url + '?inspect', function(error, verification_code) { - console.info('webhook.id = ' + webhook.id); - console.info('verification_code = ' + verification_code); - openpay.webhooks.verify(webhook.id, verification_code, function(error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }) - }); - }); - */ - - - describe('Get webhook by id and status verified', function () { - it('Should return status code 200', function (done) { - openpay.webhooks.get(webhook.id, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - assert.equal(body.status, 'verified', ''); - done(); - }); - }); - }); - - describe('List webhooks by id merchant', function () { - it('Should return status code 200', function (done) { - openpay.webhooks.list(function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - assert.equal(body.length, 1, ''); - done(); - }); - }); - }); - - describe('Delete webhook by id', function () { - it('Should return statusCode 204', function (done) { - openpay.webhooks.delete(webhook.id, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - - }); - - - describe('Testing merchant', function () { - describe('Get merchant', function () { - it('should return statusCode 200', function (done) { - openpay.merchant.get(function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - var newlyCreatedCustomerId = ''; - describe('Testing customers', function () { - describe('Create customer', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.create(testCreateCustomer, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedCustomerId = body.id; - done(); - }); - }); - }); - describe('Get all customers without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.customers.list({}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get customer', function () { - it('should return statusCode 200', function (done) { - openpay.customers.get(newlyCreatedCustomerId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Update customer', function () { - it('should return statusCode 200', function (done) { - openpay.customers.update(newlyCreatedCustomerId, testUpdateCustomer, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get all customers with constraints', function () { - it('should return statusCode 200', function (done) { - openpay.customers.list({'creation': '2013-12-10'}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - - var testCard ={ - "card_number":"4111111111111111", - "holder_name":"Juan Perez", - "expiration_year": validExpirationYear, - "expiration_month":"12", - "cvv2":"111" - }; - var newlyCreatedCardId = ''; - var newlyCreatedCustomerCardId = ''; - - describe('Testing cards API', function () { - describe('Add card', function () { - it('should return statusCode 200||201', function (done) { - openpay.cards.create(testCard, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedCardId = body.id; - done(); - }); - }); - }); - describe('Get all cards without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.cards.list({}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get card', function () { - it('should return statusCode 200', function (done) { - openpay.cards.get(newlyCreatedCardId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - - describe('Add customer card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.cards.create(newlyCreatedCustomerId, testCard, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedCustomerCardId = body.id; - done(); - }); - }); - }); - describe('Get all customer cards without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.customers.cards.list(newlyCreatedCustomerId, {}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get customer card', function () { - it('should return statusCode 200', function (done) { - openpay.customers.cards.get(newlyCreatedCustomerId, newlyCreatedCustomerCardId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - - var testBankAccount = { - "clabe": "021180000118359717", - "holder_name": "Juan H" - }; - var newlyCreatedBankAccountId = ''; - - describe('Testing bankaccounts', function () { - describe('Create bankaccount', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.bankaccounts.create(newlyCreatedCustomerId, testBankAccount, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, ''); - newlyCreatedBankAccountId = body.id; - done(); - }); - }); - }); - describe('Get all bank accounts without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.customers.bankaccounts.list(newlyCreatedCustomerId, {}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get bankaccount', function () { - it('should return statusCode 200', function (done) { - openpay.customers.bankaccounts.get(newlyCreatedCustomerId, newlyCreatedBankAccountId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - - //var testGetCharge = 'tlogyahn68d2qurjqhqt'; - var testExistingCardCharge = { - "source_id" : '', - "method" : "card", - "amount" : 50, - "description" : "Test existing card charge" - }; - var testCreateCharge = { - "method": "card", - "card": { - "card_number": "4111111111111111", - "holder_name": "Aa Bb", - "expiration_year": validExpirationYear, - "expiration_month": "12", - "cvv2": "110", - }, - "amount" : 20, - "description" : "Test Charge" - }; - var testCreateChargeWithoutCapture = { - "method": "card", - "card": { - "card_number": "4111111111111111", - "holder_name": "Aa Bb", - "expiration_year": validExpirationYear, - "expiration_month": "12", - "cvv2": "110", - }, - "amount" : 20, - "description" : "Test Charge", - "capture" : false - }; - var testCreateBankAccountCharge = { - "method" : "bank_account", - "amount" : 50, - "description" : "Test bank account charge" - }; - var testCreateStoreCharge = { - "method" : "store", - "amount" : 60.01, - "description" : "Test store charge" - }; - var testRefundData = {"description":"Testing refund"}; - - describe('Testing charges', function () { - describe('Get all charges without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.charges.list({}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - if (testCreateCharges) { - describe('Create charge with existing card', function () { - it('should return statusCode 200||201', function (done) { - testExistingCardCharge.source_id = newlyCreatedCardId; - //console.log(testExistingCardCharge); - openpay.charges.create(testExistingCardCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - var newlyCreatedTransactionId = ''; - describe('Create charge with new card', function () { - it('should return statusCode 200||201', function (done) { - openpay.charges.create(testCreateCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Get charge', function () { - it('should return statusCode 200', function (done) { - openpay.charges.get(newlyCreatedTransactionId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Refund merchant charge', function () { - it('should return statusCode 200', function (done) { - openpay.charges.refund(newlyCreatedTransactionId, testRefundData, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Create charge without capture', function () { - it('should return statusCode 200||201', function (done) { - openpay.charges.create(testCreateChargeWithoutCapture, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Capture charge', function () { - it('should return statusCode 200||201', function (done) { - openpay.charges.capture(newlyCreatedTransactionId, null, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - describe('Create charge with new bank account', function () { - it('should return statusCode 200||201', function (done) { - openpay.charges.create(testCreateBankAccountCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Create charge on Store', function () { - it('should return statusCode 200', function (done) { - openpay.charges.create(testCreateStoreCharge, function (error, body, response) { - assert.equal(response.statusCode, 200, 'Status code != 200'); - assert.notEqual(body.id, null); - assert.equal(body.method, 'store'); - assert.equal(body.payment_method.type, 'store'); - assert.notEqual(body.payment_method.reference, null); - assert.notEqual(body.payment_method.barcode_url, null); - done(); - }); - }); - }); - } - - describe('Create customer charge with existing card', function () { - it('should return statusCode 200||201', function (done) { - testExistingCardCharge.source_id = newlyCreatedCustomerCardId; //fails if use merchant card - //console.log(testExistingCardCharge); - openpay.customers.charges.create(newlyCreatedCustomerId, testExistingCardCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - var newlyCreatedCustomerTransactionId = ''; - describe('Create customer charge with new card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.charges.create(newlyCreatedCustomerId, testCreateCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedCustomerTransactionId = body.id; - done(); - }); - }); - }); - describe('Get all customer charges without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.customers.charges.list(newlyCreatedCustomerId, {}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - describe('Get customer charge', function () { - it('should return statusCode 200', function (done) { - openpay.customers.charges.get(newlyCreatedCustomerId, newlyCreatedCustomerTransactionId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - /*describe('Refund customer charge', function(){ - it('should return statusCode 200', function (done){ - openpay.customers.charges.refund(newlyCreatedCustomerId, newlyCreatedCustomerTransactionId, testRefundData, function (error, body, response){ - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - });*/ - describe('Create customer charge with new bank account', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.charges.create(newlyCreatedCustomerId, testCreateBankAccountCharge, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedCustomerTransactionId = body.id; - done(); - }); - }); - }); - }); - - - describe('Testing transfers', function () { - var newlyCreatedTransactionId = ''; - describe('Create transfer', function () { - it('should return statusCode 200||201', function (done) { - var temporalCustomerId = ''; - openpay.customers.create(testCreateCustomer, function (error, body, response) { - temporalCustomerId = body.id; - var testTransfer = { - "customer_id": temporalCustomerId, - "amount": 1.50, - "description": "Test transfer" - }; - openpay.customers.transfers.create(newlyCreatedCustomerId, testTransfer, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - openpay.customers.delete(temporalCustomerId, function (error, response, body) { - done(); - }); - }); - }); - }); - }); - describe('Get all transfers without constraints', function () { - it('should return statusCode 200', function (done) { - console.log('newlyCreatedCustomerId', newlyCreatedCustomerId) - openpay.customers.transfers.list(newlyCreatedCustomerId, {}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - describe('Get transfer', function () { - it('should return statusCode 200', function (done) { - openpay.customers.transfers.get(newlyCreatedCustomerId, newlyCreatedTransactionId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - - var testCardPayout = { - "method": "card", - "card": { - "card_number": "4111111111111111", - "holder_name": "Juan P", - "bank_code": "012" - }, - "amount": 1.50, - "description": "Test card payout" - }; - var testBankAccountPayout = { - "method": "bank_account", - "bank_account": { - "clabe": "012298026516924616", - "holder_name": "Juan P" - }, - "amount": 1.50, - "description": "Test bank account payout" - }; - - describe('Testing payouts', function () { - describe('Get all payouts without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.payouts.list({}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - if (testCreatePayouts) { - var newlyCreatedTransactionId = ''; - describe('Create payout with new card', function () { - it('should return statusCode 200||201', function (done) { - openpay.payouts.create(testCardPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Get payout', function () { - it('should return statusCode 200', function (done) { - openpay.payouts.get(newlyCreatedTransactionId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Create payout with new bank account', function () { - it('should return statusCode 200||201', function (done) { - openpay.payouts.create(testBankAccountPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Create payout with existing card', function () { - it('should return statusCode 200||201', function (done) { - var testExistingCardPayout = { - "method": "card", - "destination_id": newlyCreatedCardId, - "amount": 1.50, - "description": "Test payout with existing card" - }; - openpay.payouts.create(testExistingCardPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - describe('Create payout with existing bank account', function () { - it('should return statusCode 200||201', function (done) { - var testExistingBankAccountPayout = { - "method": "bank_account", - "destination_id": testBankAccountId, - "amount": 1.50, - "description": "Test payout with existing bank account" - }; - openpay.payouts.create(testExistingBankAccountPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedTransactionId = body.id; - done(); - }); - }); - }); - - var newlyCreatedCustomerTransactionId = ''; - describe('Create customer payout with new card', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.payouts.create(newlyCreatedCustomerId, testCardPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedCustomerTransactionId = body.id; - done(); - }); - }); - }); - describe('Get all customer payouts without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.customers.payouts.list(newlyCreatedCustomerId, {}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - describe('Get customer payout', function () { - it('should return statusCode 200', function (done) { - openpay.customers.payouts.get(newlyCreatedCustomerId, newlyCreatedCustomerTransactionId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Create customer payout with new bank account', function () { - it('should return statusCode 200||201', function (done) { - openpay.customers.payouts.create(newlyCreatedCustomerId, testBankAccountPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedCustomerTransactionId = body.id; - done(); - }); - }); - }); - var testExistingItemPayout = { - "method": "card", - "destination_id": "", - "amount": 1.50, - "description": "Test existing item payout" - }; - describe('Create customer payout with existing card', function () { - it('should return statusCode 200||201', function (done) { - testExistingItemPayout.destination_id = newlyCreatedCustomerCardId; - openpay.customers.payouts.create(newlyCreatedCustomerId, testExistingItemPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - describe('Create customer payout with existing bank account', function () { - it('should return statusCode 200||201', function (done) { - testExistingItemPayout.destination_id = newlyCreatedBankAccountId; - openpay.customers.payouts.create(newlyCreatedCustomerId, testExistingItemPayout, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - } - }); - - - describe('Testing fees', function () { - describe('Charge fee', function () { - it('should return statusCode 200||201', function (done) { - var testFee = { - "customer_id": newlyCreatedCustomerId, - "amount": 1.50, - "description": "Test fee" - }; - openpay.fees.create(testFee, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - done(); - }); - }); - }); - describe('Get all fees without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.fees.list({}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - }); - - var testPlan = { - "name": "Test plan", - "amount": 15.00, - "repeat_every": "1", - "repeat_unit": "month", - "retry_times": 2, - "status_after_retry": "cancelled", - "trial_days": "30" - }; - var newlyCreatedPlanId = ''; - describe('Testing plans', function () { - describe('Create plan', function () { - it('should return statusCode 200||201', function (done) { - openpay.plans.create(testPlan, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedPlanId = body.id; - done(); - }); - }); - }); - describe('Get all plans without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.plans.list(function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - describe('Get plan', function () { - it('should return statusCode 200', function (done) { - openpay.plans.get(newlyCreatedPlanId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Update plan', function () { - it('should return statusCode 200', function (done) { - openpay.plans.update(newlyCreatedPlanId, {"name": "Test plan"}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Get plan subscriptions', function () { - it('should return statusCode 200', function (done) { - openpay.plans.listSubscriptions(newlyCreatedPlanId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - }); - - describe('Testing subscriptions', function () { - var newlyCreatedSubscriptionId = ''; - describe('Create subscription', function () { - it('should return statusCode 200||201', function (done) { - var testSubscription = { - "plan_id": newlyCreatedPlanId, - "card_id": newlyCreatedCustomerCardId, - "trial_days": "30" - }; - openpay.customers.subscriptions.create(newlyCreatedCustomerId, testSubscription, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode == 200 || response.statusCode == 201, true, 'Status code == 200'); - newlyCreatedSubscriptionId = body.id; - done(); - }); - }); - }); - describe('Get all subscriptions without constraints', function () { - it('should return statusCode 200', function (done) { - openpay.customers.subscriptions.list(newlyCreatedCustomerId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code == 200'); - done(); - }); - }); - }); - describe('Get subscription', function () { - it('should return statusCode 200', function (done) { - openpay.customers.subscriptions.get(newlyCreatedCustomerId, newlyCreatedSubscriptionId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Update subscription', function () { - it('should return statusCode 200', function (done) { - openpay.customers.subscriptions.update(newlyCreatedCustomerId, newlyCreatedSubscriptionId, {"trial_end_date": "2022-02-11"}, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, ''); - done(); - }); - }); - }); - describe('Delete subscription', function () { - it('should return statusCode 204', function (done) { - openpay.customers.subscriptions.delete(newlyCreatedCustomerId, newlyCreatedSubscriptionId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - }); - - - describe('Delete plan', function () { - it('should return statusCode 204', function (done) { - openpay.plans.delete(newlyCreatedPlanId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - describe('Delete card', function () { - it('should return statusCode 204', function (done) { - openpay.cards.delete(newlyCreatedCardId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - describe('Delete customer card', function () { - it('should return statusCode 204', function (done) { - openpay.customers.cards.delete(newlyCreatedCustomerId, newlyCreatedCustomerCardId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - - describe('Delete bankaccount', function () { - it('should return statusCode 204', function (done) { - openpay.customers.bankaccounts.delete(newlyCreatedCustomerId, newlyCreatedBankAccountId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - - describe('Delete customer', function () { - it('should return statusCode 204', function (done) { - openpay.customers.delete(newlyCreatedCustomerId, function (error, body, response) { - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 204, ''); - done(); - }); - }); - }); - -}); - - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} - -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); - }); -} diff --git a/test/transfers.test.js b/test/transfers.test.js deleted file mode 100644 index c18481b..0000000 --- a/test/transfers.test.js +++ /dev/null @@ -1,43 +0,0 @@ -var assert = require('assert'); -var _ = require('underscore'); -var Openpay = require('../lib/openpay'); -/*Sandbox*/ -var openpay = new Openpay('m1qp3av1ymcfufkuuoah', 'sk_ed05f1de65fa4a67a3d3056a4efa2905'); -openpay.setTimeout(3000) - -var enableLogging = true; -var customerId = ''; -var testCreateCustomer = { - "name": "Juan", - "email": "juan@nonexistantdomain.com" -}; - -describe('Get all transfers with creation filter', function () { - this.timeout(0); - it('should return statusCode 200', function (done) { - var searchParams = { - 'creation[lte]': '2021-01-01', - 'limit': 10000 - }; - console.log('timeout:', openpay.timeout) - openpay.customers.create(testCreateCustomer, function (error, body) { - openpay.customers.transfers.list(body.id, searchParams, function (error, body, response) { - console.log('timeout', response.timeout) - printLog(response.statusCode, body, error); - assert.equal(response.statusCode, 200, 'Status code != 400'); - done(); - }); - }); - }) -}); - -function printLog(code, body, error) { - if (enableLogging) { - console.log(code, _.isUndefined(body) || _.isNull(body) ? '' : _.isArray(body) ? _.pluck(body, 'id') : body.id); - } - if (code >= 300) { - console.log(' '); - console.log(error); - console.log(' '); - } -} diff --git a/tests/colombia.spec.ts b/tests/colombia.spec.ts new file mode 100644 index 0000000..0891669 --- /dev/null +++ b/tests/colombia.spec.ts @@ -0,0 +1,461 @@ +import type { IOpenpay } from '../dist/openpay'; + +import { assert, describe, expect, it } from 'vitest'; +import { Openpay } from '../dist/openpay'; + +describe('Test the Openpay Colombia SDK', () => { + const openpay = new Openpay({ + merchantId: process.env.OPENPAY_MERCHANT_ID ?? '', + privateKey: process.env.OPENPAY_PRIVATE_KEY ?? '', + isProductionReady: false, + countryCode: 'co', + clientIP: '127.0.0.1', + }); + const device_session_id = process.env.OPENPAY_DEVICE_SESSION_ID ?? ''; + + // Defining a valid expiration year for cards, adding 5 years to the current one + const validExpYear = (new Date().getFullYear() + 5).toString().substring(2, 4); + + //////////////////////////////// + // WEBHOOK TESTS + //////////////////////////////// + + let testWebhookId = ''; + + const testWebhook: IOpenpay.Webhook.CreateInput = { + url: process.env.OPENPAY_WEBHOOK_TEST_URL ?? '', + user: 'juanito', + password: 'supersecure', + event_types: [ + 'charge.refunded', + 'charge.failed', + 'charge.cancelled', + 'charge.created', + 'chargeback.accepted', + ], + }; + + describe('Test webhooks API', () => { + it('should create a webhook', async () => { + const webhook = await openpay.webhooks.create(testWebhook); + expect(webhook).toBeTruthy(); + testWebhookId = webhook.id; + + console.log('The webhook:', webhook.id); + }); + + it('should get the webhook', async () => { + await expect(openpay.webhooks.get(testWebhookId)).resolves.toBeTruthy(); + }); + + it('should get all the webhooks', async () => { + await expect(openpay.webhooks.list()).resolves.toBeTruthy(); + }); + + it('should delete the webhook', async () => { + await expect(openpay.webhooks.delete(testWebhookId)).resolves.toBeUndefined(); + }); + }); + + //////////////////////////////// + // CUSTOMER TESTS + //////////////////////////////// + + let testCustomerId = ''; + const testCustomer: IOpenpay.Customer.CreateInput = { + name: 'Juan', + last_name: 'Pérez', + email: 'juan@ejemplo.com', + phone_number: '1234567890', + requires_account: true, // Create account to perform charge/fees/transfer tests + }; + + const today = toFilterDate(new Date()); + + describe('Testing customers API', () => { + it('should create a customer', async () => { + const customer = await openpay.customers.create(testCustomer); + expect(customer).toBeTruthy(); + testCustomerId = customer.id; + + console.log('The customer:', customer.id); + }); + + it('should get all customers', async () => { + await expect(openpay.customers.list()).resolves.toBeTruthy(); + }); + + it('should get the test customer', async () => { + await expect(openpay.customers.get(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should update the customer', async () => { + const customer = await openpay.customers.update(testCustomerId, { + name: 'Alberto', + email: 'alberto@ejemplo.com', + }); + expect(customer).toBeTruthy(); + + testCustomer.name = customer.name; + testCustomer.email = customer.email; + }); + + it('should get customers created today', async () => { + const customers = await openpay.customers.list({ creation: today }); + expect(customers).toBeTruthy(); + assert(customers.length > 0, 'No customers returned. It should have returned the test one'); + }); + }); + + //////////////////////////////// + // CARDS TESTS + //////////////////////////////// + + let testCardId = ''; + let testCustomerCardId = ''; + const testCard: IOpenpay.Card.CreateInput = { + card_number: '4111111111111111', + holder_name: testCustomer.name, + expiration_year: validExpYear, + expiration_month: '1', + cvv2: '110', + }; + + describe('Testing cards API', () => { + it('should create a card', async () => { + const card = await openpay.cards.create(testCard); + expect(card).toBeTruthy(); + testCardId = card.id; + + console.log('The card:', card.id); + }); + + it('should get all cards', async () => { + await expect(openpay.cards.list()).resolves.toBeTruthy(); + }); + + it('should get the test card', async () => { + await expect(openpay.cards.get(testCardId)).resolves.toBeTruthy(); + }); + + describe('Test customer cards API', () => { + it('should create a card for the customer', async () => { + const card = await openpay.customers.cards.create(testCustomerId, testCard); + expect(card).toBeTruthy(); + testCustomerCardId = card.id; + + console.log('The customer card:', card.id); + }); + + it('should get all cards of the customer', async () => { + await expect(openpay.customers.cards.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the test card for the customer', async () => { + await expect(openpay.customers.cards.get(testCustomerId, testCustomerCardId)).resolves.toBeTruthy(); + }); + }); + }); + + //////////////////////////////// + // CHARGE TESTS + //////////////////////////////// + + let testTxnId = ''; + let testCustomerTxnId = ''; + + const testExistingCardCharge: IOpenpay.Charge.CreateFromCard = { + amount: 200, + source_id: '', + method: 'card', + currency: 'COP', + device_session_id, + customer: testCustomer, + description: 'Test existing card charges', + }; + + const testStoreCharge: IOpenpay.Charge.CreateFromStore = { + amount: 50, + method: 'store', + currency: 'COP', + customer: testCustomer, + description: 'Test store charge', + }; + + const testRefund: IOpenpay.Charge.RefundInput = { description: 'Testing refund' }; + + describe('Test charges API', () => { + it('should get all charges', async () => { + await expect(openpay.charges.list()).resolves.toBeTruthy(); + }); + + it('should create a charge to an existing card', async () => { + testExistingCardCharge.source_id = testCardId; + const txn = await openpay.charges.create(testExistingCardCharge); + expect(txn).toBeTruthy(); + testTxnId = txn.id; + + console.log('The charge to existing card:', txn.id); + }); + + it('should get the created charge', async () => { + await expect(openpay.charges.get(testTxnId)).resolves.toBeTruthy(); + }); + + it('should refund the charge', async () => { + const txn = await openpay.charges.refund(testTxnId, testRefund); + expect(txn).toBeTruthy(); + }); + + it('should create charge on store', async () => { + const txn = await openpay.charges.create(testStoreCharge); + expect(txn).toBeTruthy(); + console.log('The charge to a store:', txn.id); + + expect(txn.id).toBeTruthy(); + assert.equal(txn.method, 'store'); + assert.equal(txn.payment_method?.type, 'store'); + expect(txn.payment_method?.reference).toBeTruthy(); + expect(txn.payment_method?.barcode_url).toBeTruthy(); + }); + + describe('Test customer charges API', () => { + it('should create a charge to an existing card', async () => { + const { customer, ...data } = testExistingCardCharge; + const txn = await openpay.customers.charges.create(testCustomerId, { + ...data, + source_id: testCustomerCardId, + }); + expect(txn).toBeTruthy(); + testCustomerTxnId = txn.id; + + console.log('The charge to an existing customer card:', txn.id); + }); + + it('should get all charges', async () => { + await expect(openpay.customers.charges.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the created charge', async () => { + await expect(openpay.customers.charges.get(testCustomerId, testCustomerTxnId)).resolves.toBeTruthy(); + }); + + it('should refund the charge', async () => { + await expect( + openpay.customers.charges.refund(testCustomerId, testCustomerTxnId, testRefund), + ).resolves.toBeTruthy(); + }); + + it('should create charge on store', async () => { + const { customer, ...data } = testStoreCharge; + const txn = await openpay.customers.charges.create(testCustomerId, data); + expect(txn).toBeTruthy(); + console.log('The charge to a customer on store:', txn.id); + }); + }); + }); + + //////////////////////////////// + // PLAN TESTS + //////////////////////////////// + + let testPlanId = ''; + const testPlan: IOpenpay.Plan.CreateInput = { + name: 'Test plan', + amount: 150, + trial_days: 30, + retry_times: 2, + repeat_every: 1, + currency: 'COP', + repeat_unit: 'month', + status_after_retry: 'cancelled', + }; + + describe('Test plans API', () => { + it('should create a plan', async () => { + const plan = await openpay.plans.create(testPlan); + expect(plan).toBeTruthy(); + testPlanId = plan.id; + + console.log('The plan:', plan.id); + }); + + it('should get all plans', async () => { + await expect(openpay.plans.list()).resolves.toBeTruthy(); + }); + + it('should get the plan', async () => { + await expect(openpay.plans.get(testPlanId)).resolves.toBeTruthy(); + }); + + it('should update the plan', async () => { + await expect(openpay.plans.update(testPlanId, { name: 'Updated test plan' })).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // SUBSCRIPTION TESTS + //////////////////////////////// + + let testSubscriptionId = ''; + + describe('Test subscriptions API', () => { + it('should create a subscription', async () => { + const subscription = await openpay.customers.subscriptions.create(testCustomerId, { + plan_id: testPlanId, + card_id: testCustomerCardId, + }); + expect(subscription).toBeTruthy(); + testSubscriptionId = subscription.id; + + console.log('The subscription:', subscription.id); + }); + + it('should get all the subscriptions', async () => { + await expect(openpay.customers.subscriptions.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the subscription', async () => { + await expect( + openpay.customers.subscriptions.get(testCustomerId, testSubscriptionId), + ).resolves.toBeTruthy(); + }); + + it('should update the subscription', async () => { + await expect( + openpay.customers.subscriptions.update(testCustomerId, testSubscriptionId, { trial_end_date: today }), + ).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // PSE TESTS + //////////////////////////////// + + const testPse: IOpenpay.Charge.CreateFromBank = { + method: 'bank_account', + amount: 10000, + currency: 'COP', + description: 'Cargo inicial a mi cuenta', + iva: '1900', + redirect_url: '/', + customer: { + name: 'Cliente Colombia', + last_name: 'Vazquez Juarez', + email: 'juan.vazquez@empresa.co', + phone_number: '4448936475', + requires_account: false, + customer_address: { + department: 'Medellín', + city: 'Antioquía', + additional: 'Avenida 7m bis #174-25 Apartamento 637', + }, + }, + }; + + describe('Test PSE API', () => { + it('should create a charge to a new client', async () => { + const txn = await openpay.pse.create(testPse); + expect(txn).toBeTruthy(); + + console.log('The PSE txn:', txn.id); + }); + + describe('Test customer PSE API', () => { + it('should create a charge to an existing user', async () => { + const { customer, ...data } = testPse; + const txn = await openpay.customers.pse.create(testCustomerId, data); + expect(txn).toBeTruthy(); + testCustomerTxnId = txn.id; + + console.log('The PSE charge to existing customer:', txn.id); + }); + }); + }); + + //////////////////////////////// + // TOKEN TESTS + //////////////////////////////// + + let testTokenId = ''; + + const testToken: IOpenpay.Token.CreateInput = { + card_number: '4111111111111111', + holder_name: 'Juan Perez Ramirez', + expiration_year: validExpYear, + expiration_month: '1', + cvv2: '110', + address: { + city: 'Bogotá', + country_code: 'CO', + postal_code: '110511', + line1: 'Av 5 de Febrero', + line2: 'Roble 207', + line3: 'col carrillo', + state: 'Bogota', + }, + }; + + describe('Test Token API', () => { + it('should create a token', async () => { + const token = await openpay.tokens.create(testToken); + expect(token).toBeTruthy(); + testTokenId = token.id; + + console.log('The token:', token.id); + }); + + it('should get the token', async () => { + await expect(openpay.tokens.get(testTokenId)).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // STORES TESTS + //////////////////////////////// + + describe('Test Stores API', () => { + it('should list stores by location', async () => { + await expect( + openpay.stores.list({ + latitud: 4.65589142889691, + longitud: -74.11335673251888, + kilometers: 10, + amount: 1, + }), + ).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // DELETION TESTS + //////////////////////////////// + + describe('Test object deletion API', () => { + it('should delete the subscription', async () => { + await expect( + openpay.customers.subscriptions.delete(testCustomerId, testSubscriptionId), + ).resolves.toBeUndefined(); + }); + + it('should delete the plan', async () => { + await expect(openpay.plans.delete(testPlanId)).resolves.toBeUndefined(); + }); + + it('should delete the cards', async () => { + await expect(openpay.cards.delete(testCardId)).resolves.toBeUndefined(); + await expect( + openpay.customers.cards.delete(testCustomerId, testCustomerCardId), + ).resolves.toBeUndefined(); + }); + + it('should delete the customers', async () => { + await expect(openpay.customers.delete(testCustomerId)).resolves.toBeUndefined(); + }); + }); +}); + +/** Format date as yyyy-mm-dd */ +function toFilterDate(date: Date) { + return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; +} diff --git a/tests/mexico.spec.ts b/tests/mexico.spec.ts new file mode 100644 index 0000000..afb7c13 --- /dev/null +++ b/tests/mexico.spec.ts @@ -0,0 +1,596 @@ +import type { IOpenpay } from '../dist/openpay'; + +import { assert, describe, expect, it } from 'vitest'; +import { Openpay } from '../dist/openpay'; + +const testPayouts = false; + +describe('Test the Openpay México SDK', () => { + const openpay = new Openpay({ + merchantId: process.env.OPENPAY_MERCHANT_ID ?? '', + privateKey: process.env.OPENPAY_PRIVATE_KEY ?? '', + isProductionReady: false, + countryCode: 'mx', + clientIP: '127.0.0.1', + }); + const device_session_id = process.env.OPENPAY_DEVICE_SESSION_ID ?? ''; + + // Defining a valid expiration year for cards, adding 5 years to the current one + const validExpYear = (new Date().getFullYear() + 5).toString().substring(2, 4); + + //////////////////////////////// + // WEBHOOK TESTS + //////////////////////////////// + + let testWebhookId = ''; + + const testWebhook: IOpenpay.Webhook.CreateInput = { + url: process.env.OPENPAY_WEBHOOK_TEST_URL ?? '', + event_types: [ + 'charge.refunded', + 'charge.failed', + 'charge.cancelled', + 'charge.created', + 'chargeback.accepted', + ], + }; + + describe('Test webhooks API', () => { + it('should create a webhook', async () => { + const webhook = await openpay.webhooks.create(testWebhook); + expect(webhook).toBeTruthy(); + testWebhookId = webhook.id; + + console.log('The webhook:', webhook.id); + }); + + it('should get the webhook', async () => { + await expect(openpay.webhooks.get(testWebhookId)).resolves.toBeTruthy(); + }); + + it('should get all the webhooks', async () => { + await expect(openpay.webhooks.list()).resolves.toBeTruthy(); + }); + + it('should delete the webhook', async () => { + await expect(openpay.webhooks.delete(testWebhookId)).resolves.toBeUndefined(); + }); + }); + + //////////////////////////////// + // CUSTOMER TESTS + //////////////////////////////// + + let testCustomerId = ''; + let testSecondaryCustomerId = ''; + const testCustomer: IOpenpay.Customer.CreateInput = { + name: 'Juan', + last_name: 'Pérez', + email: 'juan@ejemplo.com', + phone_number: '1234567890', + requires_account: true, // Create account to perform charge/fees/transfer tests + }; + + const today = toFilterDate(new Date()); + + describe('Testing customers API', () => { + it('should create a customer', async () => { + const customer = await openpay.customers.create(testCustomer); + expect(customer).toBeTruthy(); + testCustomerId = customer.id; + + console.log('The customer:', customer.id); + }); + + it('should get all customers', async () => { + await expect(openpay.customers.list()).resolves.toBeTruthy(); + }); + + it('should get the test customer', async () => { + await expect(openpay.customers.get(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should update the customer', async () => { + const customer = await openpay.customers.update(testCustomerId, { + name: 'Alberto', + email: 'alberto@ejemplo.com', + }); + expect(customer).toBeTruthy(); + + testCustomer.name = customer.name; + testCustomer.email = customer.email; + }); + + it('should get customers created today', async () => { + const customers = await openpay.customers.list({ creation: today }); + expect(customers).toBeTruthy(); + assert(customers.length > 0, 'No customers returned. It should have returned the test one'); + }); + }); + + //////////////////////////////// + // CARDS TESTS + //////////////////////////////// + + let testCardId = ''; + let testCustomerCardId = ''; + const testCard: IOpenpay.Card.CreateInput = { + card_number: '4111111111111111', + holder_name: testCustomer.name, + expiration_year: validExpYear, + expiration_month: '1', + cvv2: '110', + }; + + describe('Testing cards API', () => { + it('should create a card', async () => { + const card = await openpay.cards.create(testCard); + expect(card).toBeTruthy(); + testCardId = card.id; + + console.log('The card:', card.id); + }); + + it('should get all cards', async () => { + await expect(openpay.cards.list()).resolves.toBeTruthy(); + }); + + it('should get the test card', async () => { + await expect(openpay.cards.get(testCardId)).resolves.toBeTruthy(); + }); + + describe('Test customer cards API', () => { + it('should create a card for the customer', async () => { + const card = await openpay.customers.cards.create(testCustomerId, testCard); + expect(card).toBeTruthy(); + testCustomerCardId = card.id; + + console.log('The customer card:', card.id); + }); + + it('should get all cards of the customer', async () => { + await expect(openpay.customers.cards.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the test card for the customer', async () => { + await expect(openpay.customers.cards.get(testCustomerId, testCustomerCardId)).resolves.toBeTruthy(); + }); + }); + }); + + //////////////////////////////// + // BANK ACCOUNTS TESTS + //////////////////////////////// + + let testBankAccountId = ''; + const testBankAccount: IOpenpay.BankAccount.CreateInput = { + clabe: '021180000118359717', + holder_name: testCustomer.name, + }; + + describe('Testing bank accounts API', () => { + it('should create a bank account', async () => { + const bank = await openpay.customers.bankaccounts.create(testCustomerId, testBankAccount); + expect(bank).toBeTruthy(); + testBankAccountId = bank.id; + + console.log('The bank account:', bank.id); + }); + + it('should get all bank accounts of the customer', async () => { + await expect(openpay.customers.bankaccounts.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the test bank account for the customer', async (x) => { + await expect( + openpay.customers.bankaccounts.get(testCustomerId, testBankAccountId), + ).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // CHARGE TESTS + //////////////////////////////// + + let testTxnId = ''; + let testCustomerTxnId = ''; + + const testExistingCardCharge: IOpenpay.Charge.CreateFromCard = { + amount: 50, + source_id: '', + method: 'card', + device_session_id, + customer: testCustomer, + description: 'Test existing card charges', + }; + + const testBankAccountCharge: IOpenpay.Charge.CreateFromBank = { + amount: 50, + method: 'bank_account', + customer: testCustomer, + description: 'Test bank account charge', + }; + + const testStoreCharge: IOpenpay.Charge.CreateFromStore = { + amount: 50, + method: 'store', + customer: testCustomer, + description: 'Test store charge', + }; + + const testRefund: IOpenpay.Charge.RefundInput = { description: 'Testing refund' }; + + describe('Test charges API', () => { + it('should get all charges', async () => { + await expect(openpay.charges.list()).resolves.toBeTruthy(); + }); + + it('should create a charge to an existing card', async () => { + testExistingCardCharge.source_id = testCardId; + const txn = await openpay.charges.create(testExistingCardCharge); + expect(txn).toBeTruthy(); + testTxnId = txn.id; + + console.log('The charge to existing card:', txn.id); + }); + + it('should get the created charge', async () => { + await expect(openpay.charges.get(testTxnId)).resolves.toBeTruthy(); + }); + + it('should refund the charge', async () => { + const txn = await openpay.charges.refund(testTxnId, testRefund); + expect(txn).toBeTruthy(); + }); + + it('should create charge without capture', async () => { + testExistingCardCharge.source_id = testCardId; + const txn = await openpay.charges.create({ ...testExistingCardCharge, capture: false }); + expect(txn).toBeTruthy(); + testTxnId = txn.id; + + console.log('The charge without capture:', txn.id); + }); + + it('should capture the charge', async () => { + await expect(openpay.charges.capture(testTxnId, null)).resolves.toBeTruthy(); + }); + + it('should create charge with new bank account', async () => { + await expect(openpay.charges.create(testBankAccountCharge)).resolves.toBeTruthy(); + }); + + it('should create charge on store', async () => { + const txn = await openpay.charges.create(testStoreCharge); + expect(txn).toBeTruthy(); + console.log('The charge on store:', txn.id); + + expect(txn.id).toBeTruthy(); + assert.equal(txn.method, 'store'); + assert.equal(txn.payment_method?.type, 'store'); + expect(txn.payment_method?.reference).toBeTruthy(); + expect(txn.payment_method?.barcode_url).toBeTruthy(); + }); + + describe('Test customer charges API', () => { + it('should create a charge to an existing card', async () => { + const { customer, ...data } = testExistingCardCharge; + const txn = await openpay.customers.charges.create(testCustomerId, { + ...data, + source_id: testCustomerCardId, + }); + expect(txn).toBeTruthy(); + testCustomerTxnId = txn.id; + + console.log('The charge to existing customer card:', txn.id); + }); + + it('should get all charges', async () => { + await expect(openpay.customers.charges.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the created charge', async () => { + await expect(openpay.customers.charges.get(testCustomerId, testCustomerTxnId)).resolves.toBeTruthy(); + }); + + it('should refund the charge', async () => { + await expect( + openpay.customers.charges.refund(testCustomerId, testCustomerTxnId, testRefund), + ).resolves.toBeTruthy(); + }); + + it('should create charge with new bank account', async () => { + const { customer, ...data } = testBankAccountCharge; + const txn = await openpay.customers.charges.create(testCustomerId, data); + expect(txn).toBeTruthy(); + console.log('The charge to customer new bank:', txn.id); + }); + }); + }); + + //////////////////////////////// + // TRANSFERS TESTS + //////////////////////////////// + + let testTransferTxnId = ''; + + describe('Test transfers API', () => { + it('should create a transfer', async () => { + const secondaryCustomer = await openpay.customers.create(testCustomer); + expect(secondaryCustomer).toBeTruthy(); + testSecondaryCustomerId = secondaryCustomer.id; + + const txn = await openpay.customers.transfers.create(testCustomerId, { + customer_id: testSecondaryCustomerId, + amount: 1.5, + description: 'Test transfer', + }); + expect(txn).toBeTruthy(); + testTransferTxnId = txn.id; + + console.log('The transfer:', txn); + }); + + it('should get all customer transfers', async () => { + await expect(openpay.customers.transfers.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the transfer', async () => { + await expect(openpay.customers.transfers.get(testCustomerId, testTransferTxnId)).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // PAYOUT TESTS + //////////////////////////////// + + let testPayoutTxnId = ''; + let testCustomerPayoutTxnId = ''; + + const testCardPayout: IOpenpay.Payout.CreateInput = { + amount: 1.5, + method: 'card', + description: 'Test card payout', + card: { + card_number: testCard.card_number, + holder_name: testCard.holder_name, + bank_code: '012', + }, + }; + + const testBankPayout: IOpenpay.Payout.CreateInput = { + amount: 1.5, + method: 'bank_account', + description: 'Test bank payout', + bank_account: { + clabe: testBankAccount.clabe, + holder_name: testBankAccount.holder_name, + }, + }; + + if (testPayouts) { + describe('Test payouts API', () => { + it('should get all payouts', async () => { + await expect(openpay.payouts.list()).resolves.toBeTruthy(); + }); + + it('should create a payout to a new card', async () => { + const txn = await openpay.payouts.create(testCardPayout); + expect(txn).toBeTruthy(); + testPayoutTxnId = txn.id; + + console.log('The payout:', txn.id); + }); + + it('should get the payout', async () => { + await expect(openpay.payouts.get(testPayoutTxnId)).resolves.toBeTruthy(); + }); + + it('should create a payout to a new bank account', async () => { + await expect(openpay.payouts.create(testBankPayout)).resolves.toBeTruthy(); + }); + + it('should create a payout to an existing card', async () => { + await expect( + openpay.payouts.create({ + method: 'card', + destination_id: testCardId, + amount: 1.5, + description: 'Test payout to existing card', + }), + ).resolves.toBeTruthy(); + }); + + it('should create a payout to an existing bank account', async () => { + await expect( + openpay.payouts.create({ + method: 'bank_account', + destination_id: testBankAccountId, + amount: 1.5, + description: 'Test payout to existing bank account', + }), + ).resolves.toBeTruthy(); + }); + + describe('Test customer payouts API', () => { + it('should create a payout to a new card', async () => { + const txn = await openpay.customers.payouts.create(testCustomerId, testCardPayout); + expect(txn).toBeTruthy(); + testCustomerPayoutTxnId = txn.id; + + console.log('The customer payout:', txn.id); + }); + + it('should get all payouts', async () => { + await expect(openpay.customers.payouts.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the payout', async () => { + await expect( + openpay.customers.payouts.get(testCustomerId, testCustomerPayoutTxnId), + ).resolves.toBeTruthy(); + }); + + it('should create a payout to a new bank account', async () => { + await expect( + openpay.customers.payouts.create(testCustomerId, testBankPayout), + ).resolves.toBeTruthy(); + }); + + it('should create a payout to an existing card', async () => { + await expect( + openpay.customers.payouts.create(testCustomerId, { + method: 'card', + destination_id: testCustomerCardId, + amount: 1.5, + description: 'Test customer payout to existing card', + }), + ).resolves.toBeTruthy(); + }); + + it('should create a payout to an existing bank account', async () => { + await expect( + openpay.customers.payouts.create(testCustomerId, { + method: 'bank_account', + destination_id: testBankAccountId, + amount: 1.5, + description: 'Test customer payout to existing bank account', + }), + ).resolves.toBeTruthy(); + }); + }); + }); + } + + //////////////////////////////// + // FEE TESTS + //////////////////////////////// + + describe('Test fees API', () => { + it('should charge a fee', async () => { + const txn = await openpay.fees.create({ + customer_id: testCustomerId, + amount: 1.5, + description: 'Test fee', + }); + expect(txn).toBeTruthy(); + + console.log('The fee:', txn.id); + }); + + it('should get all fees', async () => { + await expect(openpay.fees.list()).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // PLAN TESTS + //////////////////////////////// + + let testPlanId = ''; + const testPlan: IOpenpay.Plan.CreateInput = { + name: 'Test plan', + amount: 15.0, + trial_days: 30, + retry_times: 2, + repeat_every: 1, + repeat_unit: 'month', + status_after_retry: 'cancelled', + }; + + describe('Test plans API', () => { + it('should create a plan', async () => { + const plan = await openpay.plans.create(testPlan); + expect(plan).toBeTruthy(); + testPlanId = plan.id; + + console.log('The plan:', plan.id); + }); + + it('should get all plans', async () => { + await expect(openpay.plans.list()).resolves.toBeTruthy(); + }); + + it('should get the plan', async () => { + await expect(openpay.plans.get(testPlanId)).resolves.toBeTruthy(); + }); + + it('should update the plan', async () => { + await expect(openpay.plans.update(testPlanId, { name: 'Updated test plan' })).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // SUBSCRIPTION TESTS + //////////////////////////////// + + let testSubscriptionId = ''; + + describe('Test subscriptions API', () => { + it('should create a subscription', async () => { + const subscription = await openpay.customers.subscriptions.create(testCustomerId, { + plan_id: testPlanId, + card_id: testCustomerCardId, + }); + expect(subscription).toBeTruthy(); + testSubscriptionId = subscription.id; + + console.log('The subscription:', subscription.id); + }); + + it('should get all the subscriptions', async () => { + await expect(openpay.customers.subscriptions.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the subscription', async () => { + await expect( + openpay.customers.subscriptions.get(testCustomerId, testSubscriptionId), + ).resolves.toBeTruthy(); + }); + + it('should update the subscription', async () => { + await expect( + openpay.customers.subscriptions.update(testCustomerId, testSubscriptionId, { trial_end_date: today }), + ).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // DELETION TESTS + //////////////////////////////// + + describe('Test object deletion API', () => { + it('should delete the subscription', async () => { + await expect( + openpay.customers.subscriptions.delete(testCustomerId, testSubscriptionId), + ).resolves.toBeUndefined(); + }); + + it('should delete the plan', async () => { + await expect(openpay.plans.delete(testPlanId)).resolves.toBeUndefined(); + }); + + it('should delete the cards', async () => { + await expect(openpay.cards.delete(testCardId)).resolves.toBeUndefined(); + await expect( + openpay.customers.cards.delete(testCustomerId, testCustomerCardId), + ).resolves.toBeUndefined(); + }); + + it("should delete the customer's bank account", async () => { + await expect( + openpay.customers.bankaccounts.delete(testCustomerId, testBankAccountId), + ).resolves.toBeUndefined(); + }); + + it('should delete the customers', async () => { + await expect(openpay.customers.delete(testCustomerId)).resolves.toBeUndefined(); + await expect(openpay.customers.delete(testSecondaryCustomerId)).resolves.toBeUndefined(); + }); + }); +}); + +/** Format date as yyyy-mm-dd */ +function toFilterDate(date: Date) { + return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; +} diff --git a/tests/peru.spec.ts b/tests/peru.spec.ts new file mode 100644 index 0000000..0c1059a --- /dev/null +++ b/tests/peru.spec.ts @@ -0,0 +1,449 @@ +import type { IOpenpay } from '../dist/openpay'; + +import { assert, describe, expect, it } from 'vitest'; +import { Openpay } from '../dist/openpay'; + +describe('Test the Openpay Perú SDK', () => { + const openpay = new Openpay({ + merchantId: process.env.OPENPAY_MERCHANT_ID ?? '', + privateKey: process.env.OPENPAY_PRIVATE_KEY ?? '', + isProductionReady: false, + countryCode: 'pe', + clientIP: '127.0.0.1', + }); + const device_session_id = process.env.OPENPAY_DEVICE_SESSION_ID ?? ''; + + // Defining a valid expiration year for cards, adding 5 years to the current one + const validExpYear = (new Date().getFullYear() + 5).toString().substring(2, 4); + + //////////////////////////////// + // WEBHOOK TESTS + //////////////////////////////// + + let testWebhookId = ''; + + const testWebhook: IOpenpay.Webhook.CreateInput = { + url: process.env.OPENPAY_WEBHOOK_TEST_URL ?? '', + event_types: [ + 'charge.refunded', + 'charge.failed', + 'charge.cancelled', + 'charge.created', + 'chargeback.accepted', + ], + }; + + describe('Test webhooks API', () => { + it('should create a webhook', async () => { + const webhook = await openpay.webhooks.create(testWebhook); + expect(webhook).toBeTruthy(); + testWebhookId = webhook.id; + + console.log('The webhook:', webhook.id); + }); + + it('should get the webhook', async () => { + await expect(openpay.webhooks.get(testWebhookId)).resolves.toBeTruthy(); + }); + + it('should get all the webhooks', async () => { + await expect(openpay.webhooks.list()).resolves.toBeTruthy(); + }); + + it('should delete the webhook', async () => { + await expect(openpay.webhooks.delete(testWebhookId)).resolves.toBeUndefined(); + }); + }); + + //////////////////////////////// + // CUSTOMER TESTS + //////////////////////////////// + + let testCustomerId = ''; + const testCustomer: IOpenpay.Customer.CreateInput = { + name: 'Marco', + last_name: 'Morales Pérez', + email: 'marco@ejemplo.com', + phone_number: '1234567890', + requires_account: true, // Create account to perform charge/fees/transfer tests + }; + + const today = toFilterDate(new Date()); + + describe('Testing customers API', () => { + it('should create a customer', async () => { + const customer = await openpay.customers.create(testCustomer); + expect(customer).toBeTruthy(); + testCustomerId = customer.id; + + console.log('The customer:', customer.id); + }); + + it('should get all customers', async () => { + await expect(openpay.customers.list()).resolves.toBeTruthy(); + }); + + it('should get the test customer', async () => { + await expect(openpay.customers.get(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should update the customer', async () => { + const customer = await openpay.customers.update(testCustomerId, { + name: 'Alberto', + email: 'alberto@ejemplo.com', + }); + expect(customer).toBeTruthy(); + + testCustomer.name = customer.name; + testCustomer.email = customer.email; + }); + + it('should get customers created today', async () => { + const customers = await openpay.customers.list({ creation: today }); + expect(customers).toBeTruthy(); + assert(customers.length > 0, 'No customers returned. It should have returned the test one'); + }); + }); + + //////////////////////////////// + // CARDS TESTS + //////////////////////////////// + + let testCardId = ''; + let testCustomerCardId = ''; + + const testCard: IOpenpay.Card.CreateInput = { + card_number: '4111111111111111', + holder_name: testCustomer.name, + expiration_year: validExpYear, + expiration_month: '1', + cvv2: '110', + }; + + describe('Testing cards API', () => { + it('should create a card', async () => { + const card = await openpay.cards.create(testCard); + expect(card).toBeTruthy(); + testCardId = card.id; + + console.log('The card:', card.id); + }); + + it('should get all cards', async () => { + await expect(openpay.cards.list()).resolves.toBeTruthy(); + }); + + it('should get the test card', async () => { + await expect(openpay.cards.get(testCardId)).resolves.toBeTruthy(); + }); + + describe('Test customer cards API', () => { + it('should create a card for the customer', async () => { + const card = await openpay.customers.cards.create(testCustomerId, testCard); + expect(card).toBeTruthy(); + testCustomerCardId = card.id; + + console.log('The customer card:', card.id); + }); + + it('should get all cards of the customer', async () => { + await expect(openpay.customers.cards.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the test card for the customer', async () => { + await expect(openpay.customers.cards.get(testCustomerId, testCustomerCardId)).resolves.toBeTruthy(); + }); + }); + }); + + //////////////////////////////// + // CHARGE TESTS + //////////////////////////////// + + let testTxnId = ''; + let testCustomerTxnId = ''; + + const testExistingCardCharge: IOpenpay.Charge.CreateFromCard = { + amount: 716, + source_id: '', + method: 'card', + currency: 'PEN', + device_session_id, + customer: testCustomer, + description: 'Test existing card charges', + }; + + const testStoreCharge: IOpenpay.Charge.CreateFromStore = { + amount: 716, + method: 'store', + currency: 'PEN', + customer: testCustomer, + description: 'Test store charge', + }; + + describe('Test charges API', () => { + it('should get all charges', async () => { + await expect(openpay.charges.list()).resolves.toBeTruthy(); + }); + + it('should create a charge to an existing card', async () => { + testExistingCardCharge.source_id = testCardId; + const txn = await openpay.charges.create(testExistingCardCharge); + expect(txn).toBeTruthy(); + testTxnId = txn.id; + + console.log('The charge to an existing card:', txn.id); + }); + + it('should get the created charge', async () => { + await expect(openpay.charges.get(testTxnId)).resolves.toBeTruthy(); + }); + + it('should create charge on store', async () => { + const txn = await openpay.charges.create(testStoreCharge); + expect(txn).toBeTruthy(); + console.log('The charge on store:', txn.id); + + expect(txn.id).toBeTruthy(); + assert.equal(txn.method, 'store'); + assert.equal(txn.payment_method?.type, 'store'); + expect(txn.payment_method?.reference).toBeTruthy(); + expect(txn.payment_method?.barcode_url).toBeTruthy(); + }); + + describe('Test customer charges API', () => { + it('should create a charge to an existing card', async () => { + const { customer, ...data } = testExistingCardCharge; + const txn = await openpay.customers.charges.create(testCustomerId, { + ...data, + source_id: testCustomerCardId, + }); + expect(txn).toBeTruthy(); + testCustomerTxnId = txn.id; + + console.log('The customer charge on existing card:', txn.id); + }); + + it('should get all charges', async () => { + await expect(openpay.customers.charges.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the created charge', async () => { + await expect(openpay.customers.charges.get(testCustomerId, testCustomerTxnId)).resolves.toBeTruthy(); + }); + + it('should create charge on store', async () => { + const { customer, ...data } = testStoreCharge; + const txn = await openpay.customers.charges.create(testCustomerId, data); + expect(txn).toBeTruthy(); + console.log('The customer charge on store:', txn.id); + }); + }); + }); + + //////////////////////////////// + // PLAN TESTS + //////////////////////////////// + + let testPlanId = ''; + const testPlan: IOpenpay.Plan.CreateInput = { + name: 'Test plan', + amount: 15.0, + trial_days: 30, + retry_times: 2, + currency: 'PEN', + repeat_every: 1, + repeat_unit: 'month', + status_after_retry: 'cancelled', + }; + + describe('Test plans API', () => { + it('should create a plan', async () => { + const plan = await openpay.plans.create(testPlan); + expect(plan).toBeTruthy(); + testPlanId = plan.id; + + console.log('The plan:', plan.id); + }); + + it('should get all plans', async () => { + await expect(openpay.plans.list()).resolves.toBeTruthy(); + }); + + it('should get the plan', async () => { + await expect(openpay.plans.get(testPlanId)).resolves.toBeTruthy(); + }); + + it('should update the plan', async () => { + await expect(openpay.plans.update(testPlanId, { name: 'Updated test plan' })).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // SUBSCRIPTION TESTS + //////////////////////////////// + + let testSubscriptionId = ''; + + describe('Test subscriptions API', () => { + it('should create a subscription', async () => { + const subscription = await openpay.customers.subscriptions.create(testCustomerId, { + plan_id: testPlanId, + card_id: testCustomerCardId, + }); + expect(subscription).toBeTruthy(); + testSubscriptionId = subscription.id; + + console.log('The subscription:', subscription.id); + }); + + it('should get all the subscriptions', async () => { + await expect(openpay.customers.subscriptions.list(testCustomerId)).resolves.toBeTruthy(); + }); + + it('should get the subscription', async () => { + await expect( + openpay.customers.subscriptions.get(testCustomerId, testSubscriptionId), + ).resolves.toBeTruthy(); + }); + + it('should update the subscription', async () => { + await expect( + openpay.customers.subscriptions.update(testCustomerId, testSubscriptionId, { trial_end_date: today }), + ).resolves.toBeTruthy(); + }); + }); + + //////////////////////////////// + // TOKEN TESTS + //////////////////////////////// + + let testTokenId = ''; + + const testToken: IOpenpay.Token.CreateInput = { + card_number: '4111111111111111', + holder_name: 'Juan Perez Ramirez', + expiration_year: validExpYear, + expiration_month: '1', + cvv2: '110', + address: { + city: 'Lima', + country_code: 'PE', + postal_code: '110511', + line1: 'Av 5 de Febrero', + line2: 'Roble 207', + line3: 'col carrillo', + state: 'Lima', + }, + }; + + describe('Test Token API', () => { + it('should create a token', async () => { + const token = await openpay.tokens.create(testToken); + expect(token).toBeTruthy(); + testTokenId = token.id; + + console.log('The token:', token.id); + }); + + it('should get the token', async () => { + const token = await openpay.tokens.get(testTokenId); + expect(token).toBeTruthy(); + assert.equal(token.id, testTokenId); + }); + }); + + //////////////////////////////// + // CHECKOUT TESTS + //////////////////////////////// + + let testCheckoutId = ''; + + const testCheckout: IOpenpay.Checkout.CreateInput = { + amount: 250, + currency: 'PEN', + send_email: false, + order_id: Date.now().toString(), + description: 'Link checkout charge', + redirect_url: 'https://www.openpay.pe', + customer: { + email: testCustomer.email, + last_name: testCustomer.last_name ?? '', + name: testCustomer.name, + phone_number: testCustomer.phone_number ?? '', + }, + }; + + describe('Test Checkouts API', () => { + it('should create a checkout', async () => { + const checkout = await openpay.checkouts.create(testCheckout); + expect(checkout).toBeTruthy(); + testCheckoutId = checkout.id; + + console.log('The checkout:', checkout.id); + }); + + it('should get the checkout', async () => { + const checkout = await openpay.checkouts.get(testCheckoutId); + expect(checkout).toBeTruthy(); + assert.equal(checkout.id, testCheckoutId); + }); + + it('should update the checkout', async () => { + const checkout = await openpay.checkouts.update(testCheckoutId, 'available', { + expiration_date: `${today} 23:59`, + }); + expect(checkout).toBeTruthy(); + assert.equal(checkout.id, testCheckoutId); + assert.equal(checkout.status, 'available'); + }); + + it('should get all the checkouts', async () => { + await expect(openpay.checkouts.list()).resolves.toBeTruthy(); + }); + + it('should create a customer checkout', async () => { + const { customer, order_id, ...data } = testCheckout; + // @ts-expect-error Perú doesn't expect the customer info + const checkout = await openpay.customers.checkouts.create(testCustomerId, { + ...data, + order_id: (Date.now() + 1).toString(), + }); + expect(checkout).toBeTruthy(); + + console.log('The customer checkout:', checkout.id); + }); + }); + + //////////////////////////////// + // DELETION TESTS + //////////////////////////////// + + describe('Test object deletion API', () => { + it('should delete the subscription', async () => { + await expect( + openpay.customers.subscriptions.delete(testCustomerId, testSubscriptionId), + ).resolves.toBeUndefined(); + }); + + it('should delete the plan', async () => { + await expect(openpay.plans.delete(testPlanId)).resolves.toBeUndefined(); + }); + + it('should delete the cards', async () => { + await expect(openpay.cards.delete(testCardId)).resolves.toBeUndefined(); + await expect( + openpay.customers.cards.delete(testCustomerId, testCustomerCardId), + ).resolves.toBeUndefined(); + }); + + it('should delete the customers', async () => { + await expect(openpay.customers.delete(testCustomerId)).resolves.toBeUndefined(); + }); + }); +}); + +/** Format date as yyyy-mm-dd */ +function toFilterDate(date: Date) { + return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..a7f0d75 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "CommonJS", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "noUncheckedIndexedAccess": true, + "noEmit": true + } +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..4b3f7f4 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,14 @@ +import { config } from 'dotenv'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + watch: false, + testTimeout: 10000, + include: ['./tests/**/*.spec.ts'], + env: { + // Sandbox environment + ...config({ path: './.env.testing' }).parsed, + }, + }, +});