{"id":20741099,"url":"https://github.com/robtimus/connect-client-sdk-ts","last_synced_at":"2025-05-11T03:33:13.141Z","repository":{"id":165161300,"uuid":"633414589","full_name":"robtimus/connect-client-sdk-ts","owner":"robtimus","description":"An SDK for the Worldline Connect Client API","archived":true,"fork":false,"pushed_at":"2025-01-04T14:19:54.000Z","size":1166,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-04T10:17:57.355Z","etag":null,"topics":["connect-sdk","javascript","nodejs","typescript"],"latest_commit_sha":null,"homepage":"https://robtimus.github.io/connect-client-sdk-ts/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robtimus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-27T12:55:29.000Z","updated_at":"2025-02-22T13:42:48.000Z","dependencies_parsed_at":"2024-04-04T17:53:46.486Z","dependency_job_id":"d29ed223-ebcf-4e2c-bb08-6cc4df1caf02","html_url":"https://github.com/robtimus/connect-client-sdk-ts","commit_stats":{"total_commits":139,"total_committers":2,"mean_commits":69.5,"dds":0.05035971223021585,"last_synced_commit":"f2d9a4659dfdfd14063d36fd1691be8a893cde5c"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fconnect-client-sdk-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fconnect-client-sdk-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fconnect-client-sdk-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fconnect-client-sdk-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robtimus","download_url":"https://codeload.github.com/robtimus/connect-client-sdk-ts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253514352,"owners_count":21920327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["connect-sdk","javascript","nodejs","typescript"],"created_at":"2024-11-17T06:33:47.172Z","updated_at":"2025-05-11T03:33:12.773Z","avatar_url":"https://github.com/robtimus.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Worldline Connect client SDK\n[![npm](https://img.shields.io/npm/v/@robtimus/connect-client-sdk)](https://www.npmjs.com/package/@robtimus/connect-client-sdk)\n[![Build Status](https://github.com/robtimus/connect-client-sdk-ts/actions/workflows/build.yml/badge.svg)](https://github.com/robtimus/connect-client-sdk-ts/actions/workflows/build.yml)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=robtimus%3Aconnect-client-sdk\u0026metric=alert_status)](https://sonarcloud.io/summary/overall?id=robtimus%3Aconnect-client-sdk)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=robtimus%3Aconnect-client-sdk\u0026metric=coverage)](https://sonarcloud.io/summary/overall?id=robtimus%3Aconnect-client-sdk)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/connect-client-sdk-ts/badge.svg)](https://snyk.io/test/github/robtimus/connect-client-sdk-ts)\n\nAn SDK for the [Worldline Connect](https://epayments.developer-ingenico.com/) Client API. It's based on the [official SDK](https://github.com/Ingenico-ePayments/connect-sdk-client-js), but is mostly written from scratch, and provides some improvements:\n\n* No hard requirement on browser specifics. Although this is the default, with only a little work it's possible to use the SDK in React Native apps.\n* No custom code for functionality most modern browsers support like Base64 encoding/decoding.\n* Proper promises.\n* HTTP calls use the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) if available, with [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) available as fallback.\n* Native cryptography if available, through the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API). [node-forge](https://www.npmjs.com/package/node-forge) can still be used as fallback.\n* No deprecated legacy code.\n* More support for creating Apple Pay and Google Pay payments.\n\n## Installation\n\nInstall this SDK using your preferred Node.js package manager like `npm`, `yarn` or `pnpm`. For instance:\n\n    npm i @robtimus/connect-client-sdk\n\n## Packaging\n\nThe SDK's default packaging is as separate ES modules. This can be used by most bundlers, but also in non-browser environments.\nThe default export contains the most important types:\n\n```typescript\nimport { PaymentContext, PaymentRequest, Session, SessionDetails } from \"@robtimus/connect-client-sdk\";\n```\n\n### Usage Universal Module Definition (UMD)\n\nThe SDK is available under global namespace `connectClientSdk`, and can be imported in the following way:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    ...\n    \u003cscript src=\"./node_modules/@robtimus/connect-client-sdk/dist/connect-client-sdk.umd.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cscript\u003e\n      const session = new connectClientSdk.Session({\n        ...\n      }, {\n        ...\n      })\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Getting started\n\n1. Use the Worldline Connect Server APi's [Create session](https://apireference.connect.worldline-solutions.com/s2sapi/v1/en_US/json/sessions/create.html) call to create a session.\n\n2. Create a [SessionDetails](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.SessionDetails.html) object using the Create session response:\n\n```typescript\nconst sessionDetails: SessionDetails = {\n  assetUrl: \"https://payment.pay1.secured-by-ingenico.com/\",\n  clientApiUrl: \"https://eu.api-ingenico.com/client\",\n  clientSessionId: \"f084372052fb47d9a766ec35bfa0e6bd\",\n  customerId: \"9991-0b67467b30df4c6d8649c8adc568fd0f\",\n};\n```\n\n\u003e In JavaScript, the session response can be used as-is. In TypeScript you need to either remove the `invalidTokens` and `region` properties (if present), or cast the response to `SessionDetails`.\n\n3. Create a [PaymentContext](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.PaymentContext.html) object with the necessary values (more properties can be added as necessary):\n\n```typescript\nconst paymentContext: PaymentContext = {\n  amountOfMoney: {\n    amount: 1000,\n    currencyCode: \"EUR\",\n  },\n  countryCode: \"NL\",\n};\n```\n\n4. Create a [Session](https://robtimus.github.io/connect-client-sdk-ts/classes/Session.Session.html) object with the created `SessionDetails` and `PaymentContext` objects:\n\n```typescript\nconst session = new Session(sessionDetails, paymentContext);\n```\n\n\u003e Unlike the official SDK, this SDK requires the payment context to be specified up front. It can be updated using `session.updatePaymentContext`. This accepts a partial `PaymentContext` that will be merged into the session's payment context. This allows you to only specify the changes you want to make.\n\n5. Use the `Session` object to retrieve the available payment products, payment product groups, and their accounts on file. Display these, and let your customer select one:\n\n```typescript\nconst paymentItems = await session.getBasicPaymentItems();\n// Display the contents of paymentItems.paymentItems (the payment products and payment product groups)\n// and paymentItems.accountsOnFile\n```\n\n6. When a payment product or payment product group is selected, use the `Session` object to retrieve more information about the payment product or payment product group. This contains the fields for the product. Display these fields and let your customer fill them in:\n\n```typescript\nconst paymentProduct = await session.getPaymentProduct(1);\n// or const paymentProductGroup = await session.getPaymentProductGroup(\"cards\");\n// Display the contents of paymentProduct.fields or paymentProductGroup.fields\n```\n\n7. Create an instance of [PaymentRequest](https://robtimus.github.io/connect-client-sdk-ts/classes/model.PaymentRequest.html), set its payment product, and store the value entered for each field:\n\n```typescript\nconst paymentRequest = new PaymentRequest();\npaymentRequest.setPaymentProduct(paymentProduct);\npaymentRequest.setValue(\"cardNumber\", \"4567 3500 0042 7977\");\npaymentRequest.setValue(\"cvv\", \"123\");\npaymentRequest.setValue(\"expiryDate\", \"12/99\");\npaymentRequest.setValue(\"cardholderName\", \"Wile E. Coyote\");\n```\n\n\u003e The values can be masked (as shown above), as long as the mask matches the field's mask. The SDK will automatically remove these masks when needed.\n\n8. Validate the `PaymentRequest` object:\n\n```typescript\nconst result = paymentRequest.validate();\nif (!result.valid) {\n  // result.errors contains each validation error, e.g. { fieldId: \"cardNumber\", ruleId: \"luhn\" }\n  // or { fieldId: \"cvv\", ruleId: \"required\" }\n  // These can be be used to display error messages to your customer\n}\n```\n\n9. Encrypt the contents of the `PaymentRequest` object:\n\n```typescript\nconst encryptor = session.getEncryptor();\nconst payload = await encryptor.encrypt(paymentRequest);\n```\n\n10. Send the payload to your server, where it can be used for the `encryptedCustomerInput` property of a [Create payment](https://apireference.connect.worldline-solutions.com/s2sapi/v1/en_US/json/payments/create.html) call.\n\n## Extended usage\n\n### IIN details\n\nWhen using the `cards` payment product group, it's important to know which payment product a card belongs to. This can be done by retrieving the [IIN details](https://apireference.connect.worldline-solutions.com/c2sapi/v1/en_US/json/services/getIINdetails.html), and checking the status property:\n\n```typescript\nconst iinDetails = await session.getIINDetails(\"4567 35\");\nswitch (iinDetails.status) {\n  case \"SUPPORTED\":\n    // The card is known and allowed within the current payment context.\n    // iinDetails.isAllowedInContext is true, iinDetails.paymentProductId and iinDetails.countryCode\n    // are available.\n    // If the card has multiple brands, iinDetails.coBrands contains the paymentProductId for each of them,\n    // and an isAllowedInContext flag that determines whether or not the co-brand is allowed for the\n    // current context.\n    // To render the brands, session.getPaymentProductDisplayHints can be called with the paymentProductId\n    // field of each support cobrand for which isAllowedInContext is true.\n    break;\n  case \"NOT_ALLOWED\":\n    // The card is known but not allowed within the current payment context.\n    // Like SUPPORTED, but iinDetails.isAllowedInContext is false.\n    break;\n  case \"NOT_ENOUGH_DIGITS\":\n    // Fewever than 6 digits were provided. No additional properties are available.\n    break;\n  case \"UNKNOWN\":\n    // The card is not known.\n    // iinDetails.errorId and iinDetails.errors come from the Worldline Connect Client API error response.\n    break\n}\n```\n\n### Payment product specifics\n\n#### Apple Pay\n\nif Apple Pay (302) is one of your available payment products, you need to provide some more information in the `PaymentContext` to be able to use it:\n\n```typescript\nconst paymentContext: PaymentContext = {\n  ...\n  paymentProductSpecificInputs: {\n    applePay: {\n      merchantName: \"Your name\",\n      merchantCountryCode: \"Your optional 2-letter ISO country code;\\\n                            the acquirer country as returned by the Worldline Connect Client API\\\n                            will be used if available, otherwise this value if specified,\\\n                            otherwise the country code from the payment context\",\n      lineItem: \"Optional line item; if not set the merchant name will be used\",\n    }\n  }\n};\n```\n\nYou can then use the following code to set a `PaymentRequest`'s value for Apple Pay's `encryptedPaymentData` field:\n\n```typescript\nconst applePayProduct = await session.getPaymentProduct(302);\n// or const applePayProduct = paymentProducts.getPaymentProduct(302);\n// or const applePayProduct = paymentItems.getPaymentItem(302);\nconst applePayHelper = await session.ApplePay(applePayProduct);\nconst paymentData = await applePayHelper.createPayment();\n\npaymentRequest.setValue(\"encryptedPaymentData\", JSON.stringify(paymentData.paymentData));\n```\n\n\u003e If the browser does not support Apple Pay, the SDK will filter it out of the available payment products.\n\n#### Google Pay\n\nIf Google Pay (320) is one of your available payment products, you need to provide some more information in the `PaymentContext` to be able to use it:\n\n```typescript\nconst paymentContext: PaymentContext = {\n  ...\n  paymentProductSpecificInputs: {\n    googlePay: {\n      connectMerchantId: \"Your Connect merchant id\",\n      googlePayMerchantId: \"Your Google Pay merchant id\",\n      transactionCountryCode: \"ISO 3166-1 alpha-2 country code for the country where the transaction\\\n                               will be completed/processed;\\\n                               the acquirer country as returned by the Worldline Connect Client API\\\n                               will be used if available, otherwise this value if specified,\\\n                               otherwise the country code from the payment context\",\n      merchantName: \"Your optional user visible merchant name; if not set the Business name in your\\\n                     Google Pay Developer Profile will be used\",\n      environment: \"PRODUCTION\", // or \"TEST\" for test purposes\n    }\n  }\n};\n```\n\nYou can then use the following code to set a `PaymentRequest`'s value for Google Pay's `encryptedPaymentData` field:\n\n```typescript\nconst googlePayProduct = await session.getPaymentProduct(320);\n// or const googlePayProduct = paymentProducts.getPaymentProduct(320);\n// or const googlePayProduct = paymentItems.getPaymentItem(320);\nconst googlePayHelper = await session.GooglePay(googlePayProduct);\nconst paymentData = await googlePayHelper.createPayment();\n\npaymentRequest.setValue(\"encryptedPaymentData\", paymentData.paymentMethodData.tokenizationData.token);\n```\n\n\u003e The `googlePayHelper` can be used before initializing the payment for two purposes:\n\u003e 1. `googlePayHelper.prefetchPaymentData()` prefetches configuration to improve `createPayment` execution time on later user interaction.\n\u003e 2. `googlePayHelper.createButton({ ... })` creates a button that you can add to your page (see https://developers.google.com/pay/api/web/guides/tutorial#add-button). Note that the `allowedPaymentMethods` will be set for you, you only need to provide the `onClick` handler and display properties.\n\n\u003e You need to load an additional JavaScript file (see https://developers.google.com/pay/api/web/guides/tutorial#js-load). If you don't, the SDK will filter Google Pay out of the available payment products.\n\n#### Bancontact\n\nBy default, retrieving the Bancontact (3012) product will not return the fields of the basic flow. You can force these fields to be returned by providing some more information in the `PaymentContext`:\n\n```typescript\nconst paymentContext: PaymentContext = {\n  ...\n  paymentProductSpecificInputs: {\n    bancontact: {\n      forceBasicFlow: true,\n    }\n  }\n};\n```\n\nSee the details of the `forceBasicFlow` query parameter of the [Get payment product](https://apireference.connect.worldline-solutions.com/c2sapi/v1/en_US/javascript/products/get.html) call for more information.\n\n### Masking field values\n\nTo help in formatting field values like credit cards or expiry dates, [PaymentProductField](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.PaymentProductField.html) provides functions `applyMask`, `applyWildcardMask` and `removeMask` to apply and remove masks. For example:\n\n```typescript\nconst cardNumberField = paymentProduct.getField(\"cardNumber\");\nconst value = \"4567350000427977\";\n\nconst maskedValue = cardNumberField.applyMask(value).formattedValue; // 4567 3500 0042 7977\n\nconst unmaskedValue = cardNumberField.removeMask(maskedValue); // 4567350000427977\n```\n\n### Accounts on file (tokens)\n\nAccounts on file are available from instances of [BasicPaymentItem](https://robtimus.github.io/connect-client-sdk-ts/types/model.BasicPaymentItem.html) / [PaymentItem](https://robtimus.github.io/connect-client-sdk-ts/types/model.PaymentItem.html), [BasicPaymentProduct](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.BasicPaymentProduct.html) / [PaymentProduct](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.PaymentProduct.html) and [BasicPaymentProductGroup](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.BasicPaymentProductGroup.html) / [PaymentProductGroup](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.PaymentProductGroup.html). They are also available from instances of [BasicPaymentItems](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.BasicPaymentItems.html), [BasicPaymentProducts](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.BasicPaymentProducts.html) and [BasicPaymentProductGroups](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.BasicPaymentProductGroups.html); these contain the accounts on file of each of their elements.\n\nAn account on file can be rendered in the list of available accounts on file using the label template elements of its display hints in combination with the account on file attributes:\n\n```typescript\nconst accountOnFile = ...;\nconst displayValue = accountOnFile.displayHints.labelTemplate\n  .map((e) =\u003e accountOnFile.getAttributeDisplayValue(e.attributeKey))\n  .join(\" \");\n// or equivalent:\nconst label = accountOnFile.getLabel();\n```\n\nTo render an account on file's detail page, fetch its matching payment product and display it mostly as usual. However, some fields should not be editable. [AccountOnFile](https://robtimus.github.io/connect-client-sdk-ts/interfaces/model.AccountOnFile.html) has method `isReadOnlyAttribute` that can be used. For instance:\n\n```typescript\nconst paymentProduct = await session.getPaymentProduct(accountOnFile.paymentProductId);\nfor (const field of paymentProduct.fields) {\n  if (accountOnFile.isReadOnlyAttribute(field.id)) {\n    // render accountOnFile.getAttributeDisplayValue(field.id) as text or a disabled input element\n  } else {\n    const attribute = accountOnFile.findAttribute(field.id);\n    if (attribute) {\n      // render field with attribute.value as initial value\n    } else {\n      // render field as usual\n    }\n  }\n}\n```\n\nWhen creating a `PaymentRequest`, make sure to set not only the payment product but also the account on file:\n\n```typescript\nconst paymentRequest = new PaymentRequest();\npaymentRequest.setPaymentProduct(paymentProduct);\npaymentRequest.setAccountOnFile(accountOnFile);\n// Read-only fields like the cardNumber should not be set\n// The cvv is usually not stored in an account on file\n// The expiryDate is usually editable because it changes every time a new card is issued\npaymentRequest.setValue(\"cvv\", \"123\");\npaymentRequest.setValue(\"expiryDate\", \"12/99\");\n```\n\n### Server-side rendering support\n\nIn case you perform server-side rendering, and the payment product or payment product group is already available, it's possible to set this on a `Session` object:\n\n```typescript\nsession.setProvidedPaymentItem({\n  id: 1,\n  ...\n});\n```\n\nWhenever this payment product or payment product group is retrieved, the Worldline Connect Client API will not be queried, but the provided value will be returned instead.\n\n\u003e The value should be provided as returned by the Worldline Connect Client API or the Worldline Connect Server API. The SDK will convert this as necessary.\n\n### Non-browser support\n\nThe official SDK cannot be used outside of browsers, because it relies on browser mechanics like [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) and `window`.\\\nBy default this SDK also doesn't work outside of browsers. However, it's possible to replace the browser specifics with a custom implementation of [Device](https://robtimus.github.io/connect-client-sdk-ts/interfaces/ext.Device.html). This consists of:\n\n* An [HttpClient](https://robtimus.github.io/connect-client-sdk-ts/interfaces/ext_http.HttpClient.html). [fetchHttpClient](https://robtimus.github.io/connect-client-sdk-ts/variables/ext_impl_http_fetch.fetchHttpClient.html) can be used, or a custom implementation can be created.\n* [DeviceInformation](https://robtimus.github.io/connect-client-sdk-ts/interfaces/ext.DeviceInformation.html) that describes some device-specifics. This is used for metadata that's sent to the Worldline Connect Client API, as well as encrypted customer input.\n* Optionally, an [ApplePayClient](https://robtimus.github.io/connect-client-sdk-ts/interfaces/ext.ApplePayClient.html) and [GooglePayClient](https://robtimus.github.io/connect-client-sdk-ts/interfaces/ext.GooglePayClient.html). If either one is not available, the matching payment product will be filtered out.\n\nWhen you've created a custom `Device`, provide it when creating a `Session` object:\n\n```typescript\nconst device = ...;\nconst session = new Session(sessionDetails, paymentContext, device);\n```\n\n## API\n\nThe API can be found [here](https://robtimus.github.io/connect-client-sdk-ts/modules/index.html).\n\n### [Differences from the Worldline Connect Client API](https://github.com/robtimus/connect-client-sdk-ts/wiki/Differences-from-the-Worldline-Connect-Client-API)\n\n## Requirements\n\n### Browsers\n\nThe following are the minimum supported browsers:\n\n| Browser             | Min version |\n|---------------------|-------------|\n| Chrome              | 74+         |\n| Edge                | 79+         |\n| Safari              | 14.1+       |\n| Firefox             | 90+         |\n| Opera               | 62+         |\n| Chrome for Android  | 113+        |\n| Safari on iOS       | 14.5+       |\n| Opera Mobile        | 73+         |\n| Android Browser     | 113+        |\n| Firefox for Android | 113+        |\n\nInternet Explorer and older versions of these browser can become supported by using a polyfill like [core-js](https://www.npmjs.com/package/core-js).\n\nIf the Web Crypto API is not available, it's possible to use [node-forge](https://www.npmjs.com/package/node-forge) instead. For instance:\n\n```typescript\nimport { forgeCryptoEngine } from \"@robtimus/connect-client-sdk/dist/ext/impl/crypto/forge\";\nimport { webCryptoCryptoEngine } from \"@robtimus/connect-client-sdk/dist/ext/impl/crypto/WebCrypto\";\n\nSession.defaultCryptoEngine = webCryptoCryptoEngine ?? forgeCryptoEngine;\n\n// create session as usual\n```\n\nWhen using UMD, this is done automatically when using `connect-client-sdk.forge.umd.js` instead of `connect-client-sdk.umd.js`:\n\n```html\n\u003cscript src=\"./node_modules/@robtimus/connect-client-sdk/dist/connect-client-sdk.forge.umd.js\"\u003e\u003c/script\u003e\n```\n\n### Node.js\n\nNode.js 16 or higher is required.\n\n## Building the repository\n\nFrom the root of the project install all dependencies, then compile the code:\n\n```\nnpm ci\nnpm run build\n# optional:\nnpm run typedoc\n```\n\n## Testing\n\nThere are three types of tests:\n\n1. Unit tests. These will work out-of-the-box.\\\n   Run these tests as follows:\n\n    ```\n    npm run test\n    ```\n2. Integration tests. Before you can run these, you first need to copy file `test/config.json.dist` to `test/config.json` and replace all values as needed.\\\n   Run these tests as follows:\n\n    ```\n    npm run test:integration\n    ```\n3. Selenium (in-browser) tests. Before you can run these, you first need to copy file `test/config.json.dist` to `test/config.json` and replace all values as needed.\\\n   Run these tests as follows:\n\n    ```\n    npm run test:selenium\n    ```\n\nYou can also run all these types of tests together as follows:\n\n    npm run test:all\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtimus%2Fconnect-client-sdk-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtimus%2Fconnect-client-sdk-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtimus%2Fconnect-client-sdk-ts/lists"}