diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 3ac7a8a..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,55 +0,0 @@ -# https://circleci.com/docs/2.0/configuration-reference/ -version: 2 -jobs: - - test: - docker: - - image: cimg/node:lts - working_directory: ~/repo - steps: - - checkout - - restore_cache: - keys: - - v1-dependencies-{{ checksum "package.json" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - run: yarn install - - save_cache: - paths: - - node_modules - key: v1-dependencies-{{ checksum "package.json" }} - - run: yarn lint && yarn test - - persist_to_workspace: - root: ~/repo - paths: . - - deploy: - docker: - - image: cimg/node:lts - working_directory: ~/repo - steps: - - attach_workspace: - at: ~/repo - - run: - name: Authenticate with registry - command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc - - run: - name: Publish package - command: npm publish --access public - -workflows: - version: 2 - build-deploy: - jobs: - - test: - filters: - tags: - only: /^v.*/ - - deploy: - requires: - - test - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ diff --git a/.fernignore b/.fernignore new file mode 100644 index 0000000..084a8eb --- /dev/null +++ b/.fernignore @@ -0,0 +1 @@ +# Specify files that shouldn't be modified by Fern diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index f8b8ed9..0000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,17 +0,0 @@ -## Expected Behavior - - -## Actual Behavior - - -## Steps to Reproduce the Problem - - 1. - 1. - 1. - -## Specifications - - - Version: - - Platform: - - Subsystem: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 0d98733..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,27 +0,0 @@ -## Description of the change - -> Description here - -## Type of change -- [ ] Bug fix (non-breaking change that fixes an issue) -- [ ] New feature (non-breaking change that adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - -## Related issues - -> Fix [#1]() - -## Checklists - -### Development - -- [ ] Lint rules pass locally -- [ ] The code changed/added as part of this pull request has been covered with tests -- [ ] All tests related to the changed code pass in development - -### Code review - -- [ ] This pull request has a descriptive title and information useful to a reviewer. There may be a screenshot or screencast attached -- [ ] "Ready for review" label attached to the PR and reviewers mentioned in a comment -- [ ] Changes have been reviewed by at least one other engineer -- [ ] Issue from task tracker has a link to this pull request diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e2b82d1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: ci + +on: [push] + +jobs: + compile: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Compile + run: yarn && yarn build + + publish: + needs: [ compile ] + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Install dependencies + run: yarn install + + - name: Build + run: yarn build + + - name: Publish to npm + run: | + npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} + npm publish --access public + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 331f2c9..66afc72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,66 +1,12 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -# next.js build output -.next - -# Ignore JS files in src -/src/**/*.js - -/lib \ No newline at end of file +node_modules +.DS_Store +/dist +/Client.d.ts +/Client.js +/environments.d.ts +/environments.js +/index.d.ts +/index.js +/api +/core +/errors \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..e62938d --- /dev/null +++ b/.npmignore @@ -0,0 +1,8 @@ +node_modules +src +.gitignore +.github +.fernignore +.prettierrc.yml +tsconfig.json +yarn.lock \ No newline at end of file diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 0000000..0c06786 --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,2 @@ +tabWidth: 4 +printWidth: 120 diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 16d05dc..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,321 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -This project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased][unreleased] - -## [v4.1.1] - 2023-02-02 - -- fix audience put request - -## [v4.1.0] - 2022-10-21 - -- adds support for invoke step via `client.automations.invokeAdHocAutomation({...})` - -## [v4.0.2] - 2022-10-19 - -- Fix `unexpected error` in Node 18.x -- Fix baseURLs getting chopped off - -## [v4.0.1] - 2022-10-13 - -- resolves `FetchError: invalid json response body` for API's returning no body - -## [v4.0.0] - -- Migrate from Axios to fetch - -## [3.16.0] - -- adds support for idempotency expiry to be passed in profiles and brands POST - -## [3.15.0] - -- adds support for audit events - -## [3.14.0] - -- adds support for token management - -## [3.13.1] - 2022-06-03 - -- adds provider and channel timeout - -## [3.12.0] - 2022-03-31 - -- adds support for message trace id (`message.metadata.trace_id`) - -## [3.11.0] - 2022-03-23 - -- adds support for `audiences` - -## [3.10.1] - 2022-03-20 - -- adds support for messages timeout (`message.timeout`) - -## [3.10.0] - 2020-03-24 - -- adds support for messages brand_id (`message.brand_id`) - -## [3.9.0] - 2022-03-17 - -- adds support for bulk messaging API v2 support - -## [3.8.0] - 2022-03-14 - -- adds additional types for utm property (`message.metadata.utm`) - -## [v3.7.0] - 2022-03-11 - -- adds additional types for the tags property (`message.metadata.tags`) -- adds support for searching message by tags - -## [v3.6.0] - 2022-02-10 - -- adds additional types for the recipient property (`message.to`) - -## [v3.5.0] - 2022-02-10 - -- adds type for unroutable status - -## [v3.4.0] - 2022-01-25 - -- adds support for the send message object in the request body of a `/send` call - -## [v3.3.0] - 2022-01-25 - -- adds support for bulk processing endpoints - -## [v3.2.1] - 2022-01-13 - -- Fixes `getMessages` query params - -## [v3.2.0] - 2021-11-18 - -- adds idempotency expiration support for send and send list endpoints - -## [v3.1.0] - 2021-11-16 - -- Expose additional type definitions for `getMessage` - -## [v3.0.0] - 2021-11-02 - -- fixes type definition for `getRecipientSubscriptions` - -## [v2.8.0] - 2021-10-29 - -- adds GET /messages/{messageId}/output API - -## [v2.7.0] - 2021-10-21 - -- adds GET /messages/{messageId}/history API - -## [v2.6.0] - 2021-10-07 - -- Add support for DELETE /profiles/{recipient_id} (#58) -- adds GET /messages API -- adds idempotencyKey support in automations client - -## [v2.4.0] - 2021-08-23 - -- adds notifications API -- type fix `put` method of `ICourierClientLists` - -## [v2.3.0] - 2021-04-28 - -- adds support for update-profile step via `client.automations.invokeAdHocAutomation({...})` - -## [v2.2.0] - 2021-04-07 - -- adds automations API - -## [v2.1.0] - 2021-03-15 - -- adds support to add more recipients to a list subscription (#40) -- adds support to delete all the lists subscriptions for a recipient (#39) -- adds support to add recipient to multiple lists (#38) -- updates preference interface to accept new preference options (#37) - -## [v2.0.0] - 2021-03-03 - -- supports adding subscription preferences (#35) - -## [v1.7.3] - 2021-03-03 - -### Added - -- ICourierClient exported as a type [#33](https://github.com/trycourier/courier-node/pull/33) - -## [v1.7.2] - 2021-02-16 - -### Fixed - -- Update PUT list subscription request params with appropriate type [#32](https://github.com/trycourier/courier-node/pull/32) - -## [v1.7.1] - 2021-02-01 - -### Fixed - -- Fix the notification(s) typo [#28](https://github.com/trycourier/courier-node/pull/28) - -## [v1.7.0] - 2021-01-25 - -### Added - -- Support for [Preferences API]() by @helenamerk and @aydrian - - `GET /preferences` via `client.preferences.list()` - - `GET /preferences/{recipient_id}` via `client.preferences.get(recipientId)` - - `PUT /preferences/{recipient_id}` via `client.preferences.put(recipientId, {...})` - -## [v1.6.2] - 2021-01-19 - -### Fixed - -- Bumped [axios](https://www.npmjs.com/package/axios) to version 0.21.1 -- Updated types for Send to List Parameters by @rileylnapier - -## [v1.6.1] - 2020-09-23 - -### Fixed - -- Fixed return types for `PUT` methods that return 204 -- Fixed param types for `client.lists.send()` -- Fixed return type for `client.lists.findByRecipientId()` -- Fixed param types for `client.lists.put()` - -## [v1.6.0] - 2020-09-22 - -### Added - -- Support for `idempotencyKey` for `POST` methods by @aydrian & @rileylnapier -- Support for [Lists API](https://docs.courier.com/reference/lists-api) by @aydrian - - `POST /send/list` via `client.lists.send(params, config)` - - `GET /profiles/{recipient_id}/lists` via `client.lists.findByRecipientId(recipientId, params)` - - `GET /lists` via `client.lists.list(params)` - - `GET /lists/{list_id}` via `client.lists.get(listId)` - - `PUT /lists/{list_id}` via `client.lists.put(listId, {...})` - - `DELETE /lists/{list_id}` via `client.lists.delete(listId)` - - `PUT /lists/{list_id}/restore` via `client.lists.restore(listId)` - - `GET /lists/{list_id}/subscriptions` via `client.lists.getSubscriptions(listId)` - - `PUT /lists/{list_id}/subscriptions` via `client.lists.putSubscriptions(listId, [recipientId], config)` - - `PUT /lists/{list_id}/subscriptions/{recipient_id}` via `client.lists.subscribe(listId, recipientId)` - - `DELETE /lists/{list_id}/subscriptions/{recipient_id}` via `client.lists.unsubscribe(listId, recipientId)` - -### Changed - -- Default `base_url` is now `api.courier.com` - -## [v1.5.0] - 2020-07-08 - -### Added - -- Support for [Brands API](https://docs.courier.com/reference/brands-api) by @aydrian - - `GET /brands` via `client.getBrands(params)` - - `GET /brands/:brand_id` via `client.getBrand(brandId)` - - `POST /brands` via `client.createBrand({…})` - - `PUT /brands/:brand_id` via `client.replaceBrand({…})` - - `DELETE /brands/:brand_id` via `client.deleteBrand(brandId)` -- Support for specifying notification brand during [send](https://docs.courier.com/reference/send-api#sendmessage) by @aydrian - -## [v1.4.0] - 2020-06-29 - -### Added - -- Support `GET /messages/:messageId` via `client.getMessage(messageId)` @rileylnapier - -## [v1.3.0] - 2020-03-10 - -### Added - -- Support credential storage using `COURIER_AUTH_TOKEN` environment variable by @aydrian -- Support setting base url using `COURIER_BASE_URL` environment variable by @aydrian -- Support preferences and override in send method by @aydrian -- Create GitHub Issue and Pull Request templates by @rileylnapier - -### Changed - -- Updated user agent string to match new standard by @aydrian - -## [v1.2.1] - 2019-12-30 - -### Fixed - -- Convert package.json import to a require by @@scarney81 - -## [v1.2.0] - 2019-12-20 - -## Added - -- Custom user agent string by @aydrian - -## [v1.1.6] - 2019-07-12 - -## [v1.1.5] - 2019-07-12 - -## [v1.1.4] - 2019-07-12 - -## [v1.1.3] - 2019-07-12 - -## [v1.1.2] - 2019-07-12 - -## [v1.1.1] - 2019-07-12 - -## [v1.1.0] - 2019-07-12 - -## [v1.0.4] - 2019-07-12 - -## [v1.0.3] - 2019-07-12 - -## [v1.0.2] - 2019-07-12 - -## v1.0.1 - 2019-07-12 - -[unreleased]: https://github.com/trycourier/courier-node/compare/v4.1.1...HEAD -[v4.1.1]: https://github.com/trycourier/courier-node/compare/v4.1.1...v4.1.0 -[v4.0.2]: https://github.com/trycourier/courier-node/compare/v4.0.1...v4.0.2 -[v4.0.1]: https://github.com/trycourier/courier-node/compare/v4.0.0...v4.0.1 -[v4.0.0]: https://github.com/trycourier/courier-node/compare/v3.16.0...v4.0.0 -[v3.11.0]: https://github.com/trycourier/courier-node/compare/v3.10.0...v3.11.0 -[v3.10.0]: https://github.com/trycourier/courier-node/compare/v3.9.0...v3.10.0 -[v3.9.0]: https://github.com/trycourier/courier-node/compare/v3.8.0...v3.9.0 -[v3.8.0]: https://github.com/trycourier/courier-node/compare/v3.7.0...v3.8.0 -[v3.7.0]: https://github.com/trycourier/courier-node/compare/v3.6.0...v3.7.0 -[v3.6.0]: https://github.com/trycourier/courier-node/compare/v3.5.0...v3.6.0 -[v3.5.0]: https://github.com/trycourier/courier-node/compare/v3.4.0...v3.5.0 -[v3.4.0]: https://github.com/trycourier/courier-node/compare/v3.3.0...v3.4.0 -[v3.3.0]: https://github.com/trycourier/courier-node/compare/v3.2.1...v3.3.0 -[v3.2.1]: https://github.com/trycourier/courier-node/compare/v3.2.0...v3.2.1 -[v3.2.0]: https://github.com/trycourier/courier-node/compare/v3.1.0...v3.2.0 -[v3.1.0]: https://github.com/trycourier/courier-node/compare/v3.0.0...v3.1.0 -[v3.0.0]: https://github.com/trycourier/courier-node/compare/v2.8.0...v3.0.0 -[v2.8.0]: https://github.com/trycourier/courier-node/compare/v2.7.0...v2.8.0 -[v2.7.0]: https://github.com/trycourier/courier-node/compare/v2.6.0...v2.7.0 -[v2.6.0]: https://github.com/trycourier/courier-node/compare/v2.4.0...v2.6.0 -[v2.4.0]: https://github.com/trycourier/courier-node/compare/v2.3.0...v2.4.0 -[v2.3.0]: https://github.com/trycourier/courier-node/compare/v2.2.0...v2.3.0 -[v2.2.0]: https://github.com/trycourier/courier-node/compare/v2.1.0...v2.2.0 -[v2.1.0]: https://github.com/trycourier/courier-node/compare/v2.0.0...v2.1.0 -[v2.0.0]: https://github.com/trycourier/courier-node/compare/v1.7.3...v2.0.0 -[v1.7.3]: https://github.com/trycourier/courier-node/compare/v1.7.2...v1.7.3 -[v1.7.2]: https://github.com/trycourier/courier-node/compare/v1.7.1...v1.7.2 -[v1.7.1]: https://github.com/trycourier/courier-node/compare/v1.7.0...v1.7.1 -[v1.7.0]: https://github.com/trycourier/courier-node/compare/v1.6.2...v1.7.0 -[v1.6.2]: https://github.com/trycourier/courier-node/compare/v1.6.1...v1.6.2 -[v1.6.1]: https://github.com/trycourier/courier-node/compare/v1.6.0...v1.6.1 -[v1.6.0]: https://github.com/trycourier/courier-node/compare/v1.5.0...v1.6.0 -[v1.5.0]: https://github.com/trycourier/courier-node/compare/v1.4.0...v1.5.0 -[v1.4.0]: https://github.com/trycourier/courier-node/compare/v1.3.0...v1.4.0 -[v1.3.0]: https://github.com/trycourier/courier-node/compare/v1.2.1...v1.3.0 -[v1.2.1]: https://github.com/trycourier/courier-node/compare/v1.2.0...v1.2.1 -[v1.2.0]: https://github.com/trycourier/courier-node/compare/v1.1.6...v1.2.0 -[v1.1.6]: https://github.com/trycourier/courier-node/compare/v1.1.5...v1.1.6 -[v1.1.5]: https://github.com/trycourier/courier-node/compare/v1.1.4...v1.1.5 -[v1.1.4]: https://github.com/trycourier/courier-node/compare/v1.1.3...v1.1.4 -[v1.1.3]: https://github.com/trycourier/courier-node/compare/v1.1.2...v1.1.3 -[v1.1.2]: https://github.com/trycourier/courier-node/compare/v1.1.1...v1.1.2 -[v1.1.1]: https://github.com/trycourier/courier-node/compare/v1.1.0...v1.1.1 -[v1.1.0]: https://github.com/trycourier/courier-node/compare/v1.0.4...v1.1.0 -[v1.0.4]: https://github.com/trycourier/courier-node/compare/v1.0.3...v1.0.4 -[v1.0.3]: https://github.com/trycourier/courier-node/compare/v1.0.2...v1.0.3 -[v1.0.2]: https://github.com/trycourier/courier-node/compare/v1.0.1...v1.0.2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 830883a..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,30 +0,0 @@ -# Contributing - -PR's welcome: - -https://github.com/trycourier/courier-node - -# Testing - -```bash -yarn lint && yarn test -``` - -## Code Style/Formatting - -```bash -yarn format -``` - -## Releasing New Versions - -https://www.npmjs.com/package/@trycourier/courier - -Make sure you have incremented the version string in `package.json` to your new version string, hereafter referred to as `` and merged that commit. Then: - -```bash -git tag -a v -m v -git push origin v -``` - -Note: We use NPM Automation token (https://docs.npmjs.com/creating-and-viewing-access-tokens) to publish the package. The token exists in Circle CI environment. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 4e8b94c..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Courier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 5b00e12..0000000 --- a/README.md +++ /dev/null @@ -1,866 +0,0 @@ -[![Courier: Your Complete Communication Stack](https://marketing-assets-public.s3.us-west-1.amazonaws.com/github_nodejs.png)](https://courier.com) - -[![npm version](https://badge.fury.io/js/%40trycourier%2Fcourier.svg)](https://badge.fury.io/js/%40trycourier%2Fcourier) - -This is the official node.js module for sending notifications with node.js with the [Courier](https://courier.com) REST API. - -[Courier docs](https://docs.courier.com/docs) • [3 Different Ways To Send Emails With Node.js](https://www.courier.com/blog/how-to-send-emails-with-node-js?utm_campaign=General-Content-Distribution&utm_source=github&utm_medium=node-sdk) - -## Installation (via [npm](https://www.npmjs.com/package/@trycourier/courier)) - -```bash -npm install @trycourier/courier -``` - -## Requirements - -You will need to get a Courier API key to get started. You can sign up and create one for free at [courier.com](https://courier.com). - -## Upgrade Guides - -### v3 to v4 - -v4 uses native fetch client to make requests or falls back to a polyfill if the client doesn't exist in the environment it's running in. Check [Error Handling](#Error-Handling) out. - -## Getting Started - -```javascript -const { CourierClient } = require("@trycourier/courier"); - -const courier = CourierClient({ authorizationToken: "" }); // get from the Courier UI - -// Example: send a basic message to an email recipient -const { requestId } = await courier.send({ - message: { - to: { - data: { - name: "Marty", - }, - email: "marty_mcfly@email.com", - }, - content: { - title: "Back to the Future", - body: "Oh my {{name}}, we need 1.21 Gigawatts!", - }, - routing: { - method: "single", - channels: ["email"], - }, - }, -}); - -// Example: send a basic message to an sms recipient -const { requestId } = await courier.send({ - message: { - to: { - data: { - name: "Jenny", - }, - phone_number: "8675309", - }, - content: { - title: "Back to the Future", - body: "Oh my {{name}}, we need 1.21 Gigawatts!", - }, - routing: { - method: "single", - channels: ["sms"], - }, - }, -}); - -// Example: send a message to various recipients -const { requestId } = await courier.send({ - message: { - to: [ - { - user_id: "", // usually your system's User ID associated to a Courier profile - email: "test@email.com", - data: { - name: "some user's name", - }, - }, - { - email: "marty@email.com", - data: { - name: "Marty", - }, - }, - { - email: "doc_brown@email.com", - data: { - name: "Doc", - }, - }, - { - phone_number: "8675309", - data: { - name: "Jenny", - }, - }, - ], - content: { - title: "Back to the Future", - body: "Oh my {{name}}, we need 1.21 Gigawatts!", - }, - routing: { - method: "all", - channels: ["sms", "email"], - }, - }, -}); - -// Example: send a message supporting email & SMS -const { requestId } = await courier.send({ - message: { - template: "", // get from the Courier UI - to: { - user_Id: "", // usually your system's User ID - email: "example@example.com", - phone_number: "555-228-3890", - }, - data: {}, // optional variables for merging into templates - }, -}); - -// Example: send a message to a list -const { requestId } = await courier.send({ - message: { - template: "", // get from the Courier UI - to: { - list_id: "", // e.g. your Courier List Id - }, - data: {}, // optional variables for merging into templates - }, -}); - -// Example: send a message to a pattern -const { requestId } = await courier.send({ - message: { - template: "", // get from the Courier UI - to: { - list_pattern: "", // e.g. example.list.* - }, - data: {}, // optional variables for merging into templates - }, -}); - -// Example: send a message to a list, pattern and user -const { requestId } = await courier.send({ - message: { - to: [ - { - list_pattern: "", // e.g. example.list.* - }, - { - list_id: "", // e.g. your Courier List Id - }, - { - email: "test@email.com" - } - ] - }, - routing: { - method: "single", - channels: ["email"], - }, - }, -}); - -// Example: send a basic message that expires after the specified timeout -const { requestId } = await courier.send({ - message: { - to: { - data: { - name: "Marty", - }, - email: "marty_mcfly@email.com", - }, - content: { - title: "Back to the Future", - body: "Oh my {{name}}, we need 1.21 Gigawatts!", - }, - routing: { - method: "single", - channels: ["email"], - }, - timeout: { - message: 3600000 // 1 hour in milliseconds - }, - }, -}); - -// Example: send a basic message with a trace id -const { requestId } = await courier.send({ - message: { - to: { - data: { - name: "Marty", - }, - email: "marty_mcfly@email.com", - }, - content: { - title: "Back to the Future", - body: "Oh my {{name}}, we need 1.21 Gigawatts!", - }, - routing: { - method: "single", - channels: ["email"], - }, - metadata: { - trace_id: "ravenclaw-for-the-win" - }, - }, -}); -``` - -## Environment Variables - -`courier-node` supports credential storage in environment variables. If no `authorizationToken` is provided when instantiating the Courier client (e.g., `const courier = CourierClient();`), the value in the `COURIER_AUTH_TOKEN` env var will be used. - -If you need to use a base url other than the default https://api.courier.com, you can set it using the `COURIER_BASE_URL` env var. - -## Advanced Usage - -```javascript -const { CourierClient } = require("@trycourier/courier"); - -const courier = CourierClient({ authorizationToken: "" }); - -async function run() { - // Example: send a message - const { requestId } = await courier.send({ - message: { - template: "", - to: { - // optional - user_id: "", - }, - data: {}, // optional - brand_id: "", //optional - routing: {}, - channels: {}, // optional - providers: {}, // optional - }, - }); - console.log(requestId); - - // Example: send message with utm metadata - const { requestId } = await courier.send({ - message: { - template: "", - to: {...}, - routing: { - method: "single", - channels: ["email"], - }, - channels: { - email: { - routing_method: "all", - providers: ["sendgrid", "sns"], - metadata: { - utm: { - medium: "f", - campaign: "g", - }, - }, - }, - }, - providers: { - sns: { - metadata: { - utm: { - medium: "h", - }, - }, - }, - }, // optional - metadata: { - utm: { - source: "a", - medium: "b", - campaign: "c", - }, - }, - timeout: { - message: 300000, - channel: { - email: 1000 // 1 second - } - } - }, - }); - -/** - * If the template or content contains any action blocks, the hyperlinks will be augmented with utm compliant query parameters. - * - * The resulting link of an action block sent through sendgrid would be: - * www.example.com?utm_source=a&utm_medium=f&utm_campaign=g - * - * While the resulting link of an action block sent through sns would be: - * www.example.com?utm_source=a&utm_medium=h&utm_campaign=g - * - * Notice that provider metadata supersedes channel metadata and channel metadata supersedes message metadata - * - **/ - -/** - * If the message includes a timeout property we will start timing out messages after the first attempt. - * We are able to timeout complete channels or specific providers. - **/ - - // Example: get a message status - const messageStatus = await courier.getMessage(requestId); - console.log(messageStatus); - - // Example: get a message history - const { results } = await courier.getMessageHistory(requestId); - console.log(results); - - // Example: get a message output - const { results } = await courier.getMessageOutput(requestId); - console.log(results); - - // Example: get all messages - const { paging, results } = await courier.getMessages(); - console.log(results); - - // Example: replace a recipient's profile - const { status: replaceStatus } = await courier.replaceProfile({ - recipientId: "", - profile: { - email: "example@example.com", - }, - }); - console.log(replaceStatus); - - // Example: merge into a recipient's profile - const { status: mergeStatus } = await courier.mergeProfile({ - recipientId: "", - profile: { - sms: "555-555-5555", - }, - }); - console.log(mergeStatus); - - // Example: get a recipient's profile - const { profile } = await courier.getProfile({ - recipientId: "", - }); - console.log(profile); - - // Example: get all brands - const { paging, results } = await courier.getBrands({ - cursor: "", // optional - }); - console.log(results); - - // Example: get a specific brand - const brand = await courier.getBrand(""); - console.log(brand); - - // Example: create a brand - const newBrand = await courier.createBrand({ - name: "My Brand", - settings: { - colors: { - primary: "#0000FF", - secondary: "#FF0000", - tertiary: "#00FF00", - }, - }, - }); - console.log(newBrand); - - // Example: replace a brand - const replacedBrand = await courier.replaceBrand({ - id: "", - name: "My New Brand", - settings: { - color: { - primary: "#FF0000", - secondary: "#00FF00", - tertiary: "#0000FF", - }, - }, - }); - console.log(replacedBrand); - - // Example: delete a brand - await courier.deleteBrand(""); - - // Example: get all lists - const { paging, items } = await courier.lists.list({ - cursor: "", // optional - }); - console.log(items); - - // Example: get a specific list - const list = await courier.lists.get(""); - console.log(list); - - // Example: create or replace a list - const replacedList = await courier.lists.put("", { - name: "My New List", - }); - console.log(replacedList); - - // Example: delete a list - await courier.lists.delete(""); - - // Example: restore a list - await courier.lists.restore(""); - - // Example: get a list's subscriptions - const { paging, items } = await courier.lists.getSubscriptions(""); - console.log(items); - - // Example: replace many recipients to a new or existing list - await courier.lists.putSubscriptions("", [ - { recipientId: "RECIPIENT_ID_1" }, - { recipientId: "RECIPIENT_ID_2" }, - ]); - - // Example: subscribe single recipient to a new or existing list - const { recipient } = courier.lists.subscribe("", ""); - console.log(recipient); - - // Example: unsubscribe recipient from list - await courier.lists.unsubscribe("", ""); - - // Example: get a recipient's subscribed lists - const { paging, items } = await courier.lists.findByRecipientId( - "" - ); - console.log(items); - - // Example: Automation Ad-Hoc Invoke - const { runId } = await courier.automations.invokeAdHocAutomation({ - automation: { - cancelation_token: "I_AM_TOKEN", - steps: [ - { - action: "send", - }, - ], - }, - brand: "BRAND_ID", - data: { - example: "EXAMPLE_DATA", - }, - profile: { - email: "foo@bar.com", - }, - recipient: "RECIPIENT_ID", - template: "TEMPLATE_NAME_OR_ID", - }); - console.log(runId); - - // Example: Automation Invoke Template - const { runId } = await courier.automations.invokeAutomationTemplate({ - templateId: "AUTOMATION_TEMPLATE_ID", - brand: "BRAND_ID", - data: { - example: "EXAMPLE_DATA", - }, - profile: { - email: "foo@bar.com", - }, - recipient: "RECIPIENT_ID", - template: "TEMPLATE_NAME_OR_ID", - }); - console.log(runId); - - // Example: List notifications - const { paging, results } = await courier.notifications.list({}); - console.log(results); - - // Example: Get notification content - const { blocks, channels } = await courier.notifications.getContent( - "notification1" - ); - console.log(blocks); - console.log(channels); - - // Example: Get notification draft content - const { blocks, channels } = await courier.notifications.getDraftContent( - "notification1" - ); - console.log(blocks); - console.log(channels); - - // Example: Post notification variations - await courier.notifications.postVariations("notification1", { - blocks: [ - { - id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6", - type: "text", - locales: { - fr_FR: "block fr 1", - }, - }, - { - id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2", - type: "text", - locales: { - fr_FR: "block fr 2", - }, - }, - ], - channels: [ - { - id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e", - type: "email", - locales: { - fr_FR: { - subject: "French Subject", - }, - }, - }, - { - id: "channel_2c2aad1c-30f0-4a55-8d8f-d213f32147bc", - type: "push", - locales: { - fr_FR: { - title: "French Title", - }, - }, - }, - ], - }); - - // Example: Post notification draft variations - await courier.notifications.postDraftVariations("notification1", { - blocks: [ - { - id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6", - type: "text", - locales: { - fr_FR: "block fr 1", - }, - }, - { - id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2", - type: "text", - locales: { - fr_FR: "block fr 2", - }, - }, - ], - channels: [ - { - id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e", - type: "email", - locales: { - fr_FR: { - subject: "French Subject", - }, - }, - }, - { - id: "channel_2c2aad1c-30f0-4a55-8d8f-d213f32147bc", - type: "push", - locales: { - fr_FR: { - title: "French Title", - }, - }, - }, - ], - }); - - // Example: Get notification submission checks - const { checks } = await courier.notifications.getSubmissionChecks( - "notification1", - "submission1" - ); - console.log(checks); - - // Example: Put notification submission checks - const { checks } = await courier.notifications.putSubmissionChecks( - "notification1", - "submission1", - { - checks: [ - { - id: "check1", - status: "RESOLVED", - type: "custom", - }, - ], - } - ); - console.log(checks); - - // Example: Cancel notification submission - await courier.notifications.cancelSubmission("notification1", "submission1"); - - // Bulk Processing - // Example: create a job (API v1 semantics) - const response = await courier.bulk.createJob({ - message: { - event: "RR4NDQ7NZ24A8TKPWVBEDGE15E9A", - }, - }); - console.log(response); - - // Example: create a job (API v2 semantics) - const response = await courier.bulk.createJob({ - message: { - message: { - template: "RR4NDQ7NZ24A8TKPWVBEDGE15E9A", - }, - }, - }); - console.log(response); - - // Example: get a job - const response = await courier.bulk.getJob({ - jobId: "1-61efe386-6ff57552409e311b7a1f371f", - }); - console.log(response); - - // Example: Ingest users in a job (API v1 semantics) - const response = await courier.bulk.ingestUsers({ - jobId: "1-61efe386-6ff57552409e311b7a1f371f", - users: [ - { - profile: { - email: "tejas@courier.com", - }, - }, - ], - }); - console.log(response); - - // Example: Ingest users in a job (API v2 semantics) - const response = await courier.bulk.ingestUsers({ - jobId: "1-61efe386-6ff57552409e311b7a1f371f", - users: [ - { - to: { - email: "tejas@courier.com", - }, - }, - ], - }); - console.log(response); - - // Example: Run a job - await courier.bulk.runJob({ - jobId: "1-61efe386-6ff57552409e311b7a1f371f", - }); - - // Example: Get user details in a job - const response = await courier.bulk.getJobUsers({ - jobId: "1-61efe386-6ff57552409e311b7a1f371f", - }); - console.log(response); -} - -run(); -``` - -### Error Handling - -This package tries to use the native `fetch` client to make requests or falls back to a polyfill if the client doesn't exist in the environment it's running in. - -All network related promise rejections are not handled in any way. All successfully made requests that produce errors on the server side are resulting in promise rejections with custom `CourierHttpClientError` error type. - -`CourierHttpClientError` extends native `Error` interface with two extra properties: - -- `response`: this is the `fetch` response as is -- `data`: this is the parsed body of the response - -```javascript -// Error handling example -const { - CourierClient, - CourierHttpClientError, -} = require("@trycourier/courier"); - -const courier = CourierClient(); - -try { - await courier.send(/* ... */); -} catch (error) { - if (error instanceof CourierHttpClientError) { - console.log("Failed to send with status code:", error.response.status); - console.log("The Courier response is:", error.data); - console.log("The error message is:", error.message); - } else { - console.log( - "There was a problem making that request. Make sure you are online." - ); - } -} -``` - -### Idempotency - -For `POST` methods, you can supply an `idempotencyKey` in the config parameter to ensure the idempotency of the API Call. We recommend that you use a `V4 UUID` for the key. Keys are eligible to be removed from the system after they're at least 24 hours old, and a new request is generated if a key is reused after the original has been removed. For more info, see [Idempotent Requests](https://docs.courier.com/reference/idempotent-requests) in the Courier documentation. - -```javascript -const { CourierClient } = require("@trycourier/courier"); -import uuid4 from "uuid4"; - -const courier = CourierClient(); -const idempotencyKey = uuid4(); - -async function run() { - const { requestId } = await courier.send( - { - template: "", - to: { - user_id: "", - email: "example@example.com", - phone_number: "555-867-5309", - }, - data: { - world: "JavaScript!", - }, - }, - { - idempotencyKey, - } - ); - console.log(requestId); -} - -run(); -``` - -### Audiences - -Audiences APIs are used to create, get, update, and delete audiences. A Courier Audience is a dynamic group of users (created using Courier's Profile API) that matches a set of criteria. Audience is reactive to changes in the user's profile. As you change user profile using `profiles` API, the audience will be updated accordingly. You will not have to maintain a list of users in your audience. Courier takes care of that for you. If you have potentially large set of users, you first create an audience and then use the audience's id to retrieve the list of users. Once you satified with the calculated list of users, you can use the `audienceId` to send notification using `send` API. - -```ts -// Example: create audience which would allow sending notification to all users that match the given filter criteria -const { audienceId } = await courier.audiences.put({ - id: "", - filter: { - operator: "EQ", - path: "title", - value: "Software Engineer", - }, -}); - -// To retrieve list of members in a given audience, you can use the following: -const { items: audienceMembers } = await courier.audiences.listMembers( - audienceId - cursor: "", // optional -); - -// To send a notification to all users that match the given filter criteria, you can use the following: -const { requestId } = await courier.send({ - message: { - template: "", // This can be inline content as well - to: { - audience_id: audienceId, - }, - data: {}, // optional - brand_id: "", //optional - routing: {}, - channels: {}, // optional - providers: {}, // optional - }, -}); -``` - -### Tenants - -The Tenants API is designed to enable multi-tenant notification workflows. This is useful for defining user to tenant level relationships, especially in the context of B2B applications. - -Use Cases: - -- Sending branded notifications on behalf of an organization -- Creating slack-bots on behalf of an organization - -#### Creating a Tenant - -```ts -const { tenantId } = await courier.tenants.put({ - id: "", - name: "Courier", - user_profile: { - slack: { - access_token: "", - }, - }, -}); -``` - -#### Retrieving a Tenant - -```ts -const account = await courier.tenants.get(""); -``` - -#### Deleting a Tenant - -```ts -await courier.tenants.delete(""); -``` - -#### Listing Tenants - -```ts -const { items: tenants, has_more, next_page } = await courier.tenants.list(); -``` - -### Users - -#### Updating user - -```ts -await courier.users.put("", { - accounts: [{ account_id: "ACCOUNT_ID", profile: { foo: "bar" } }], - profile: { name: "John Doe" }, -}); -``` - -#### Updating user accounts - -```ts -await courier.users.putAccounts("", { - accounts: [{ account_id: "ACCOUNT_ID", profile: { foo: "bar" } }], -}); -``` - -#### Updating user preferences - -Courier currently does not allow creating new topics via the API. You must create topics via the Courier UI. Once a topic is created, you can update a user's preferences for that topic via the API. - -```ts -await courier.users.putUserPreferenceByTopic(mockUserId, "", { - default_status: "OPTED_IN", - status: "OPTED_OUT", -}); -``` - -#### Getting user preferences - -- Get all topic level preferences for a user - -```ts -const { items: userPreferences } = await courier.users.getUserPreferences( - "" -); -``` - -- Get a specific topic level preference for a user - -```ts -const userPreference = await courier.users.getUserPreferenceByTopic( - "", - "" -); -``` - -## License - -[MIT License](http://www.opensource.org/licenses/mit-license.php) - -## Author - -[Courier](https://github.com/trycourier) ([support@courier.com](mailto:support@courier.com)) diff --git a/jestconfig.json b/jestconfig.json deleted file mode 100644 index 9296d5d..0000000 --- a/jestconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "transform": { - "^.+\\.(t|j)sx?$": "ts-jest" - }, - "testRegex": "(/__tests__/(.*|(\\.|/))(test|spec))\\.(jsx?|tsx?)$", - "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"], - "setupFiles": ["./setupJest.ts"] -} diff --git a/package.json b/package.json index ef705fe..4db9eaa 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,26 @@ { - "name": "@trycourier/courier", - "version": "5.7.0", - "description": "A node.js module for communicating with the Courier REST API.", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "files": [ - "lib/**/*" - ], - "homepage": "https://github.com/trycourier/courier-node", - "repository": "git@github.com:trycourier/courier-node.git", - "author": "Courier ", - "license": "MIT", - "devDependencies": { - "@types/jest": "^24.0.15", - "@types/node": "^12.6.2", - "jest": "^24.8.0", - "jest-fetch-mock": "^3.0.3", - "prettier": "^1.18.2", - "ts-jest": "^24.0.2", - "tslint": "^5.18.0", - "tslint-config-prettier": "^1.18.0", - "typescript": "^3.5.3" - }, - "scripts": { - "test": "jest --config jestconfig.json", - "lint": "tslint -p tsconfig.json", - "build": "tsc", - "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", - "prepare": "yarn build", - "prepublishOnly": "yarn lint && yarn test" - }, - "dependencies": { - "cross-fetch": "^3.1.5" - } -} + "name": "@trycourier/courier", + "version": "v6.0.0", + "private": false, + "repository": "https://github.com/trycourier/courier-node", + "main": "./index.js", + "types": "./index.d.ts", + "scripts": { + "format": "prettier --write 'src/**/*.ts'", + "build": "tsc", + "prepack": "cp -rv dist/. ." + }, + "dependencies": { + "url-join": "4.0.1", + "@types/url-join": "4.0.1", + "axios": "0.27.2", + "qs": "6.11.2", + "@types/qs": "6.9.8", + "js-base64": "3.7.2" + }, + "devDependencies": { + "@types/node": "17.0.33", + "prettier": "2.7.1", + "typescript": "4.6.4" + } +} \ No newline at end of file diff --git a/setupJest.ts b/setupJest.ts deleted file mode 100644 index a949736..0000000 --- a/setupJest.ts +++ /dev/null @@ -1,8 +0,0 @@ -import fetchMock from "jest-fetch-mock"; - -jest.setMock("cross-fetch", fetchMock); -jest - .spyOn(globalThis, "fetch") - .mockImplementation((...args) => - fetchMock(...(args as Parameters)) - ); diff --git a/src/Client.ts b/src/Client.ts new file mode 100644 index 0000000..a6b7899 --- /dev/null +++ b/src/Client.ts @@ -0,0 +1,194 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "./environments"; +import * as core from "./core"; +import * as Courier from "./api"; +import urlJoin from "url-join"; +import * as errors from "./errors"; +import { Audiences } from "./api/resources/audiences/client/Client"; +import { AuditEvents } from "./api/resources/auditEvents/client/Client"; +import { AuthTokens } from "./api/resources/authTokens/client/Client"; +import { Automations } from "./api/resources/automations/client/Client"; +import { Brands } from "./api/resources/brands/client/Client"; +import { Bulk } from "./api/resources/bulk/client/Client"; +import { Lists } from "./api/resources/lists/client/Client"; +import { Messages } from "./api/resources/messages/client/Client"; +import { Profiles } from "./api/resources/profiles/client/Client"; +import { Templates } from "./api/resources/templates/client/Client"; +import { Tenants } from "./api/resources/tenants/client/Client"; +import { TokenManagement } from "./api/resources/tokenManagement/client/Client"; +import { Translations } from "./api/resources/translations/client/Client"; +import { UserPreferences } from "./api/resources/userPreferences/client/Client"; + +export declare namespace CourierClient { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class CourierClient { + constructor(protected readonly _options: CourierClient.Options) {} + + /** + * Use the send API to send a message to one or more recipients. + */ + public async send( + request: Courier.SendMessageRequest, + requestOptions?: CourierClient.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/send" + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.SendMessageResponse; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected _audiences: Audiences | undefined; + + public get audiences(): Audiences { + return (this._audiences ??= new Audiences(this._options)); + } + + protected _auditEvents: AuditEvents | undefined; + + public get auditEvents(): AuditEvents { + return (this._auditEvents ??= new AuditEvents(this._options)); + } + + protected _authTokens: AuthTokens | undefined; + + public get authTokens(): AuthTokens { + return (this._authTokens ??= new AuthTokens(this._options)); + } + + protected _automations: Automations | undefined; + + public get automations(): Automations { + return (this._automations ??= new Automations(this._options)); + } + + protected _brands: Brands | undefined; + + public get brands(): Brands { + return (this._brands ??= new Brands(this._options)); + } + + protected _bulk: Bulk | undefined; + + public get bulk(): Bulk { + return (this._bulk ??= new Bulk(this._options)); + } + + protected _lists: Lists | undefined; + + public get lists(): Lists { + return (this._lists ??= new Lists(this._options)); + } + + protected _messages: Messages | undefined; + + public get messages(): Messages { + return (this._messages ??= new Messages(this._options)); + } + + protected _profiles: Profiles | undefined; + + public get profiles(): Profiles { + return (this._profiles ??= new Profiles(this._options)); + } + + protected _templates: Templates | undefined; + + public get templates(): Templates { + return (this._templates ??= new Templates(this._options)); + } + + protected _tenants: Tenants | undefined; + + public get tenants(): Tenants { + return (this._tenants ??= new Tenants(this._options)); + } + + protected _tokenManagement: TokenManagement | undefined; + + public get tokenManagement(): TokenManagement { + return (this._tokenManagement ??= new TokenManagement(this._options)); + } + + protected _translations: Translations | undefined; + + public get translations(): Translations { + return (this._translations ??= new Translations(this._options)); + } + + protected _userPreferences: UserPreferences | undefined; + + public get userPreferences(): UserPreferences { + return (this._userPreferences ??= new UserPreferences(this._options)); + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/__tests__/audiences.test.ts b/src/__tests__/audiences.test.ts deleted file mode 100644 index 267a908..0000000 --- a/src/__tests__/audiences.test.ts +++ /dev/null @@ -1,163 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import * as AudienceTypes from "../audiences/types"; -import { CourierClient } from "../index"; - -const mockAudienceId = "software-engineers-from-sf"; -const mockAudienceName = "List of people who are software engineers"; -const mockFilter: AudienceTypes.FilterConfig = { - operator: "EQ", - path: "title", - value: "Software Engineer" -}; - -const mockPutAudienceResponse: AudienceTypes.IAudiencePutResponse = { - audience: { - created_at: "2020-01-01T00:00:00.000Z", - description: "audience-description", - filter: mockFilter, - id: mockAudienceId, - name: mockAudienceName, - updated_at: "2020-01-01T00:00:00.000Z" - } -}; - -const mockGetAudienceResponse: AudienceTypes.IAudience = { - created_at: "2020-01-01T00:00:00.000Z", - description: "audience-description", - filter: mockFilter, - id: mockAudienceId, - name: mockAudienceName, - updated_at: "2020-01-01T00:00:00.000Z" -}; - -const mockAudienceMembersResponse: AudienceTypes.IAudienceMemberListResponse = { - items: [ - { - added_at: "2022-03-22T19:13:13.137Z", - audience_id: "software-engineers-from-sf", - audience_version: 3, - member_id: "courier-profile-id-1", - reason: "EQ('title', 'Software Engineer') => true" - } - ], - paging: { - cursor: "", - more: false - } -}; - -const mockAudiencesResponse: AudienceTypes.IAudienceListResponse = { - items: [ - { - created_at: "2022-03-21T00:56:14.860Z", - description: "Updated descriptionss", - filter: mockFilter, - id: mockAudienceId, - name: mockAudienceName, - updated_at: "2022-03-21T05:16:57.031Z" - } - ], - paging: { - cursor: "", - more: false - } -}; - -describe("CourierAudiences", () => { - beforeAll(() => { - mockRequests([ - { - method: "PUT", - path: `/audiences/${mockAudienceId}`, - response: { body: mockPutAudienceResponse } - }, - { - method: "DELETE", - path: `/audiences/${mockAudienceId}`, - response: { status: 204 } - }, - { - method: "GET", - path: `/audiences/${mockAudienceId}`, - response: { body: { audience: mockGetAudienceResponse } } - }, - { - method: "GET", - path: `/audiences/${mockAudienceId}/members`, - response: { body: mockAudienceMembersResponse } - }, - { - method: "GET", - path: `/audiences`, - response: { body: mockAudiencesResponse } - } - ]); - }); - - test(".putAudience", async () => { - const { audiences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - audiences.put({ - filter: { - operator: "EQ", - path: "title", - value: "Software Engineer" - }, - id: mockAudienceId, - name: "My favorite software engineers" - }) - ).resolves.toMatchObject(mockPutAudienceResponse.audience); - }); - - test(".getAudience", async () => { - const { audiences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(audiences.get(mockAudienceId)).resolves.toMatchObject( - mockGetAudienceResponse - ); - }); - - test(".listAudiences", async () => { - const { audiences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(audiences.listAudiences()).resolves.toMatchObject( - mockAudiencesResponse - ); - }); - - test(".listMembers", async () => { - const { audiences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(audiences.listMembers(mockAudienceId)).resolves.toMatchObject( - mockAudienceMembersResponse - ); - }); - - test(".listMembers", async () => { - const { audiences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(audiences.listMembers(mockAudienceId)).resolves.toMatchObject( - mockAudienceMembersResponse - ); - }); - - test(".delete", async () => { - const { audiences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(audiences.delete(mockAudienceId)).resolves.not.toThrow(); - }); -}); diff --git a/src/__tests__/audit-events.test.ts b/src/__tests__/audit-events.test.ts deleted file mode 100644 index d43894e..0000000 --- a/src/__tests__/audit-events.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from ".."; -import { IAuditEvent } from "../audit-events/types"; - -const mockAuditEvent: IAuditEvent = { - auditEventId: "foo", - source: "studio", - timestamp: "123", - type: "mock" -}; - -describe("CourierAudiences", () => { - beforeAll(() => { - mockRequests([ - { - method: "GET", - path: "/audit-events", - response: { - body: { paging: { more: false }, results: [mockAuditEvent] } - } - }, - { - method: "GET", - path: "/audit-events/foo", - response: { body: mockAuditEvent } - } - ]); - }); - - const { auditEvents } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - describe("list", () => { - it("resolves with a list of audit events", async () => { - expect.assertions(1); - - const response = await auditEvents.list({}); - expect(response).toMatchObject({ - paging: { more: false }, - results: [mockAuditEvent] - }); - }); - }); - - describe("get", () => { - it("resolves with an audit event", async () => { - expect.assertions(1); - - const response = await auditEvents.get({ auditEventId: "foo" }); - expect(response).toMatchObject(mockAuditEvent); - }); - }); -}); diff --git a/src/__tests__/automations.test.ts b/src/__tests__/automations.test.ts deleted file mode 100644 index b12457a..0000000 --- a/src/__tests__/automations.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from "../index"; -import { ICourierAutomationInvokeResponse } from "../automations/types"; - -const mockAutomationInvokeResponse: ICourierAutomationInvokeResponse = { - runId: "1234" -}; - -describe("CourierAutomations", () => { - beforeAll(() => { - mockRequests([ - { - method: "POST", - path: /\/automations\/(.+\/)?invoke/, - response: { body: mockAutomationInvokeResponse } - } - ]); - }); - - test(".invokeAdHocAutomation", async () => { - const { automations } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - automations.invokeAdHocAutomation( - { - automation: { - cancelation_token: "I_AM_TOKEN", - steps: [ - { - action: "send" - }, - { - action: "cancel" - }, - { - action: "send-list", - list: "my-list" - }, - { - action: "delay" - }, - { - action: "invoke", - template: "my-template", - context: { - brand: "brand-1", - data: { - foo: "bar" - }, - profile: { - email: "foo@bar.com" - }, - recipient: "foobar", - template: "another-template" - } - }, - { - action: "update-profile", - recipient_id: "RECIPIENT_ID", - profile: { - email: "foo@bar.com" - }, - merge: "none" - } - ] - }, - brand: "BRAND_ID", - data: { - example: "EXAMPLE_DATA" - }, - profile: { - email: "foo@bar.com" - }, - recipient: "RECIPIENT_ID", - template: "TEMPLATE_NAME_OR_ID" - }, - { - idempotencyKey: "IDEMPOTENCY_KEY", - // e.g. expiration date in epoch time, 30 mins from now - idempotencyExpiry: Date.now() + 30 * 60 * 1000 - } - ) - ).resolves.toMatchObject(mockAutomationInvokeResponse); - }); - - test(".invokeAutomationTemplate", async () => { - const { automations } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - automations.invokeAutomationTemplate({ - templateId: "AUTOMATION_TEMPLATE_ID", - brand: "BRAND_ID", - data: { - example: "EXAMPLE_DATA" - }, - profile: { - email: "foo@bar.com" - }, - recipient: "RECIPIENT_ID", - template: "TEMPLATE_NAME_OR_ID" - }) - ).resolves.toMatchObject(mockAutomationInvokeResponse); - }); -}); diff --git a/src/__tests__/bulk.test.ts b/src/__tests__/bulk.test.ts deleted file mode 100644 index c238430..0000000 --- a/src/__tests__/bulk.test.ts +++ /dev/null @@ -1,152 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from "../index"; -import { - ICourierBulkCreateJobResponse, - ICourierBulkGetJobResponse, - ICourierBulkGetJobUsersResponse, - ICourierBulkIngestUsersResponse -} from "../bulk/types"; - -const mockCreateJobResponse: ICourierBulkCreateJobResponse = { - jobId: "1-61eb3d79-55abd6f73597a7afc3a6e11d" -}; - -const mockIngestUsersResponse: ICourierBulkIngestUsersResponse = { - total: 1, - errors: [] -}; - -const mockGetJobResponse: ICourierBulkGetJobResponse = { - job: { - definition: { - event: "foo" - }, - enqueued: 1, - failures: 0, - received: 1, - status: "COMPLETED" - } -}; - -const mockGetJobUsersResponse: ICourierBulkGetJobUsersResponse = { - items: [ - { - profile: { - email: "foo@bar.com" - }, - data: { - recipientName: "John Doe" - }, - recipient: "iamC8st6OQVvngG_7ORgP", - status: "ENQUEUED" - } - ], - paging: { - more: false - } -}; - -describe("CourierBulk", () => { - beforeAll(() => { - mockRequests([ - { - method: "POST", - path: "/bulk", - response: { status: 201, body: mockCreateJobResponse } - }, - { - method: "POST", - path: /\/bulk\/.*/, - response: { body: mockIngestUsersResponse } - }, - { - method: "POST", - path: /\/bulk\/.*\/run/, - response: { status: 204 } - }, - { - method: "GET", - path: /\/bulk\/.*\/users/, - response: { body: mockGetJobUsersResponse } - }, - { - method: "GET", - path: /\/bulk\/.*/, - response: { body: mockGetJobResponse } - } - ]); - }); - - test(".createJob", async () => { - const { bulk } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - bulk.createJob({ - message: { - event: "foo" - } - }) - ).resolves.toMatchObject(mockCreateJobResponse); - }); - - test(".ingestUsers", async () => { - const { bulk } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - bulk.ingestUsers({ - jobId: "1-61eb3d79-55abd6f73597a7afc3a6e11d", - users: [ - { - profile: { - email: "foo@bar.com" - }, - data: { - recipientName: "John Doe" - } - } - ] - }) - ).resolves.toMatchObject(mockIngestUsersResponse); - }); - - test(".runJob", async () => { - const { bulk } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - bulk.runJob({ - jobId: "1-61eb3d79-55abd6f73597a7afc3a6e11d" - }) - ).resolves.toBeUndefined(); - }); - - test(".getJob", async () => { - const { bulk } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - bulk.getJob({ - jobId: "1-61eb3d79-55abd6f73597a7afc3a6e11d" - }) - ).resolves.toMatchObject(mockGetJobResponse); - }); - - test(".getJobUsers", async () => { - const { bulk } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - bulk.getJobUsers({ - jobId: "1-61eb3d79-55abd6f73597a7afc3a6e11d" - }) - ).resolves.toMatchObject(mockGetJobUsersResponse); - }); -}); diff --git a/src/__tests__/http-client.test.ts b/src/__tests__/http-client.test.ts deleted file mode 100644 index 67c232f..0000000 --- a/src/__tests__/http-client.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import fetchMock from "jest-fetch-mock"; -import { initHttpClient } from "../http-client"; - -describe("HttpClient", () => { - beforeEach(() => { - fetchMock.resetMocks(); - fetchMock.doMockOnce(); - }); - - test("should have auth token", async () => { - const token = "test-auth-token"; - const client = initHttpClient({ - baseUrl: "", - version: "1", - authorizationToken: token - }); - await client.get("https://api.courier.com/lists/list-1"); - expect(fetchMock.mock.calls.length).toEqual(1); - const expectedAuth = { headers: { Authorization: `Bearer ${token}` } }; - expect(fetchMock.mock.calls[0][1]).toMatchObject(expectedAuth); - }); - - test("should URI encode values", async () => { - const client = initHttpClient({ - baseUrl: "", - version: "1", - authorizationToken: "auth-token" - }); - await client.put( - "https://api.courier.com/lists/list-1/subscriptions/subscriber|some-value+other-value?query=param" - ); - expect(fetchMock.mock.calls.length).toEqual(1); - expect(fetchMock.mock.calls[0][0]).toEqual( - "https://api.courier.com/lists/list-1/subscriptions/subscriber%7Csome-value+other-value?query=param" - ); - }); - - test("should prepend baseURL", async () => { - const client = initHttpClient({ - baseUrl: "https://execute-api.us-east-1.amazonaws.com/dev", - version: "1", - authorizationToken: "auth-token" - }); - await client.get("/lists/list1|test.list"); - expect(fetchMock.mock.calls.length).toEqual(1); - expect(fetchMock.mock.calls[0][0]).toEqual( - "https://execute-api.us-east-1.amazonaws.com/dev/lists/list1%7Ctest.list" - ); - }); -}); diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts deleted file mode 100644 index 8f9acac..0000000 --- a/src/__tests__/index.test.ts +++ /dev/null @@ -1,657 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from "../index"; -import { - ICourierBrand, - ICourierBrandGetAllResponse, - ICourierMessageGetHistoryResponse, - ICourierMessageGetOutputResponse, - ICourierMessageGetResponse, - ICourierMessagesGetResponse, - ICourierProfileGetResponse, - ICourierProfilePostResponse, - ICourierProfilePutResponse, - ICourierSendResponse, - ICourierSendMessageResponse, - ICourierMessageCancelResponse -} from "../types"; - -const mockSendResponse: ICourierSendResponse = { - messageId: "1234" -}; - -const mockSendV2Response: ICourierSendMessageResponse = { - requestId: "1234" -}; - -const mockReplaceProfileResponse: ICourierProfilePutResponse = { - status: "SUCCESS" -}; - -const mockMergeProfileResponse: ICourierProfilePostResponse = { - status: "SUCCESS" -}; - -const mockGetProfileResponse: ICourierProfileGetResponse = { - profile: { - name: "Troy" - } -}; - -const mockGetMessageResponse: ICourierMessageGetResponse = { - id: "mockMessageId", - recipient: "mockRecipient", - status: "SENT" -}; - -const mockGetMessageHistoryResponse: ICourierMessageGetHistoryResponse = { - results: [ - { - data: '{"favoriteAdjective":"awesomeness"}', - event: "courier-quickstart", - recipient: "Google_107913066099530916297", - ts: 1621286334939, - type: "ENQUEUED" - }, - { - event_id: "courier-quickstart", - notification_id: "courier-quickstart", - ts: 1621286335117, - type: "MAPPED" - }, - { - merged_profile: { - email: "tejas.kumthekar26@gmail.com", - email_verified: true, - family_name: "K", - given_name: "Tejas", - name: "Tejas K", - sub: "Google_107913066099530916297" - }, - stored_profile: { - email: "tejas.kumthekar26@gmail.com", - email_verified: true, - family_name: "K", - given_name: "Tejas", - name: "Tejas K", - sub: "Google_107913066099530916297" - }, - ts: 1621286335173, - type: "PROFILE_LOADED" - }, - { - channel: { - id: "5371fee1-8d74-4e00-bf45-037637168a07" - }, - integration: { - id: "courier-internal-sendgrid", - provider: "sendgrid" - }, - output: { - html: - "/messages/1-60a2ddbe-51a48d9c5fd0866e2495ce11/output/ffdc6d0d-2fc8-4447-a3b3-7d7e07e10689/html", - subject: - "/messages/1-60a2ddbe-51a48d9c5fd0866e2495ce11/output/ffdc6d0d-2fc8-4447-a3b3-7d7e07e10689/subject", - text: - "/messages/1-60a2ddbe-51a48d9c5fd0866e2495ce11/output/ffdc6d0d-2fc8-4447-a3b3-7d7e07e10689/text" - }, - ts: 1621286335562, - type: "RENDERED" - }, - { - channel: { - id: "5371fee1-8d74-4e00-bf45-037637168a07" - }, - integration: { - id: "courier-internal-sendgrid", - provider: "sendgrid" - }, - ts: 1621286335715, - type: "SENT" - }, - { - channel: { - id: "5371fee1-8d74-4e00-bf45-037637168a07" - }, - integration: { - id: "courier-internal-sendgrid", - provider: "sendgrid" - }, - reference: {}, - ts: 1621286337000, - type: "DELIVERED" - } - ] -}; - -const mockGetMessageOutputResponse: ICourierMessageGetOutputResponse = { - results: [ - { - channel: "email", - channel_id: "02db680f-38c2-4203-b1f2-ec4e31dc7362", - content: { - html: "", - subject: "foo bar", - text: "Lorem ipsum dolor, sit amet" - } - }, - { - channel: "push", - channel_id: "8f2494bb-480f-49a3-b601-86f13d651d0d", - content: { - blocks: [ - { - text: "Lorem ipsum dolor, sit amet.", - type: "text" - } - ], - body: "Lorem ipsum dolor, sit amet", - title: "foo bar" - } - } - ] -}; - -const mockCancelMessageResponse: ICourierMessageCancelResponse = { - canceledAt: 0, - event: "", - id: "", - recipient: "", - status: "" -}; - -const mockGetMessagesResponse: ICourierMessagesGetResponse = { - paging: { - more: false - }, - results: [ - { - id: "mockMessageId", - enqueued: 1632840573355, - sent: 1632840580620, - recipient: "mockRecipient", - status: "SENT", - event: "mockEvent", - notification: "mockNotification" - } - ] -}; - -const mockBrandResponse: ICourierBrand = { - created: 1591814489093, - id: "VHEGJ8NQEB4T3JM3SZJ8TWD27JPG", - name: "Default Brand", - published: 1591814489121, - settings: { - email: { - footer: {}, - header: { - barColor: "#9D3789" - } - } - }, - updated: 1591814489143, - version: "2020-06-10T18:41:29.093Z" -}; - -const mockGetBrandsResponse: ICourierBrandGetAllResponse = { - paging: { - more: false - }, - results: [mockBrandResponse] -}; - -describe("CourierClient - send with V2 schema", () => { - beforeAll(() => { - mockRequests([ - { - method: "POST", - path: "/send", - headers: { "Idempotency-Key": null }, - response: { body: mockSendV2Response } - }, - { - method: "POST", - path: "/send", - headers: { "Idempotency-Key": "IDEMPOTENCY_KEY_UUID" }, - response: { body: mockSendV2Response } - } - ]); - }); - - test(".send", async () => { - const { send } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - send({ - message: { - data: { - example: "EXAMPLE_DATA" - }, - template: "EVENT_ID", - to: { - phone_number: "PHONE_NUMBER" - } - } - }) - ).resolves.toMatchObject(mockSendV2Response); - }); - - test(".send ad hoc list", async () => { - const { send } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - send({ - message: { - to: [ - { - user_id: "", // usually your system's User ID associated to a Courier profile - email: "test@email.com", - data: { - name: "some user's name" - } - }, - { - email: "marty@email.com", - data: { - name: "Marty" - } - }, - { - email: "doc_brown@email.com", - data: { - name: "Doc" - } - }, - { - phone_number: "8675309", - data: { - name: "Jenny" - } - } - ], - content: { - title: "Back to the Future", - body: "Oh my {{name}}, we need 1.21 Gigawatts!" - }, - routing: { - method: "all", - channels: ["sms", "email"] - } - } - }) - ).resolves.toMatchObject(mockSendV2Response); - }); - - test(".send with Idempotency Key", async () => { - const { send } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await send( - { - message: { - data: { - example: "EXAMPLE_DATA" - }, - template: "EVENT_ID", - to: { - phone_number: "PHONE_NUMBER" - } - } - }, - { - idempotencyKey: "IDEMPOTENCY_KEY_UUID", - // e.g. expiration date in epoch time, 30 mins from now - idempotencyExpiry: Date.now() + 30 * 60 * 1000 - } - ); - }); -}); - -describe("CourierClient", () => { - beforeAll(() => { - mockRequests([ - { - method: "POST", - path: "/send", - headers: { "Idempotency-Key": null }, - response: { body: mockSendResponse } - }, - { - method: "POST", - path: "/send", - headers: { "Idempotency-Key": "IDEMPOTENCY_KEY_UUID" }, - response: { body: mockSendResponse } - }, - { - method: "PUT", - path: /\/profiles\/.*/, - response: { body: mockReplaceProfileResponse } - }, - { - method: "POST", - path: /\/profiles\/.*/, - headers: { "Idempotency-Key": "IDEMPOTENCY_KEY_UUID" }, - response: { body: mockMergeProfileResponse } - }, - { - method: "POST", - path: /\/profiles\/.*/, - headers: { "Idempotency-Key": null }, - response: { body: mockMergeProfileResponse } - }, - { - method: "GET", - path: /\/profiles\/.*/, - response: { body: mockGetProfileResponse } - }, - { - method: "POST", - path: /\/messages\/.*\/cancel/, - response: { body: mockCancelMessageResponse } - }, - { - method: "GET", - path: /\/messages\/.*\/history/, - response: { body: mockGetMessageHistoryResponse } - }, - { - method: "GET", - path: /\/messages\/.*\/output/, - response: { body: mockGetMessageOutputResponse } - }, - { - method: "GET", - path: /\/messages\/.*/, - response: { body: mockGetMessageResponse } - }, - { - method: "GET", - path: "/messages", - response: { body: mockGetMessagesResponse } - }, - { - method: "GET", - path: "/brands", - response: { body: mockGetBrandsResponse } - }, - { - method: "GET", - path: /\/brands\/.*/, - response: { body: mockBrandResponse } - }, - { - method: "POST", - path: "/brands", - headers: { "Idempotency-Key": null }, - response: { body: mockBrandResponse } - }, - { - method: "POST", - path: "/brands", - headers: { "Idempotency-Key": "IDEMPOTENCY_KEY_UUID" }, - response: { body: mockBrandResponse } - }, - { - method: "PUT", - path: /\/brands\/.*/, - response: { body: mockBrandResponse } - }, - { - method: "DELETE", - path: /\/brands\/.*/, - response: { status: 204 } - } - ]); - }); - - test(".send", async () => { - const { send } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - send({ - data: { - example: "EXAMPLE_DATA" - }, - eventId: "EVENT_ID", - profile: { - sms: "PHONE_NUMBER" - }, - recipientId: "RECIPIENT_ID" - }) - ).resolves.toMatchObject(mockSendResponse); - }); - - test(".send with Idempotency Key", async () => { - const { send } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await send( - { - data: { - example: "EXAMPLE_DATA" - }, - eventId: "EVENT_ID", - profile: { - sms: "PHONE_NUMBER" - }, - recipientId: "RECIPIENT_ID" - }, - { - idempotencyKey: "IDEMPOTENCY_KEY_UUID", - // e.g. expiration date in epoch time, 30 mins from now - idempotencyExpiry: Date.now() + 30 * 60 * 1000 - } - ); - }); - - test(".cancelMessage", async () => { - const { cancelMessage } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - cancelMessage(mockCancelMessageResponse.id) - ).resolves.toMatchObject(mockCancelMessageResponse); - }); - - test(".getMessage", async () => { - const { getMessage } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(getMessage(mockGetMessageResponse.id)).resolves.toMatchObject( - mockGetMessageResponse - ); - }); - - test(".getMessageHistory", async () => { - const { getMessageHistory } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(getMessageHistory("MESSAGE_ID")).resolves.toMatchObject( - mockGetMessageHistoryResponse - ); - }); - - test(".getMessageOutput", async () => { - const { getMessageOutput } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(getMessageOutput("MESSAGE_ID")).resolves.toMatchObject( - mockGetMessageOutputResponse - ); - }); - - test(".getMessages", async () => { - const { getMessages } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(getMessages()).resolves.toMatchObject(mockGetMessagesResponse); - }); - - test(".replaceProfile", async () => { - const { replaceProfile } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - replaceProfile({ - profile: { - foo: "bar" - }, - recipientId: "RECIPIENT_ID" - }) - ).resolves.toMatchObject(mockReplaceProfileResponse); - }); - - test(".mergeProfile", async () => { - const { mergeProfile } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - mergeProfile({ - profile: { - foo: "bar" - }, - recipientId: "RECIPIENT_ID" - }) - ).resolves.toMatchObject(mockMergeProfileResponse); - }); - - test(".mergeProfile with Idempotency Key", async () => { - const { mergeProfile } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await mergeProfile( - { - profile: { - foo: "bar" - }, - recipientId: "RECIPIENT_ID" - }, - { - idempotencyKey: "IDEMPOTENCY_KEY_UUID" - } - ); - }); - - test(".getProfile", async () => { - const { getProfile } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - getProfile({ - recipientId: "RECIPIENT_ID" - }) - ).resolves.toMatchObject(mockGetProfileResponse); - }); - - test(".getBrands", async () => { - const { getBrands } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(getBrands()).resolves.toMatchObject(mockGetBrandsResponse); - }); - - test(".getBrand", async () => { - const { getBrand } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - getBrand("VHEGJ8NQEB4T3JM3SZJ8TWD27JPG") - ).resolves.toMatchObject(mockBrandResponse); - }); - - test(".createBrand", async () => { - const { createBrand } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - createBrand({ - id: "VHEGJ8NQEB4T3JM3SZJ8TWD27JPG", - name: "Default Brand", - settings: { - email: { - footer: {}, - header: { - barColor: "#9D3789" - } - } - } - }) - ).resolves.toMatchObject(mockBrandResponse); - }); - - test(".createBrand with Idempotency Key", async () => { - const { createBrand } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await createBrand( - { - id: "VHEGJ8NQEB4T3JM3SZJ8TWD27JPG", - name: "Default Brand", - settings: { - email: { - footer: {}, - header: { - barColor: "#9D3789" - } - } - } - }, - { - idempotencyKey: "IDEMPOTENCY_KEY_UUID" - } - ); - }); - - test(".replaceBrand", async () => { - const { replaceBrand } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - replaceBrand({ - id: "VHEGJ8NQEB4T3JM3SZJ8TWD27JPG", - name: "Default Brand", - settings: { - email: { - footer: {}, - header: { - barColor: "#9D3789" - } - } - } - }) - ).resolves.toMatchObject(mockBrandResponse); - }); - - test(".deleteBrand", async () => { - const { deleteBrand } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - deleteBrand("VHEGJ8NQEB4T3JM3SZJ8TWD27JPG") - ).resolves.toBeUndefined(); - }); -}); diff --git a/src/__tests__/issue-token.test.ts b/src/__tests__/issue-token.test.ts deleted file mode 100644 index bd88926..0000000 --- a/src/__tests__/issue-token.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { CourierClient } from ".."; -import { - ICourierAuthIssueTokenParameters, - ICourierAuthIssueTokenResponse -} from "../issue-token/types"; -import mockRequests from "./lib/mock-requests"; - -const mockRequest: ICourierAuthIssueTokenParameters = { - scope: "user_id:example_user_id read:messages", - expiresIn: "2 days" -}; - -const mockResponse: ICourierAuthIssueTokenResponse = { - token: "example_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6InVzZXJfaW" -}; - -describe("Courier Issue Token", () => { - beforeEach(() => { - mockRequests([ - { - method: "POST", - path: `/auth/issue-token`, - response: { body: mockResponse } - } - ]); - }); - - test("should issue token", async () => { - const { issueToken } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(issueToken(mockRequest)).resolves.toMatchObject(mockResponse); - }); -}); diff --git a/src/__tests__/lib/mock-requests.ts b/src/__tests__/lib/mock-requests.ts deleted file mode 100644 index a8794d3..0000000 --- a/src/__tests__/lib/mock-requests.ts +++ /dev/null @@ -1,53 +0,0 @@ -import fetchMock from "jest-fetch-mock"; - -interface MockConfig { - method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; - path: string | RegExp; - headers?: Record; - response: { - status?: number; - body?: any; - }; -} - -const mockRequests = (configs: MockConfig[]) => { - const findMatchingConfig = (request: Request) => { - const { url, method } = request; - const { pathname } = new URL(url); - - const matchingConfig = configs.find(config => { - const matchingMethod = config.method === method; - const matchingPath = - typeof config.path === "string" - ? pathname === config.path - : config.path.test(pathname); - - const matchingHeaders = config.headers - ? Object.entries(config.headers).every( - ([key, value]) => request.headers.get(key) === value - ) - : true; - - return matchingMethod && matchingPath && matchingHeaders; - }); - - return matchingConfig; - }; - - fetchMock.doMockIf( - request => !!findMatchingConfig(request), - async request => { - const config = findMatchingConfig(request)!; - - return { - status: config.response.status || 200, - body: config.response.body ? JSON.stringify(config.response.body) : "", - headers: config.response.body - ? { "content-type": "application/json" } - : undefined - }; - } - ); -}; - -export default mockRequests; diff --git a/src/__tests__/lists.test.ts b/src/__tests__/lists.test.ts deleted file mode 100644 index da50c4b..0000000 --- a/src/__tests__/lists.test.ts +++ /dev/null @@ -1,293 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from "../index"; - -import { - ICourierList, - ICourierListFindByRecipientIdResponse, - ICourierListGetAllResponse, - ICourierListGetSubscriptionsResponse, - ICourierPutSubscriptionsRecipient -} from "../lists/types"; - -import { - ICourierSendListOrPatternParams, - ICourierSendResponse -} from "../types"; - -const mockSendResponse: ICourierSendResponse = { - messageId: "1234" -}; - -const mockListResponse: ICourierList = { - created: 1591814489093, - id: "example.list.id", - name: "Example List", - updated: 1591814489143 -}; - -const mockGetListsResponse: ICourierListGetAllResponse = { - items: [mockListResponse], - paging: { - more: false - } -}; - -const mockFindByRecipientIdResponse: ICourierListFindByRecipientIdResponse = { - paging: { - more: false - }, - results: [mockListResponse] -}; - -const mockGetListSubscriptionsResponse: ICourierListGetSubscriptionsResponse = { - items: [ - { - preferences: { - notifications: { - W951R8G37V49KZMK8DEKW8Z588BZ: { - status: "OPTED_IN" - } - } - }, - recipientId: "ABCD1234" - } - ], - paging: { - more: false - } -}; - -describe("CourierLists", () => { - beforeAll(() => { - mockRequests([ - { - method: "GET", - path: "/lists", - response: { body: mockGetListsResponse } - }, - { - method: "GET", - path: /\/lists\/.*\/subscriptions/, - response: { body: mockGetListSubscriptionsResponse } - }, - { - method: "GET", - path: /\/lists\/.*/, - response: { body: mockListResponse } - }, - { - method: "PUT", - path: /\/lists\/.*\/subscriptions/, - response: { status: 204 } - }, - { - method: "PUT", - path: /\/lists\/.*\/subscriptions\/.*/, - response: { status: 204 } - }, - { - method: "POST", - path: /\/lists\/.*\/subscriptions/, - response: { status: 204 } - }, - { - method: "PUT", - path: /\/lists\/.*\/restore/, - response: { status: 204 } - }, - { - method: "PUT", - path: /\/lists\/.*/, - response: { status: 204 } - }, - { - method: "DELETE", - path: /\/lists\/.*\/subscriptions\/.*/, - response: { status: 204 } - }, - { - method: "DELETE", - path: /\/lists\/.*/, - response: { status: 204 } - }, - { - method: "POST", - path: "/send/list", - response: { body: mockSendResponse } - }, - { - method: "GET", - path: /\/profiles\/.*\/lists/, - response: { body: mockFindByRecipientIdResponse } - } - ]); - }); - - test(".send with List", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - const params: ICourierSendListOrPatternParams = { - data: { - example: "EXAMPLE_DATA" - }, - event: "EVENT_ID", - list: "example.list.id" - }; - - await expect(lists.send(params)).resolves.toMatchObject(mockSendResponse); - }); - - test(".send with Pattern", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - const params: ICourierSendListOrPatternParams = { - data: { - example: "EXAMPLE_DATA" - }, - event: "EVENT_ID", - pattern: "example.list.*" - }; - - await expect(lists.send(params)).resolves.toMatchObject(mockSendResponse); - }); - - test(".list", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(lists.list()).resolves.toMatchObject(mockGetListsResponse); - }); - - test(".get", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(lists.get("example.list.id")).resolves.toMatchObject( - mockListResponse - ); - }); - - test(".put", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - lists.put("example.list.id", { - name: "Updated Example List" - }) - ).resolves.toBeUndefined(); - }); - - test(".delete", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(lists.delete("example.list.id")).resolves.toBeUndefined(); - }); - - test(".restore", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(lists.restore("example.list.id")).resolves.toBeUndefined(); - }); - - test(".getSubscriptions", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - lists.getSubscriptions("example.list.id") - ).resolves.toMatchObject(mockGetListSubscriptionsResponse); - }); - - test(".putSubscriptions", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - lists.putSubscriptions("example.list.id", [{ recipientId: "ABCD1234" }]) - ).resolves.toBeUndefined(); - }); - - test(".putSubscriptions with subscription preferences", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - const mockNotificationId = "8YA052Y5VV4EMQP2C4KW76WF3BC3"; - - const mockRecipientWithPreferences: ICourierPutSubscriptionsRecipient = { - preferences: { - notifications: { - [mockNotificationId]: { - status: "OPTED_IN" - } - } - }, - recipientId: "ABCD1234" - }; - - await expect( - lists.putSubscriptions("example.list.id", [mockRecipientWithPreferences]) - ).resolves.toBeUndefined(); - }); - - test(".postSubscriptions", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - lists.postSubscriptions("example.list.id", [{ recipientId: "ABCD1234" }]) - ).resolves.toBeUndefined(); - }); - - test(".subscribe", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - lists.subscribe("example.list.id", "ABCD1234", { - notifications: { - W951R8G37V49KZMK8DEKW8Z588BZ: { - status: "OPTED_IN" - } - } - }) - ).resolves.toBeUndefined(); - }); - - test(".unsubscribe", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - lists.unsubscribe("example.list.id", "ABCD1234") - ).resolves.toBeUndefined(); - }); - - test(".findByRecipientId", async () => { - const { lists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - lists.findByRecipientId("RECIPIENT_ID") - ).resolves.toMatchObject(mockFindByRecipientIdResponse); - }); -}); diff --git a/src/__tests__/notifications.test.ts b/src/__tests__/notifications.test.ts deleted file mode 100644 index 2f230d7..0000000 --- a/src/__tests__/notifications.test.ts +++ /dev/null @@ -1,353 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from "../index"; - -import { - ICourierNotificationGetContentResponse, - ICourierNotificationGetSubmissionChecksResponse, - ICourierNotificationListResponse, - ICourierNotificationPutSubmissionChecksResponse -} from "../notifications/types"; - -const mockListNotificationsResponse: ICourierNotificationListResponse = { - paging: { - more: false - }, - results: [ - { - created_at: 1677027399190, - id: "notification1", - routing: { - channels: ["email"], - method: "single" - }, - tags: { - data: [] - }, - title: "Hello, World", - updated_at: 1677027399190 - }, - { - created_at: 1677027447248, - id: "notification2", - routing: { - channels: ["email"], - method: "single" - }, - tags: { - data: [] - }, - title: "Goodbye, World", - updated_at: 1677027447248 - } - ] -}; - -const mockGetNotificationContentResponse: ICourierNotificationGetContentResponse = { - blocks: [ - { - id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6", - type: "text", - content: "block 1", - checksum: "64e9e6003f89e45da9eba83c34549e7c", - locales: { - fr_FR: "block fr 1" - } - }, - { - id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2", - type: "text", - content: "block 2", - checksum: "82206013038af7af93e9eab07b2ae536", - locales: { - fr_FR: "block fr 2" - } - } - ], - channels: [ - { - id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e", - type: "email", - content: { - subject: "New Subject" - }, - checksum: "440b32881f59bdf5af1a5db71f2aa433", - locales: { - fr_FR: { - subject: "French Subject" - } - } - } - ], - checksum: "b7345b0e9e6391a0b19a350165e421c9" -}; - -const mockGetNotificationDraftContentResponse: ICourierNotificationGetContentResponse = { - blocks: [ - { - id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6", - type: "text", - content: "block 1", - checksum: "64e9e6003f89e45da9eba83c34549e7c", - locales: { - fr_FR: "block fr 1" - } - }, - { - id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2", - type: "text", - content: "block 2", - checksum: "82206013038af7af93e9eab07b2ae536", - locales: { - fr_FR: "block fr 2" - } - } - ], - channels: [ - { - id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e", - type: "email", - content: { - subject: "New Subject" - }, - checksum: "440b32881f59bdf5af1a5db71f2aa433", - locales: { - fr_FR: { - subject: "French Subject" - } - } - } - ], - checksum: "b7345b0e9e6391a0b19a350165e421c9" -}; - -const mockGetNotificationSubmissionChecksResponse: ICourierNotificationGetSubmissionChecksResponse = { - checks: [ - { - id: "check1", - status: "PENDING", - type: "custom", - updated: 1629169195778 - } - ] -}; - -const mockPutNotificationSubmissionChecksResponse: ICourierNotificationPutSubmissionChecksResponse = { - checks: [ - { - id: "check1", - status: "RESOLVED", - type: "custom", - updated: 1629169195779 - } - ] -}; - -describe("CourierNotifications", () => { - beforeAll(() => { - mockRequests([ - { - method: "GET", - path: "/notifications", - response: { body: mockListNotificationsResponse } - }, - { - method: "GET", - path: /\/notifications\/.*\/content/, - response: { body: mockGetNotificationContentResponse } - }, - { - method: "GET", - path: /\/notifications\/.*\/draft\/content/, - response: { body: mockGetNotificationDraftContentResponse } - }, - { - method: "POST", - path: /\/notifications\/.*\/variations/, - response: { status: 204 } - }, - { - method: "POST", - path: /\/notifications\/.*\/draft\/variations/, - response: { status: 204 } - }, - { - method: "GET", - path: /\/notifications\/.*\/.*\/checks/, - response: { body: mockGetNotificationSubmissionChecksResponse } - }, - { - method: "PUT", - path: /\/notifications\/.*\/.*\/checks/, - response: { body: mockPutNotificationSubmissionChecksResponse } - }, - { - method: "DELETE", - path: /\/notifications\/.*\/.*\/checks/, - response: { status: 204 } - } - ]); - }); - - test(".list notifications", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(notifications.list({})).resolves.toMatchObject( - mockListNotificationsResponse - ); - }); - - test(".get notification content", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - notifications.getContent("notification1") - ).resolves.toMatchObject(mockGetNotificationContentResponse); - }); - - test(".get notification draft content", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - notifications.getDraftContent("notification1") - ).resolves.toMatchObject(mockGetNotificationDraftContentResponse); - }); - - test(".post notification variations", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - notifications.postVariations("notification1", { - blocks: [ - { - id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6", - type: "text", - locales: { - fr_FR: "block fr 1" - } - }, - { - id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2", - type: "text", - locales: { - fr_FR: "block fr 2" - } - } - ], - channels: [ - { - id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e", - type: "email", - locales: { - fr_FR: { - subject: "French Subject" - } - } - }, - { - id: "channel_2c2aad1c-30f0-4a55-8d8f-d213f32147bc", - type: "push", - locales: { - fr_FR: { - title: "French Title" - } - } - } - ] - }) - ).resolves.toBeUndefined(); - }); - - test(".post notification draft variations", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - notifications.postDraftVariations("notification1", { - blocks: [ - { - id: "block_1d4c32e0-bca8-43f6-b5d5-8c043199bce6", - type: "text", - locales: { - fr_FR: "block fr 1" - } - }, - { - id: "block_6d50a6e3-ecc3-4815-bf51-0202c6bf54e2", - type: "text", - locales: { - fr_FR: "block fr 2" - } - } - ], - channels: [ - { - id: "channel_1ba46024-f156-4ed7-893b-cb1cdcfbd36e", - type: "email", - locales: { - fr_FR: { - subject: "French Subject" - } - } - }, - { - id: "channel_2c2aad1c-30f0-4a55-8d8f-d213f32147bc", - type: "push", - locales: { - fr_FR: { - title: "French Title" - } - } - } - ] - }) - ).resolves.toBeUndefined(); - }); - - test(".get notification submission checks", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - notifications.getSubmissionChecks("notification1", "submission1") - ).resolves.toMatchObject(mockGetNotificationSubmissionChecksResponse); - }); - - test(".put notification submission checks", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - notifications.putSubmissionChecks("notification1", "submission1", { - checks: [ - { - id: "check1", - status: "RESOLVED", - type: "custom" - } - ] - }) - ).resolves.toMatchObject(mockPutNotificationSubmissionChecksResponse); - }); - - test(".cancel notification submission", async () => { - const { notifications } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - notifications.cancelSubmission("notification1", "submission1") - ).resolves.toBeUndefined(); - }); -}); diff --git a/src/__tests__/preferences.test.ts b/src/__tests__/preferences.test.ts deleted file mode 100644 index aa3a4f9..0000000 --- a/src/__tests__/preferences.test.ts +++ /dev/null @@ -1,103 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from "../index"; - -import { - ICourierPreferencesGetResponse, - ICourierPreferencesListResponse, - ICourierPreferencesPutResponse -} from "../preferences/types"; - -const mockGetResponse: ICourierPreferencesGetResponse = { - notifications: { - "0089248b-2ce8-423e-838e-f29f938d658b": { - status: "OPTED_OUT" - } - }, - categories: { - "1341fdf3-f34r-fss3-fs23-fsfdsv233be3": { - status: "OPTED_IN" - } - } -}; - -const mockListResponse: ICourierPreferencesListResponse = { - uncategorized: [ - { - id: "9e5bb2cf-1ad4-4151-8f57-78e9754ce7dc", - title: "Untitled Notification", - config: { - type: "OPT_IN" - } - } - ], - categories: [ - { - id: "6ab6f268-d60c-43d9-9987-93f6ed835b94", - title: "New Category", - config: { - type: "REQUIRED" - } - } - ] -}; - -const mockPutResponse: ICourierPreferencesPutResponse = { - status: "SUCCESS" -}; - -describe("CourierPreference", () => { - beforeAll(() => { - mockRequests([ - { - method: "PUT", - path: /\/preferences\/.*/, - response: { body: mockPutResponse } - }, - { - method: "GET", - path: /\/preferences\/.*/, - response: { body: mockGetResponse } - }, - { - method: "GET", - path: "/preferences", - response: { body: mockListResponse } - } - ]); - }); - - test(".get", async () => { - const { preferences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(preferences.get("RECIPIENT_ID")).resolves.toMatchObject( - mockGetResponse - ); - }); - - test(".list", async () => { - const { preferences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(preferences.list()).resolves.toMatchObject(mockListResponse); - }); - - test(".put", async () => { - const { preferences } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - preferences.put("RECIPIENT_ID", { - notifications: { - "9e5bb2cf-1ad4-4151-8f57-78e9754ce7dc": { - status: "OPTED_IN" - } - } - }) - ).resolves.toMatchObject(mockPutResponse); - }); -}); diff --git a/src/__tests__/profile.test.ts b/src/__tests__/profile.test.ts deleted file mode 100644 index 2c9dbd9..0000000 --- a/src/__tests__/profile.test.ts +++ /dev/null @@ -1,119 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from "../index"; -import { ICourierRecipientSubscriptionsResponse } from "../lists/types"; -import { ICourierProfilePostResponse, List } from "../types"; - -const mockGetProfileListResponse: ICourierRecipientSubscriptionsResponse = { - paging: { - cursor: "", - more: false - }, - results: [ - { - id: "example.list1", - name: "Courier Feature update list" - } - ] -}; - -const mockPostResponse: ICourierProfilePostResponse = { - status: "SUCCESS" -}; - -const additionalMocklists: List[] = [ - { - listId: "example.list1", - name: "Courier Feature updates", - preferences: { - notifications: { - "1231123": { - status: "OPTED_IN" - } - } - } - }, - { - listId: "example.list2", - name: "Courier API updates", - preferences: { - notifications: { - "1231123": { - status: "OPTED_IN" - } - } - } - } -]; - -describe("Courier Recipient Profile", () => { - beforeEach(() => { - mockRequests([ - { - method: "GET", - path: /\/profiles\/.*\/lists/, - response: { body: mockGetProfileListResponse } - }, - { - method: "POST", - path: /\/profiles\/.*\/lists/, - response: { body: mockPostResponse } - }, - { - method: "DELETE", - path: /\/profiles\/.*\/lists/, - response: { body: mockPostResponse } - }, - { - method: "DELETE", - path: /\/profiles\/.*/, - response: { status: 200 } - } - ]); - }); - - test("should delete profile", async () => { - const { deleteProfile } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - deleteProfile({ recipientId: "12345" }) - ).resolves.toBeUndefined(); - }); - - test("should return lists associated with recipient", async () => { - const { getRecipientSubscriptions } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - getRecipientSubscriptions({ recipientId: "12345" }) - ).resolves.toMatchObject(mockGetProfileListResponse); - }); - - test("should subscribe recipient to provided lists", async () => { - const { addRecipientToLists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - addRecipientToLists({ - lists: additionalMocklists, - recipientId: "12345" - }) - ).resolves.toMatchObject(mockPostResponse); - }); - - test("should remove recipient from all the lists subscription", async () => { - const { removeRecipientFromAllLists } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - removeRecipientFromAllLists({ - recipientId: "12345" - }) - ).resolves.toMatchObject(mockPostResponse); - }); -}); diff --git a/src/__tests__/tenants.test.ts b/src/__tests__/tenants.test.ts deleted file mode 100644 index c03df6c..0000000 --- a/src/__tests__/tenants.test.ts +++ /dev/null @@ -1,110 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import * as TenantTypes from "../tenants/types"; -import { CourierClient } from "../index"; - -const mockTenantId = "a83b4d91-fe15-4f9d-b049-16e47d177312"; - -const mockPutAccountResponse: TenantTypes.ITenant = { - id: mockTenantId, - name: "test tenant", - type: "tenant" -}; - -const mockGetAccountResponse: TenantTypes.ITenant = { - id: mockTenantId, - name: "test tenant", - type: "tenant" -}; - -const mockTenantListResponse: TenantTypes.IPaginatedResult = { - items: [ - { - id: mockTenantId, - name: "test tenant", - type: "tenant" - } - ], - has_more: false, - type: "list", - url: "/tenants" -}; - -describe("CourierTenants", () => { - beforeAll(() => { - mockRequests([ - { - method: "PUT", - path: `/tenants/${mockTenantId}`, - response: { body: mockPutAccountResponse } - }, - { - method: "DELETE", - path: `/tenants/${mockTenantId}`, - response: { status: 204 } - }, - { - method: "GET", - path: `/tenants/${mockTenantId}`, - response: { body: mockGetAccountResponse } - }, - { - method: "GET", - path: `/tenants`, - response: { body: mockTenantListResponse } - } - ]); - }); - - test(".putTenant", async () => { - const { tenants } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect( - tenants.put({ - id: mockTenantId, - name: "My favorite software engineers" - }) - ).resolves.toMatchObject({}); - }); - - test(".getTenant", async () => { - const { tenants } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(tenants.get(mockTenantId)).resolves.toMatchObject({ - id: mockTenantId, - name: "test tenant", - type: "tenant" - }); - }); - - test(".listTenants", async () => { - const { tenants } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(tenants.listTenants({ limit: "10" })).resolves.toMatchObject({ - items: [ - { - id: mockTenantId, - name: "test tenant", - type: "tenant" - } - ], - has_more: false, - type: "list", - url: "/tenants" - }); - }); - - test(".deleteTenant", async () => { - const { tenants } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - await expect(tenants.delete(mockTenantId)).resolves.not.toThrow(); - }); -}); diff --git a/src/__tests__/token-management.test.ts b/src/__tests__/token-management.test.ts deleted file mode 100644 index 0378326..0000000 --- a/src/__tests__/token-management.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import mockRequests from "./lib/mock-requests"; - -import { CourierClient } from ".."; -import { IUserToken } from "../token-management/types"; - -const mockToken: IUserToken = { - token: "abc", - provider_key: "apn" -}; - -describe("CourierAudiences", () => { - beforeAll(() => { - mockRequests([ - { - method: "PUT", - path: "/users/me/tokens", - response: { status: 204 } - }, - { - method: "PUT", - path: "/users/me/tokens/abc", - response: { status: 204 } - }, - { - method: "PATCH", - path: "/users/me/tokens/abc", - response: { status: 204 } - }, - { - method: "GET", - path: "/users/me/tokens/abc", - response: { body: mockToken } - }, - { - method: "GET", - path: "/users/me/tokens", - response: { body: { tokens: [mockToken] } } - }, - { - method: "DELETE", - path: "/users/me/tokens/abc", - response: { status: 204 } - } - ]); - }); - - const { tokenManagement } = CourierClient({ - authorizationToken: "AUTH_TOKEN" - }); - - describe("putUserTokens", () => { - it("resolves void when the put call succeeds", async () => { - expect.assertions(1); - - const prom = tokenManagement.putUserTokens({ - user_id: "me", - tokens: [mockToken] - }); - await expect(prom).resolves.not.toThrow(); - }); - }); - - describe("putUserToken", () => { - it("resolves void when the put call succeeds", async () => { - expect.assertions(1); - - const prom = tokenManagement.putUserToken({ - user_id: "me", - token: mockToken - }); - await expect(prom).resolves.not.toThrow(); - }); - }); - - describe("patchUserToken", () => { - it("resolves void when the put call succeeds", async () => { - expect.assertions(1); - - const prom = tokenManagement.patchUserToken({ - user_id: "me", - token: "abc", - patch: [{ op: "replace", path: "status", value: "revoked" }] - }); - await expect(prom).resolves.not.toThrow(); - }); - }); - - describe("getUserToken", () => { - it("resolves with the token when the get call succeeds", async () => { - expect.assertions(1); - - const result = await tokenManagement.getUserToken({ - user_id: "me", - token: "abc" - }); - expect(result).toMatchObject(mockToken); - }); - }); - - describe("getUserTokens", () => { - it("resolves with the tokens when the get call succeeds", async () => { - expect.assertions(1); - - const result = await tokenManagement.getUserTokens({ - user_id: "me" - }); - expect(result).toMatchObject({ tokens: [mockToken] }); - }); - }); - - describe("deleteUserToken", () => { - it("resolves with the token when the delete call succeeds", async () => { - expect.assertions(1); - - const prom = tokenManagement.deleteUserToken({ - user_id: "me", - token: "abc" - }); - await expect(prom).resolves.not.toThrow(); - }); - }); -}); diff --git a/src/__tests__/users.test.ts b/src/__tests__/users.test.ts deleted file mode 100644 index 99d6e67..0000000 --- a/src/__tests__/users.test.ts +++ /dev/null @@ -1,123 +0,0 @@ -import mockRequests from "./lib/mock-requests"; -import { CourierClient } from "../index"; - -const mockUserId = "user-1"; - -describe("CourierUsers", () => { - beforeAll(() => { - mockRequests([ - { - method: "PUT", - path: `/users/${mockUserId}`, - response: { status: 204 }, - }, - { - method: "PUT", - path: `/users/${mockUserId}/accounts`, - response: { status: 204 }, - }, - { - method: "PUT", - path: `/users/${mockUserId}/preferences/topic-1`, - response: { status: 200 }, - }, - { - method: "GET", - path: `/users/${mockUserId}/preferences/topic-1`, - response: { - body: { - topic: { - default_status: "OPT_IN", - has_custom_routing: true, - custom_routing: ["email"], - status: "OPTED_OUT", - topic_id: "FW0YU64P4TMYKMMHH67D6FENX8VS", - topic_name: "Invitations", - }, - }, - }, - }, - { - method: "GET", - path: `/users/${mockUserId}/preferences`, - response: { - body: { - paging: { - cursor: - "MTU4OTQ5NTI1ODY4NywxLTVlYmRjNWRhLTEwODZlYWFjMWRmMjEwMTNjM2I0ZjVhMA==", - more: true, - }, - items: [ - { - default_status: "OPT_IN", - has_custom_routing: true, - custom_routing: ["email"], - status: "OPTED_OUT", - topic_id: "FW0YU64P4TMYKMMHH67D6FENX8VS", - topic_name: "Invitations", - }, - ], - }, - }, - }, - ]); - }); - - test(".put", async () => { - const { users } = CourierClient({ - authorizationToken: "AUTH_TOKEN", - }); - - await expect( - users.put(mockUserId, { - accounts: [{ account_id: "account-1", profile: { foo: "bar" } }], - profile: { name: "John Doe" }, - }) - ).resolves.not.toThrow(); - }); - - test(".putAccounts", async () => { - const { users } = CourierClient({ - authorizationToken: "AUTH_TOKEN", - }); - - await expect( - users.putAccounts(mockUserId, [ - { account_id: "account-1", profile: { foo: "bar" } }, - ]) - ).resolves.not.toThrow(); - }); - - test(".putUserPreferences", async () => { - const { users } = CourierClient({ - authorizationToken: "AUTH_TOKEN", - }); - - await expect( - users.putUserPreferenceByTopic(mockUserId, "topic-1", { - default_status: "OPTED_IN", - status: "OPTED_OUT", - }) - ).resolves.not.toThrow(); - }); - - test(".getPrefsByTopic", async () => { - const { users } = CourierClient({ - authorizationToken: "AUTH_TOKEN", - }); - - await expect( - users.getUserPreferenceByTopic(mockUserId, "topic-1") - ).resolves.not.toThrow(); - }); - - test(".getUserPreferences", async () => { - const { users } = CourierClient({ - authorizationToken: "AUTH_TOKEN", - }); - - await expect( - users.getUserPreferenceByTopics(mockUserId) - ).resolves.not.toThrow(); - }); -}); diff --git a/src/api/client/index.ts b/src/api/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/client/requests/SendMessageRequest.ts b/src/api/client/requests/SendMessageRequest.ts new file mode 100644 index 0000000..674500f --- /dev/null +++ b/src/api/client/requests/SendMessageRequest.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../.."; + +export interface SendMessageRequest { + /** Defines the message to be delivered */ + message: Courier.Message; +} diff --git a/src/api/client/requests/index.ts b/src/api/client/requests/index.ts new file mode 100644 index 0000000..01fd9dd --- /dev/null +++ b/src/api/client/requests/index.ts @@ -0,0 +1 @@ +export { SendMessageRequest } from "./SendMessageRequest"; diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..a931b36 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,3 @@ +export * from "./types"; +export * from "./resources"; +export * from "./client"; diff --git a/src/api/resources/audiences/client/Client.ts b/src/api/resources/audiences/client/Client.ts new file mode 100644 index 0000000..d7fd71a --- /dev/null +++ b/src/api/resources/audiences/client/Client.ts @@ -0,0 +1,304 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Audiences { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } +} + +export class Audiences { + constructor(protected readonly _options: Audiences.Options) {} + + /** + * Returns the specified audience by id. + */ + public async get(audienceId: string, requestOptions?: Audiences.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/audiences/${audienceId}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.Audience; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Creates or updates audience. + */ + public async update( + audienceId: string, + request: Courier.AudienceRequest, + requestOptions?: Audiences.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/audiences/${audienceId}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.Audience; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Deletes the specified recipient Profile. + */ + public async delete(audienceId: string, requestOptions?: Audiences.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/audiences/${audienceId}` + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Get list of members of an audience. + * @throws {@link Courier.BadRequestError} + */ + public async listMembers( + audienceId: string, + request: Courier.ListAudienceMembersRequest = {}, + requestOptions?: Audiences.RequestOptions + ): Promise { + const { cursor } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/audiences/${audienceId}/members` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.AudienceMemberListResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Get the audiences associated with the authorization token. + * @throws {@link Courier.BadRequestError} + */ + public async listAudiences( + request: Courier.ListAudiencesRequest = {}, + requestOptions?: Audiences.RequestOptions + ): Promise { + const { cursor } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/audiences" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.AudienceListResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/audiences/client/index.ts b/src/api/resources/audiences/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/resources/audiences/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/resources/audiences/client/requests/ListAudienceMembersRequest.ts b/src/api/resources/audiences/client/requests/ListAudienceMembersRequest.ts new file mode 100644 index 0000000..7517e06 --- /dev/null +++ b/src/api/resources/audiences/client/requests/ListAudienceMembersRequest.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListAudienceMembersRequest { + /** + * A unique identifier that allows for fetching the next set of members + * + */ + cursor?: string; +} diff --git a/src/api/resources/audiences/client/requests/ListAudiencesRequest.ts b/src/api/resources/audiences/client/requests/ListAudiencesRequest.ts new file mode 100644 index 0000000..636d353 --- /dev/null +++ b/src/api/resources/audiences/client/requests/ListAudiencesRequest.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListAudiencesRequest { + /** + * A unique identifier that allows for fetching the next set of audiences + * + */ + cursor?: string; +} diff --git a/src/api/resources/audiences/client/requests/index.ts b/src/api/resources/audiences/client/requests/index.ts new file mode 100644 index 0000000..b519c33 --- /dev/null +++ b/src/api/resources/audiences/client/requests/index.ts @@ -0,0 +1,2 @@ +export { ListAudienceMembersRequest } from "./ListAudienceMembersRequest"; +export { ListAudiencesRequest } from "./ListAudiencesRequest"; diff --git a/src/api/resources/audiences/index.ts b/src/api/resources/audiences/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/audiences/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/audiences/types/Audience.ts b/src/api/resources/audiences/types/Audience.ts new file mode 100644 index 0000000..39a72b5 --- /dev/null +++ b/src/api/resources/audiences/types/Audience.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Audience { + /** A unique identifier representing the audience_id */ + id: string; + /** The name of the audience */ + name: string; + /** A description of the audience */ + description: string; + filter: Courier.Filter; + created_at: string; + updated_at: string; +} diff --git a/src/api/resources/audiences/types/AudienceListResponse.ts b/src/api/resources/audiences/types/AudienceListResponse.ts new file mode 100644 index 0000000..d55bfe0 --- /dev/null +++ b/src/api/resources/audiences/types/AudienceListResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AudienceListResponse { + items: Courier.Audience[]; + paging: Courier.Paging; +} diff --git a/src/api/resources/audiences/types/AudienceMember.ts b/src/api/resources/audiences/types/AudienceMember.ts new file mode 100644 index 0000000..b046ee6 --- /dev/null +++ b/src/api/resources/audiences/types/AudienceMember.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AudienceMember { + added_at: string; + audience_id: string; + audience_version: number; + member_id: string; + reason: string; +} diff --git a/src/api/resources/audiences/types/AudienceMemberGetResponse.ts b/src/api/resources/audiences/types/AudienceMemberGetResponse.ts new file mode 100644 index 0000000..213a3d6 --- /dev/null +++ b/src/api/resources/audiences/types/AudienceMemberGetResponse.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AudienceMemberGetResponse { + audienceMember: Courier.AudienceMember; +} diff --git a/src/api/resources/audiences/types/AudienceMemberListResponse.ts b/src/api/resources/audiences/types/AudienceMemberListResponse.ts new file mode 100644 index 0000000..0d9823b --- /dev/null +++ b/src/api/resources/audiences/types/AudienceMemberListResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AudienceMemberListResponse { + items: Courier.AudienceMember[]; + paging: Courier.Paging; +} diff --git a/src/api/resources/audiences/types/AudiencePutResponse.ts b/src/api/resources/audiences/types/AudiencePutResponse.ts new file mode 100644 index 0000000..a6f9e00 --- /dev/null +++ b/src/api/resources/audiences/types/AudiencePutResponse.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AudiencePutResponse { + audience: Courier.Audience; +} diff --git a/src/api/resources/audiences/types/AudienceRequest.ts b/src/api/resources/audiences/types/AudienceRequest.ts new file mode 100644 index 0000000..d073828 --- /dev/null +++ b/src/api/resources/audiences/types/AudienceRequest.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AudienceRequest { + /** A unique identifier representing the audience_id */ + id?: string; + /** The name of the audience */ + name?: string; + /** A description of the audience */ + description?: string; + filter?: Courier.Filter; +} diff --git a/src/api/resources/audiences/types/BaseFilterConfig.ts b/src/api/resources/audiences/types/BaseFilterConfig.ts new file mode 100644 index 0000000..e04be54 --- /dev/null +++ b/src/api/resources/audiences/types/BaseFilterConfig.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BaseFilterConfig { + /** + * The operator to use for filtering + * + */ + operator: Courier.Operator; +} diff --git a/src/api/resources/audiences/types/ComparisonOperator.ts b/src/api/resources/audiences/types/ComparisonOperator.ts new file mode 100644 index 0000000..dceb76f --- /dev/null +++ b/src/api/resources/audiences/types/ComparisonOperator.ts @@ -0,0 +1,34 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ComparisonOperator = + | "ENDS_WITH" + | "EQ" + | "EXISTS" + | "GT" + | "GTE" + | "INCLUDES" + | "IS_AFTER" + | "IS_BEFORE" + | "LT" + | "LTE" + | "NEQ" + | "OMIT" + | "STARTS_WITH"; + +export const ComparisonOperator = { + EndsWith: "ENDS_WITH", + Eq: "EQ", + Exists: "EXISTS", + Gt: "GT", + Gte: "GTE", + Includes: "INCLUDES", + IsAfter: "IS_AFTER", + IsBefore: "IS_BEFORE", + Lt: "LT", + Lte: "LTE", + Neq: "NEQ", + Omit: "OMIT", + StartsWith: "STARTS_WITH", +} as const; diff --git a/src/api/resources/audiences/types/Filter.ts b/src/api/resources/audiences/types/Filter.ts new file mode 100644 index 0000000..0c8a9eb --- /dev/null +++ b/src/api/resources/audiences/types/Filter.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Filter = Courier.SingleFilterConfig | Courier.NestedFilterConfig; diff --git a/src/api/resources/audiences/types/FilterConfig.ts b/src/api/resources/audiences/types/FilterConfig.ts new file mode 100644 index 0000000..6929022 --- /dev/null +++ b/src/api/resources/audiences/types/FilterConfig.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type FilterConfig = Courier.SingleFilterConfig | Courier.NestedFilterConfig; diff --git a/src/api/resources/audiences/types/LogicalOperator.ts b/src/api/resources/audiences/types/LogicalOperator.ts new file mode 100644 index 0000000..78bff48 --- /dev/null +++ b/src/api/resources/audiences/types/LogicalOperator.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type LogicalOperator = "AND" | "OR"; + +export const LogicalOperator = { + And: "AND", + Or: "OR", +} as const; diff --git a/src/api/resources/audiences/types/NestedFilterConfig.ts b/src/api/resources/audiences/types/NestedFilterConfig.ts new file mode 100644 index 0000000..a6fa250 --- /dev/null +++ b/src/api/resources/audiences/types/NestedFilterConfig.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * The operator to use for filtering + */ +export interface NestedFilterConfig extends Courier.BaseFilterConfig { + rules: Courier.FilterConfig[]; +} diff --git a/src/api/resources/audiences/types/Operator.ts b/src/api/resources/audiences/types/Operator.ts new file mode 100644 index 0000000..d2ebfcd --- /dev/null +++ b/src/api/resources/audiences/types/Operator.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Operator = Courier.ComparisonOperator | Courier.LogicalOperator; diff --git a/src/api/resources/audiences/types/SingleFilterConfig.ts b/src/api/resources/audiences/types/SingleFilterConfig.ts new file mode 100644 index 0000000..9be1015 --- /dev/null +++ b/src/api/resources/audiences/types/SingleFilterConfig.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * A single filter to use for filtering + */ +export interface SingleFilterConfig extends Courier.BaseFilterConfig { + /** The value to use for filtering */ + value: string; + /** The attribe name from profile whose value will be operated against the filter value */ + path: string; +} diff --git a/src/api/resources/audiences/types/index.ts b/src/api/resources/audiences/types/index.ts new file mode 100644 index 0000000..64f2753 --- /dev/null +++ b/src/api/resources/audiences/types/index.ts @@ -0,0 +1,15 @@ +export * from "./AudienceRequest"; +export * from "./Filter"; +export * from "./Operator"; +export * from "./BaseFilterConfig"; +export * from "./FilterConfig"; +export * from "./SingleFilterConfig"; +export * from "./NestedFilterConfig"; +export * from "./ComparisonOperator"; +export * from "./LogicalOperator"; +export * from "./Audience"; +export * from "./AudienceMember"; +export * from "./AudienceListResponse"; +export * from "./AudienceMemberGetResponse"; +export * from "./AudienceMemberListResponse"; +export * from "./AudiencePutResponse"; diff --git a/src/api/resources/auditEvents/client/Client.ts b/src/api/resources/auditEvents/client/Client.ts new file mode 100644 index 0000000..78e965d --- /dev/null +++ b/src/api/resources/auditEvents/client/Client.ts @@ -0,0 +1,138 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace AuditEvents { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } +} + +export class AuditEvents { + constructor(protected readonly _options: AuditEvents.Options) {} + + /** + * Fetch the list of audit events + */ + public async list( + request: Courier.ListAuditEventsRequest = {}, + requestOptions?: AuditEvents.RequestOptions + ): Promise { + const { cursor } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/audit-events" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.ListAuditEventsResponse; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Fetch a specific audit event by ID. + */ + public async get(auditEventId: string, requestOptions?: AuditEvents.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/audit-events/${auditEventId}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.AuditEvent; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/auditEvents/client/index.ts b/src/api/resources/auditEvents/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/resources/auditEvents/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/resources/auditEvents/client/requests/ListAuditEventsRequest.ts b/src/api/resources/auditEvents/client/requests/ListAuditEventsRequest.ts new file mode 100644 index 0000000..59fe01b --- /dev/null +++ b/src/api/resources/auditEvents/client/requests/ListAuditEventsRequest.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListAuditEventsRequest { + /** + * A unique identifier that allows for fetching the next set of audit events. + * + */ + cursor?: string; +} diff --git a/src/api/resources/auditEvents/client/requests/index.ts b/src/api/resources/auditEvents/client/requests/index.ts new file mode 100644 index 0000000..b860183 --- /dev/null +++ b/src/api/resources/auditEvents/client/requests/index.ts @@ -0,0 +1 @@ +export { ListAuditEventsRequest } from "./ListAuditEventsRequest"; diff --git a/src/api/resources/auditEvents/index.ts b/src/api/resources/auditEvents/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/auditEvents/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/auditEvents/types/Actor.ts b/src/api/resources/auditEvents/types/Actor.ts new file mode 100644 index 0000000..22bf13c --- /dev/null +++ b/src/api/resources/auditEvents/types/Actor.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Actor { + id?: string; + email?: string; +} diff --git a/src/api/resources/auditEvents/types/AuditEvent.ts b/src/api/resources/auditEvents/types/AuditEvent.ts new file mode 100644 index 0000000..1da72f7 --- /dev/null +++ b/src/api/resources/auditEvents/types/AuditEvent.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AuditEvent { + actor?: Courier.Actor; + target?: Courier.Target; + auditEventId: string; + source: string; + timestamp: string; + type: string; +} diff --git a/src/api/resources/auditEvents/types/GetAuditEventParams.ts b/src/api/resources/auditEvents/types/GetAuditEventParams.ts new file mode 100644 index 0000000..dd15ce5 --- /dev/null +++ b/src/api/resources/auditEvents/types/GetAuditEventParams.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetAuditEventParams { + auditEventId: string; +} diff --git a/src/api/resources/auditEvents/types/ListAuditEventsParams.ts b/src/api/resources/auditEvents/types/ListAuditEventsParams.ts new file mode 100644 index 0000000..a5d9c39 --- /dev/null +++ b/src/api/resources/auditEvents/types/ListAuditEventsParams.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListAuditEventsParams { + cursor?: string; +} diff --git a/src/api/resources/auditEvents/types/ListAuditEventsResponse.ts b/src/api/resources/auditEvents/types/ListAuditEventsResponse.ts new file mode 100644 index 0000000..ebb58e1 --- /dev/null +++ b/src/api/resources/auditEvents/types/ListAuditEventsResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListAuditEventsResponse { + paging: Courier.Paging; + results: Courier.AuditEvent[]; +} diff --git a/src/api/resources/auditEvents/types/Target.ts b/src/api/resources/auditEvents/types/Target.ts new file mode 100644 index 0000000..7ac2315 --- /dev/null +++ b/src/api/resources/auditEvents/types/Target.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Target { + id?: string; + email?: string; +} diff --git a/src/api/resources/auditEvents/types/index.ts b/src/api/resources/auditEvents/types/index.ts new file mode 100644 index 0000000..c402f20 --- /dev/null +++ b/src/api/resources/auditEvents/types/index.ts @@ -0,0 +1,6 @@ +export * from "./ListAuditEventsParams"; +export * from "./GetAuditEventParams"; +export * from "./ListAuditEventsResponse"; +export * from "./Actor"; +export * from "./Target"; +export * from "./AuditEvent"; diff --git a/src/api/resources/authTokens/client/Client.ts b/src/api/resources/authTokens/client/Client.ts new file mode 100644 index 0000000..f18f853 --- /dev/null +++ b/src/api/resources/authTokens/client/Client.ts @@ -0,0 +1,96 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace AuthTokens { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class AuthTokens { + constructor(protected readonly _options: AuthTokens.Options) {} + + /** + * Returns a new access token. + */ + public async issueToken( + request: Courier.AuthIssueTokenParameters, + requestOptions?: AuthTokens.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/auth/issue-token" + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.AuthIssueTokenResponse; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/authTokens/client/index.ts b/src/api/resources/authTokens/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/authTokens/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/authTokens/index.ts b/src/api/resources/authTokens/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/authTokens/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/authTokens/types/AuthIssueTokenParameters.ts b/src/api/resources/authTokens/types/AuthIssueTokenParameters.ts new file mode 100644 index 0000000..1c151f6 --- /dev/null +++ b/src/api/resources/authTokens/types/AuthIssueTokenParameters.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AuthIssueTokenParameters { + scope: string; + expiresIn: string; +} diff --git a/src/api/resources/authTokens/types/AuthIssueTokenResponse.ts b/src/api/resources/authTokens/types/AuthIssueTokenResponse.ts new file mode 100644 index 0000000..d5ea5a8 --- /dev/null +++ b/src/api/resources/authTokens/types/AuthIssueTokenResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AuthIssueTokenResponse { + token?: string; +} diff --git a/src/api/resources/authTokens/types/index.ts b/src/api/resources/authTokens/types/index.ts new file mode 100644 index 0000000..e914807 --- /dev/null +++ b/src/api/resources/authTokens/types/index.ts @@ -0,0 +1,2 @@ +export * from "./AuthIssueTokenParameters"; +export * from "./AuthIssueTokenResponse"; diff --git a/src/api/resources/automations/client/Client.ts b/src/api/resources/automations/client/Client.ts new file mode 100644 index 0000000..1ca58e3 --- /dev/null +++ b/src/api/resources/automations/client/Client.ts @@ -0,0 +1,150 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; +import * as Courier from "../../.."; + +export declare namespace Automations { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class Automations { + constructor(protected readonly _options: Automations.Options) {} + + /** + * Invoke an automation run from an automation template. + */ + public async invokeAutomationTemplate( + templateId: string, + requestOptions?: Automations.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/automations/${templateId}/invoke` + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Invoke an ad hoc automation run. This endpoint accepts a JSON payload with a series of automation steps. For information about what steps are available, checkout the ad hoc automation guide [here](https://www.courier.com/docs/automations/steps/). + */ + public async invokeAdHocAutomation( + request: Courier.AutomationAdHocInvokeParams, + requestOptions?: Automations.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/automations/invoke" + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.AutomationInvokeResponse; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/automations/client/index.ts b/src/api/resources/automations/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/automations/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/automations/index.ts b/src/api/resources/automations/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/automations/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/automations/types/Automation.ts b/src/api/resources/automations/types/Automation.ts new file mode 100644 index 0000000..352e7ee --- /dev/null +++ b/src/api/resources/automations/types/Automation.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Automation { + cancelation_token?: string; + steps: Courier.AutomationStepOption[]; +} diff --git a/src/api/resources/automations/types/AutomationAdHocInvokeParams.ts b/src/api/resources/automations/types/AutomationAdHocInvokeParams.ts new file mode 100644 index 0000000..9216ea8 --- /dev/null +++ b/src/api/resources/automations/types/AutomationAdHocInvokeParams.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationAdHocInvokeParams extends Courier.AutomationInvokeParams { + automation: Courier.Automation; +} diff --git a/src/api/resources/automations/types/AutomationCancelStep.ts b/src/api/resources/automations/types/AutomationCancelStep.ts new file mode 100644 index 0000000..7fd9c89 --- /dev/null +++ b/src/api/resources/automations/types/AutomationCancelStep.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationCancelStep extends Courier.AutomationStep { + action: "cancel"; + cancelation_token?: string; +} diff --git a/src/api/resources/automations/types/AutomationDelayStep.ts b/src/api/resources/automations/types/AutomationDelayStep.ts new file mode 100644 index 0000000..2034890 --- /dev/null +++ b/src/api/resources/automations/types/AutomationDelayStep.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationDelayStep extends Courier.AutomationStep { + action: "delay"; + until?: string; +} diff --git a/src/api/resources/automations/types/AutomationInvokeParams.ts b/src/api/resources/automations/types/AutomationInvokeParams.ts new file mode 100644 index 0000000..d9c7c4f --- /dev/null +++ b/src/api/resources/automations/types/AutomationInvokeParams.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationInvokeParams { + brand?: string; + data?: Record; + profile?: Courier.Profile | undefined; + recipient?: string; + template?: string; +} diff --git a/src/api/resources/automations/types/AutomationInvokeResponse.ts b/src/api/resources/automations/types/AutomationInvokeResponse.ts new file mode 100644 index 0000000..9289e15 --- /dev/null +++ b/src/api/resources/automations/types/AutomationInvokeResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AutomationInvokeResponse { + runId: string; +} diff --git a/src/api/resources/automations/types/AutomationInvokeStep.ts b/src/api/resources/automations/types/AutomationInvokeStep.ts new file mode 100644 index 0000000..5476502 --- /dev/null +++ b/src/api/resources/automations/types/AutomationInvokeStep.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationInvokeStep extends Courier.AutomationStep { + action: "invoke"; + template: string; +} diff --git a/src/api/resources/automations/types/AutomationInvokeTemplateParams.ts b/src/api/resources/automations/types/AutomationInvokeTemplateParams.ts new file mode 100644 index 0000000..20b4823 --- /dev/null +++ b/src/api/resources/automations/types/AutomationInvokeTemplateParams.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationInvokeTemplateParams extends Courier.AutomationInvokeParams { + templateId: string; +} diff --git a/src/api/resources/automations/types/AutomationRunContext.ts b/src/api/resources/automations/types/AutomationRunContext.ts new file mode 100644 index 0000000..d5947be --- /dev/null +++ b/src/api/resources/automations/types/AutomationRunContext.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationRunContext { + brand?: string; + data?: any; + profile?: Courier.Profile | undefined; + template?: string; + recipient?: string; +} diff --git a/src/api/resources/automations/types/AutomationSendListStep.ts b/src/api/resources/automations/types/AutomationSendListStep.ts new file mode 100644 index 0000000..da86a52 --- /dev/null +++ b/src/api/resources/automations/types/AutomationSendListStep.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationSendListStep extends Courier.AutomationStep { + action: "send-list"; + brand?: string; + data?: Record; + list: string; + override?: Record; + template?: string; +} diff --git a/src/api/resources/automations/types/AutomationSendStep.ts b/src/api/resources/automations/types/AutomationSendStep.ts new file mode 100644 index 0000000..2d8a6c7 --- /dev/null +++ b/src/api/resources/automations/types/AutomationSendStep.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationSendStep extends Courier.AutomationStep { + action: "send"; + brand?: string; + data?: Record; + override?: Record; + profile?: any; + recipient?: string; + template?: string; +} diff --git a/src/api/resources/automations/types/AutomationStep.ts b/src/api/resources/automations/types/AutomationStep.ts new file mode 100644 index 0000000..a990595 --- /dev/null +++ b/src/api/resources/automations/types/AutomationStep.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AutomationStep { + if?: string; + ref?: string; +} diff --git a/src/api/resources/automations/types/AutomationStepAction.ts b/src/api/resources/automations/types/AutomationStepAction.ts new file mode 100644 index 0000000..fe71177 --- /dev/null +++ b/src/api/resources/automations/types/AutomationStepAction.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type AutomationStepAction = "cancel" | "delay" | "invoke" | "send" | "send-list" | "update-profile"; + +export const AutomationStepAction = { + Cancel: "cancel", + Delay: "delay", + Invoke: "invoke", + Send: "send", + SendList: "send-list", + UpdateProfile: "update-profile", +} as const; diff --git a/src/api/resources/automations/types/AutomationStepOption.ts b/src/api/resources/automations/types/AutomationStepOption.ts new file mode 100644 index 0000000..60fc014 --- /dev/null +++ b/src/api/resources/automations/types/AutomationStepOption.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type AutomationStepOption = + | Courier.AutomationCancelStep + | Courier.AutomationDelayStep + | Courier.AutomationInvokeStep + | Courier.AutomationSendStep + | Courier.AutomationV2SendStep + | Courier.AutomationSendListStep + | Courier.AutomationUpdateProfileStep; diff --git a/src/api/resources/automations/types/AutomationUpdateProfileStep.ts b/src/api/resources/automations/types/AutomationUpdateProfileStep.ts new file mode 100644 index 0000000..d8d5a4c --- /dev/null +++ b/src/api/resources/automations/types/AutomationUpdateProfileStep.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationUpdateProfileStep { + action: "update-profile"; + recipient_id: string; + profile?: Courier.Profile; + merge: Courier.MergeAlgorithm; +} diff --git a/src/api/resources/automations/types/AutomationV2SendStep.ts b/src/api/resources/automations/types/AutomationV2SendStep.ts new file mode 100644 index 0000000..de54ca2 --- /dev/null +++ b/src/api/resources/automations/types/AutomationV2SendStep.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AutomationV2SendStep extends Courier.AutomationStep { + action: "send"; + message: Courier.Message; +} diff --git a/src/api/resources/automations/types/MergeAlgorithm.ts b/src/api/resources/automations/types/MergeAlgorithm.ts new file mode 100644 index 0000000..80afce2 --- /dev/null +++ b/src/api/resources/automations/types/MergeAlgorithm.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MergeAlgorithm = "replace" | "none" | "overwrite" | "soft-merge"; + +export const MergeAlgorithm = { + Replace: "replace", + None: "none", + Overwrite: "overwrite", + SoftMerge: "soft-merge", +} as const; diff --git a/src/api/resources/automations/types/Profile.ts b/src/api/resources/automations/types/Profile.ts new file mode 100644 index 0000000..8000ec2 --- /dev/null +++ b/src/api/resources/automations/types/Profile.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type Profile = any; diff --git a/src/api/resources/automations/types/index.ts b/src/api/resources/automations/types/index.ts new file mode 100644 index 0000000..9fe41c0 --- /dev/null +++ b/src/api/resources/automations/types/index.ts @@ -0,0 +1,18 @@ +export * from "./AutomationStepAction"; +export * from "./MergeAlgorithm"; +export * from "./AutomationRunContext"; +export * from "./AutomationStep"; +export * from "./AutomationCancelStep"; +export * from "./AutomationDelayStep"; +export * from "./AutomationInvokeStep"; +export * from "./AutomationSendStep"; +export * from "./AutomationV2SendStep"; +export * from "./AutomationSendListStep"; +export * from "./AutomationUpdateProfileStep"; +export * from "./AutomationStepOption"; +export * from "./Automation"; +export * from "./AutomationInvokeParams"; +export * from "./AutomationAdHocInvokeParams"; +export * from "./AutomationInvokeTemplateParams"; +export * from "./AutomationInvokeResponse"; +export * from "./Profile"; diff --git a/src/api/resources/brands/client/Client.ts b/src/api/resources/brands/client/Client.ts new file mode 100644 index 0000000..0b05677 --- /dev/null +++ b/src/api/resources/brands/client/Client.ts @@ -0,0 +1,261 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Brands { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class Brands { + constructor(protected readonly _options: Brands.Options) {} + + /** + * @throws {@link Courier.BadRequestError} + * @throws {@link Courier.PaymentRequiredError} + * @throws {@link Courier.AlreadyExistsError} + */ + public async create( + request: Courier.BrandParameters, + requestOptions?: Brands.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/brands" + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.Brand; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + case 402: + throw new Courier.PaymentRequiredError(_response.error.body as Courier.PaymentRequired); + case 409: + throw new Courier.AlreadyExistsError(_response.error.body as Courier.AlreadyExists); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Fetch a specific brand by brand ID. + */ + public async get(brandId: string, requestOptions?: Brands.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/brands/${brandId}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.Brand; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Get the list of brands. + */ + public async list( + request: Courier.ListBrandsRequest = {}, + requestOptions?: Brands.RequestOptions + ): Promise { + const { cursor } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/brands" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.BrandsResponse; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Delete a brand by brand ID. + * @throws {@link Courier.ConflictError} + */ + public async delete(brandId: string, requestOptions?: Brands.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/brands/${brandId}` + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 409: + throw new Courier.ConflictError(_response.error.body as Courier.Conflict); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/brands/client/index.ts b/src/api/resources/brands/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/resources/brands/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/resources/brands/client/requests/ListBrandsRequest.ts b/src/api/resources/brands/client/requests/ListBrandsRequest.ts new file mode 100644 index 0000000..2d8741f --- /dev/null +++ b/src/api/resources/brands/client/requests/ListBrandsRequest.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListBrandsRequest { + /** + * A unique identifier that allows for fetching the next set of brands. + */ + cursor?: string; +} diff --git a/src/api/resources/brands/client/requests/index.ts b/src/api/resources/brands/client/requests/index.ts new file mode 100644 index 0000000..fec68a2 --- /dev/null +++ b/src/api/resources/brands/client/requests/index.ts @@ -0,0 +1 @@ +export { ListBrandsRequest } from "./ListBrandsRequest"; diff --git a/src/api/resources/brands/index.ts b/src/api/resources/brands/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/brands/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/brands/types/Brand.ts b/src/api/resources/brands/types/Brand.ts new file mode 100644 index 0000000..8017ca8 --- /dev/null +++ b/src/api/resources/brands/types/Brand.ts @@ -0,0 +1,22 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Brand { + /** The date/time of when the brand was created. Represented in milliseconds since Unix epoch. */ + created: number; + /** Brand Identifier */ + id?: string; + /** Brand name */ + name: string; + /** The date/time of when the brand was published. Represented in milliseconds since Unix epoch. */ + published: number; + settings: Courier.BrandSettings; + /** The date/time of when the brand was updated. Represented in milliseconds since Unix epoch. */ + updated: number; + snippets?: Courier.BrandSnippets; + /** The version identifier for the brand */ + version: string; +} diff --git a/src/api/resources/brands/types/BrandColors.ts b/src/api/resources/brands/types/BrandColors.ts new file mode 100644 index 0000000..842948f --- /dev/null +++ b/src/api/resources/brands/types/BrandColors.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BrandColors { + primary?: string; + secondary?: string; + tertiary?: string; +} diff --git a/src/api/resources/brands/types/BrandGetAllResponse.ts b/src/api/resources/brands/types/BrandGetAllResponse.ts new file mode 100644 index 0000000..2e897a4 --- /dev/null +++ b/src/api/resources/brands/types/BrandGetAllResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandGetAllResponse { + paging: Courier.Paging; + results: Courier.Brand[]; +} diff --git a/src/api/resources/brands/types/BrandParameters.ts b/src/api/resources/brands/types/BrandParameters.ts new file mode 100644 index 0000000..6cf6822 --- /dev/null +++ b/src/api/resources/brands/types/BrandParameters.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandParameters { + id?: string; + /** The name of the brand. */ + name: string; + settings: Courier.BrandSettings; + snippets?: Courier.BrandSnippets; +} diff --git a/src/api/resources/brands/types/BrandPutParameters.ts b/src/api/resources/brands/types/BrandPutParameters.ts new file mode 100644 index 0000000..7248b84 --- /dev/null +++ b/src/api/resources/brands/types/BrandPutParameters.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandPutParameters { + id: string; + /** The name of the brand. */ + name: string; + settings: Courier.BrandSettings; + snippets?: Courier.BrandSnippets; +} diff --git a/src/api/resources/brands/types/BrandSettings.ts b/src/api/resources/brands/types/BrandSettings.ts new file mode 100644 index 0000000..7c06ba8 --- /dev/null +++ b/src/api/resources/brands/types/BrandSettings.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandSettings { + colors?: Courier.BrandColors; + email?: Courier.Email; +} diff --git a/src/api/resources/brands/types/BrandSnippet.ts b/src/api/resources/brands/types/BrandSnippet.ts new file mode 100644 index 0000000..9cc9e93 --- /dev/null +++ b/src/api/resources/brands/types/BrandSnippet.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BrandSnippet { + format: "handlebars"; + name: string; + value: string; +} diff --git a/src/api/resources/brands/types/BrandSnippets.ts b/src/api/resources/brands/types/BrandSnippets.ts new file mode 100644 index 0000000..8a32d95 --- /dev/null +++ b/src/api/resources/brands/types/BrandSnippets.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandSnippets { + items: Courier.BrandSnippet[]; +} diff --git a/src/api/resources/brands/types/BrandsResponse.ts b/src/api/resources/brands/types/BrandsResponse.ts new file mode 100644 index 0000000..74f1a3e --- /dev/null +++ b/src/api/resources/brands/types/BrandsResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandsResponse { + paging: Courier.Paging; + results: Courier.Brand[]; +} diff --git a/src/api/resources/brands/types/index.ts b/src/api/resources/brands/types/index.ts new file mode 100644 index 0000000..c89128c --- /dev/null +++ b/src/api/resources/brands/types/index.ts @@ -0,0 +1,9 @@ +export * from "./Brand"; +export * from "./BrandParameters"; +export * from "./BrandPutParameters"; +export * from "./BrandGetAllResponse"; +export * from "./BrandsResponse"; +export * from "./BrandSnippet"; +export * from "./BrandSnippets"; +export * from "./BrandSettings"; +export * from "./BrandColors"; diff --git a/src/api/resources/bulk/client/Client.ts b/src/api/resources/bulk/client/Client.ts new file mode 100644 index 0000000..073e148 --- /dev/null +++ b/src/api/resources/bulk/client/Client.ts @@ -0,0 +1,326 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Bulk { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class Bulk { + constructor(protected readonly _options: Bulk.Options) {} + + /** + * @throws {@link Courier.BadRequestError} + */ + public async create( + request: Courier.BulkCreateJobParams, + requestOptions?: Bulk.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/bulk" + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.BulkCreateJobResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Ingest user data into a Bulk Job + */ + public async ingestUsers( + jobId: string, + request: Courier.BulkIngestUsersParams, + requestOptions?: Bulk.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/bulk/${jobId}` + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Run a bulk job + * @throws {@link Courier.BadRequestError} + */ + public async runJob( + jobId: string, + request: Courier.BulkRunJobParams, + requestOptions?: Bulk.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/bulk/${jobId}/run` + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Get a bulk job + * @throws {@link Courier.BadRequestError} + */ + public async getJob(jobId: string, requestOptions?: Bulk.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/bulk/${jobId}/run` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.BulkGetJobResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Get Bulk Job Users + * @throws {@link Courier.BadRequestError} + */ + public async getUsers( + jobId: string, + requestOptions?: Bulk.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/bulk/${jobId}/users` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.BulkGetJobUsersResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/bulk/client/index.ts b/src/api/resources/bulk/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/bulk/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/bulk/index.ts b/src/api/resources/bulk/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/bulk/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/bulk/types/BulkCreateJobParams.ts b/src/api/resources/bulk/types/BulkCreateJobParams.ts new file mode 100644 index 0000000..9d088d5 --- /dev/null +++ b/src/api/resources/bulk/types/BulkCreateJobParams.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BulkCreateJobParams { + message: Courier.InboundBulkMessage; +} diff --git a/src/api/resources/bulk/types/BulkCreateJobResponse.ts b/src/api/resources/bulk/types/BulkCreateJobResponse.ts new file mode 100644 index 0000000..5f7a9cf --- /dev/null +++ b/src/api/resources/bulk/types/BulkCreateJobResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BulkCreateJobResponse { + jobId: string; +} diff --git a/src/api/resources/bulk/types/BulkGetJobParams.ts b/src/api/resources/bulk/types/BulkGetJobParams.ts new file mode 100644 index 0000000..9c4cfff --- /dev/null +++ b/src/api/resources/bulk/types/BulkGetJobParams.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BulkGetJobParams { + jobId: string; +} diff --git a/src/api/resources/bulk/types/BulkGetJobResponse.ts b/src/api/resources/bulk/types/BulkGetJobResponse.ts new file mode 100644 index 0000000..c73263a --- /dev/null +++ b/src/api/resources/bulk/types/BulkGetJobResponse.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BulkGetJobResponse { + job: Courier.JobDetails; +} diff --git a/src/api/resources/bulk/types/BulkGetJobUsersParams.ts b/src/api/resources/bulk/types/BulkGetJobUsersParams.ts new file mode 100644 index 0000000..61de970 --- /dev/null +++ b/src/api/resources/bulk/types/BulkGetJobUsersParams.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BulkGetJobUsersParams { + jobId: string; + cursor?: string; +} diff --git a/src/api/resources/bulk/types/BulkGetJobUsersResponse.ts b/src/api/resources/bulk/types/BulkGetJobUsersResponse.ts new file mode 100644 index 0000000..a08c813 --- /dev/null +++ b/src/api/resources/bulk/types/BulkGetJobUsersResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BulkGetJobUsersResponse { + items: Courier.BulkMessageUserResponse[]; + paging: Courier.Paging; +} diff --git a/src/api/resources/bulk/types/BulkIngestError.ts b/src/api/resources/bulk/types/BulkIngestError.ts new file mode 100644 index 0000000..ff11768 --- /dev/null +++ b/src/api/resources/bulk/types/BulkIngestError.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BulkIngestError { + user?: any; + error?: any; +} diff --git a/src/api/resources/bulk/types/BulkIngestUsersParams.ts b/src/api/resources/bulk/types/BulkIngestUsersParams.ts new file mode 100644 index 0000000..da12ba9 --- /dev/null +++ b/src/api/resources/bulk/types/BulkIngestUsersParams.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BulkIngestUsersParams { + jobId: string; + users: Courier.InboundBulkMessageUser[]; +} diff --git a/src/api/resources/bulk/types/BulkIngestUsersResponse.ts b/src/api/resources/bulk/types/BulkIngestUsersResponse.ts new file mode 100644 index 0000000..72afc6c --- /dev/null +++ b/src/api/resources/bulk/types/BulkIngestUsersResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BulkIngestUsersResponse { + total: number; + errors?: Courier.BulkIngestError[]; +} diff --git a/src/api/resources/bulk/types/BulkJobStatus.ts b/src/api/resources/bulk/types/BulkJobStatus.ts new file mode 100644 index 0000000..a7a8302 --- /dev/null +++ b/src/api/resources/bulk/types/BulkJobStatus.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type BulkJobStatus = "CREATED" | "PROCESSING" | "COMPLETED" | "ERROR"; + +export const BulkJobStatus = { + Created: "CREATED", + Processing: "PROCESSING", + Completed: "COMPLETED", + Error: "ERROR", +} as const; diff --git a/src/api/resources/bulk/types/BulkJobUserStatus.ts b/src/api/resources/bulk/types/BulkJobUserStatus.ts new file mode 100644 index 0000000..4725291 --- /dev/null +++ b/src/api/resources/bulk/types/BulkJobUserStatus.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type BulkJobUserStatus = "PENDING" | "ENQUEUED" | "ERROR"; + +export const BulkJobUserStatus = { + Pending: "PENDING", + Enqueued: "ENQUEUED", + Error: "ERROR", +} as const; diff --git a/src/api/resources/bulk/types/BulkMessageUserResponse.ts b/src/api/resources/bulk/types/BulkMessageUserResponse.ts new file mode 100644 index 0000000..a7da91d --- /dev/null +++ b/src/api/resources/bulk/types/BulkMessageUserResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BulkMessageUserResponse extends Courier.InboundBulkMessageUser { + status: Courier.BulkJobUserStatus; + messageId?: string; +} diff --git a/src/api/resources/bulk/types/BulkRunJobParams.ts b/src/api/resources/bulk/types/BulkRunJobParams.ts new file mode 100644 index 0000000..ecbe816 --- /dev/null +++ b/src/api/resources/bulk/types/BulkRunJobParams.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BulkRunJobParams { + jobId: string; +} diff --git a/src/api/resources/bulk/types/InboundBulkMessage.ts b/src/api/resources/bulk/types/InboundBulkMessage.ts new file mode 100644 index 0000000..49ee6ea --- /dev/null +++ b/src/api/resources/bulk/types/InboundBulkMessage.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface InboundBulkMessage extends Courier.InboundBulkMessageApiV1 { + message?: Courier.InboundBulkMessageApiV2 | undefined; +} diff --git a/src/api/resources/bulk/types/InboundBulkMessageApiV1.ts b/src/api/resources/bulk/types/InboundBulkMessageApiV1.ts new file mode 100644 index 0000000..bd83664 --- /dev/null +++ b/src/api/resources/bulk/types/InboundBulkMessageApiV1.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface InboundBulkMessageApiV1 { + /** A unique identifier that represents the brand that should be used for rendering the notification. */ + brand?: string; + /** JSON that includes any data you want to pass to a message template. The data will populate the corresponding template variables. */ + data?: any; + event: string; + locale?: string; + /** JSON that is merged into the request sent by Courier to the provider to override properties or to gain access to features in the provider API that are not natively supported by Courier. */ + override?: any; +} diff --git a/src/api/resources/bulk/types/InboundBulkMessageApiV2.ts b/src/api/resources/bulk/types/InboundBulkMessageApiV2.ts new file mode 100644 index 0000000..1b8e7e1 --- /dev/null +++ b/src/api/resources/bulk/types/InboundBulkMessageApiV2.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type InboundBulkMessageApiV2 = any; diff --git a/src/api/resources/bulk/types/InboundBulkMessageUser.ts b/src/api/resources/bulk/types/InboundBulkMessageUser.ts new file mode 100644 index 0000000..80fd9b0 --- /dev/null +++ b/src/api/resources/bulk/types/InboundBulkMessageUser.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface InboundBulkMessageUser { + preferences?: Courier.RecipientPreferences; + profile?: any; + recipient?: string; + data?: any; + to?: Courier.UserRecipient; +} diff --git a/src/api/resources/bulk/types/JobDetails.ts b/src/api/resources/bulk/types/JobDetails.ts new file mode 100644 index 0000000..2eb7f58 --- /dev/null +++ b/src/api/resources/bulk/types/JobDetails.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface JobDetails { + definition: Courier.InboundBulkMessage; + enqueued: number; + failures: number; + received: number; + status: Courier.BulkJobStatus; +} diff --git a/src/api/resources/bulk/types/index.ts b/src/api/resources/bulk/types/index.ts new file mode 100644 index 0000000..d72a9dd --- /dev/null +++ b/src/api/resources/bulk/types/index.ts @@ -0,0 +1,18 @@ +export * from "./InboundBulkMessageApiV1"; +export * from "./InboundBulkMessageApiV2"; +export * from "./InboundBulkMessage"; +export * from "./BulkCreateJobParams"; +export * from "./BulkCreateJobResponse"; +export * from "./InboundBulkMessageUser"; +export * from "./BulkIngestUsersParams"; +export * from "./BulkIngestError"; +export * from "./BulkIngestUsersResponse"; +export * from "./BulkRunJobParams"; +export * from "./BulkGetJobParams"; +export * from "./BulkJobStatus"; +export * from "./BulkJobUserStatus"; +export * from "./BulkGetJobResponse"; +export * from "./JobDetails"; +export * from "./BulkGetJobUsersParams"; +export * from "./BulkMessageUserResponse"; +export * from "./BulkGetJobUsersResponse"; diff --git a/src/api/resources/commons/errors/AlreadyExistsError.ts b/src/api/resources/commons/errors/AlreadyExistsError.ts new file mode 100644 index 0000000..8bb54e0 --- /dev/null +++ b/src/api/resources/commons/errors/AlreadyExistsError.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as errors from "../../../../errors"; +import * as Courier from "../../.."; + +export class AlreadyExistsError extends errors.CourierError { + constructor(body: Courier.AlreadyExists) { + super({ + message: "AlreadyExistsError", + statusCode: 409, + body: body, + }); + Object.setPrototypeOf(this, AlreadyExistsError.prototype); + } +} diff --git a/src/api/resources/commons/errors/BadRequestError.ts b/src/api/resources/commons/errors/BadRequestError.ts new file mode 100644 index 0000000..0fd4c58 --- /dev/null +++ b/src/api/resources/commons/errors/BadRequestError.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as errors from "../../../../errors"; +import * as Courier from "../../.."; + +export class BadRequestError extends errors.CourierError { + constructor(body: Courier.BadRequest) { + super({ + message: "BadRequestError", + statusCode: 400, + body: body, + }); + Object.setPrototypeOf(this, BadRequestError.prototype); + } +} diff --git a/src/api/resources/commons/errors/ConflictError.ts b/src/api/resources/commons/errors/ConflictError.ts new file mode 100644 index 0000000..79ee3ce --- /dev/null +++ b/src/api/resources/commons/errors/ConflictError.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as errors from "../../../../errors"; +import * as Courier from "../../.."; + +export class ConflictError extends errors.CourierError { + constructor(body: Courier.Conflict) { + super({ + message: "ConflictError", + statusCode: 409, + body: body, + }); + Object.setPrototypeOf(this, ConflictError.prototype); + } +} diff --git a/src/api/resources/commons/errors/MessageNotFoundError.ts b/src/api/resources/commons/errors/MessageNotFoundError.ts new file mode 100644 index 0000000..65c1625 --- /dev/null +++ b/src/api/resources/commons/errors/MessageNotFoundError.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as errors from "../../../../errors"; +import * as Courier from "../../.."; + +export class MessageNotFoundError extends errors.CourierError { + constructor(body: Courier.MessageNotFound) { + super({ + message: "MessageNotFoundError", + statusCode: 404, + body: body, + }); + Object.setPrototypeOf(this, MessageNotFoundError.prototype); + } +} diff --git a/src/api/resources/commons/errors/NotFoundError.ts b/src/api/resources/commons/errors/NotFoundError.ts new file mode 100644 index 0000000..344eda5 --- /dev/null +++ b/src/api/resources/commons/errors/NotFoundError.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as errors from "../../../../errors"; +import * as Courier from "../../.."; + +export class NotFoundError extends errors.CourierError { + constructor(body: Courier.NotFound) { + super({ + message: "NotFoundError", + statusCode: 404, + body: body, + }); + Object.setPrototypeOf(this, NotFoundError.prototype); + } +} diff --git a/src/api/resources/commons/errors/PaymentRequiredError.ts b/src/api/resources/commons/errors/PaymentRequiredError.ts new file mode 100644 index 0000000..8889167 --- /dev/null +++ b/src/api/resources/commons/errors/PaymentRequiredError.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as errors from "../../../../errors"; +import * as Courier from "../../.."; + +export class PaymentRequiredError extends errors.CourierError { + constructor(body: Courier.PaymentRequired) { + super({ + message: "PaymentRequiredError", + statusCode: 402, + body: body, + }); + Object.setPrototypeOf(this, PaymentRequiredError.prototype); + } +} diff --git a/src/api/resources/commons/errors/index.ts b/src/api/resources/commons/errors/index.ts new file mode 100644 index 0000000..24b1d52 --- /dev/null +++ b/src/api/resources/commons/errors/index.ts @@ -0,0 +1,6 @@ +export * from "./BadRequestError"; +export * from "./PaymentRequiredError"; +export * from "./AlreadyExistsError"; +export * from "./ConflictError"; +export * from "./NotFoundError"; +export * from "./MessageNotFoundError"; diff --git a/src/api/resources/commons/index.ts b/src/api/resources/commons/index.ts new file mode 100644 index 0000000..708eabf --- /dev/null +++ b/src/api/resources/commons/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./errors"; diff --git a/src/api/resources/commons/types/AlreadyExists.ts b/src/api/resources/commons/types/AlreadyExists.ts new file mode 100644 index 0000000..a881f5f --- /dev/null +++ b/src/api/resources/commons/types/AlreadyExists.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AlreadyExists extends Courier.BaseError { + type: "invalid_request_error"; +} diff --git a/src/api/resources/commons/types/BadRequest.ts b/src/api/resources/commons/types/BadRequest.ts new file mode 100644 index 0000000..89e9c0d --- /dev/null +++ b/src/api/resources/commons/types/BadRequest.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BadRequest extends Courier.BaseError { + type: "invalid_request_error"; +} diff --git a/src/api/resources/commons/types/BaseError.ts b/src/api/resources/commons/types/BaseError.ts new file mode 100644 index 0000000..a34b3d5 --- /dev/null +++ b/src/api/resources/commons/types/BaseError.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BaseError { + /** A message describing the error that occurred. */ + message: string; +} diff --git a/src/api/resources/commons/types/ChannelClassification.ts b/src/api/resources/commons/types/ChannelClassification.ts new file mode 100644 index 0000000..21984cc --- /dev/null +++ b/src/api/resources/commons/types/ChannelClassification.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ChannelClassification = "direct_message" | "email" | "push" | "sms"; + +export const ChannelClassification = { + DirectMessage: "direct_message", + Email: "email", + Push: "push", + Sms: "sms", +} as const; diff --git a/src/api/resources/commons/types/ChannelPreference.ts b/src/api/resources/commons/types/ChannelPreference.ts new file mode 100644 index 0000000..87fb5b2 --- /dev/null +++ b/src/api/resources/commons/types/ChannelPreference.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ChannelPreference { + channel: Courier.ChannelClassification; +} diff --git a/src/api/resources/commons/types/Conflict.ts b/src/api/resources/commons/types/Conflict.ts new file mode 100644 index 0000000..9be33ed --- /dev/null +++ b/src/api/resources/commons/types/Conflict.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Conflict extends Courier.BaseError { + type: "invalid_request_error"; +} diff --git a/src/api/resources/commons/types/Email.ts b/src/api/resources/commons/types/Email.ts new file mode 100644 index 0000000..9268db1 --- /dev/null +++ b/src/api/resources/commons/types/Email.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Email { + footer?: any; + header?: any; +} diff --git a/src/api/resources/commons/types/MessageNotFound.ts b/src/api/resources/commons/types/MessageNotFound.ts new file mode 100644 index 0000000..651ad70 --- /dev/null +++ b/src/api/resources/commons/types/MessageNotFound.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface MessageNotFound extends Courier.BaseError { + type: "invalid_request_error"; +} diff --git a/src/api/resources/commons/types/NotFound.ts b/src/api/resources/commons/types/NotFound.ts new file mode 100644 index 0000000..34f2f2c --- /dev/null +++ b/src/api/resources/commons/types/NotFound.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface NotFound extends Courier.BaseError { + type: "invalid_request_error"; +} diff --git a/src/api/resources/commons/types/NotificationPreferenceDetails.ts b/src/api/resources/commons/types/NotificationPreferenceDetails.ts new file mode 100644 index 0000000..07df07d --- /dev/null +++ b/src/api/resources/commons/types/NotificationPreferenceDetails.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface NotificationPreferenceDetails { + status: Courier.PreferenceStatus; + rules?: Courier.Rule[]; + channel_preferences?: Courier.ChannelPreference[]; +} diff --git a/src/api/resources/commons/types/NotificationPreferences.ts b/src/api/resources/commons/types/NotificationPreferences.ts new file mode 100644 index 0000000..0f18ca2 --- /dev/null +++ b/src/api/resources/commons/types/NotificationPreferences.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type NotificationPreferences = Record; diff --git a/src/api/resources/commons/types/Paging.ts b/src/api/resources/commons/types/Paging.ts new file mode 100644 index 0000000..0f3c8d2 --- /dev/null +++ b/src/api/resources/commons/types/Paging.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Paging { + cursor?: string; + more: boolean; +} diff --git a/src/api/resources/commons/types/PaymentRequired.ts b/src/api/resources/commons/types/PaymentRequired.ts new file mode 100644 index 0000000..d280356 --- /dev/null +++ b/src/api/resources/commons/types/PaymentRequired.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface PaymentRequired extends Courier.BaseError { + type: "authorization_error"; +} diff --git a/src/api/resources/commons/types/PreferenceStatus.ts b/src/api/resources/commons/types/PreferenceStatus.ts new file mode 100644 index 0000000..588584e --- /dev/null +++ b/src/api/resources/commons/types/PreferenceStatus.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type PreferenceStatus = "OPTED_IN" | "OPTED_OUT" | "REQUIRED"; + +export const PreferenceStatus = { + OptedIn: "OPTED_IN", + OptedOut: "OPTED_OUT", + Required: "REQUIRED", +} as const; diff --git a/src/api/resources/commons/types/RecipientPreferences.ts b/src/api/resources/commons/types/RecipientPreferences.ts new file mode 100644 index 0000000..f39ba16 --- /dev/null +++ b/src/api/resources/commons/types/RecipientPreferences.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RecipientPreferences { + categories?: Courier.NotificationPreferences; + notifications?: Courier.NotificationPreferences; +} diff --git a/src/api/resources/commons/types/Rule.ts b/src/api/resources/commons/types/Rule.ts new file mode 100644 index 0000000..1c23b42 --- /dev/null +++ b/src/api/resources/commons/types/Rule.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Rule { + start?: string; + until: string; +} diff --git a/src/api/resources/commons/types/index.ts b/src/api/resources/commons/types/index.ts new file mode 100644 index 0000000..dbe9b26 --- /dev/null +++ b/src/api/resources/commons/types/index.ts @@ -0,0 +1,16 @@ +export * from "./Paging"; +export * from "./BaseError"; +export * from "./BadRequest"; +export * from "./PaymentRequired"; +export * from "./AlreadyExists"; +export * from "./Conflict"; +export * from "./NotFound"; +export * from "./MessageNotFound"; +export * from "./Rule"; +export * from "./PreferenceStatus"; +export * from "./ChannelClassification"; +export * from "./ChannelPreference"; +export * from "./NotificationPreferences"; +export * from "./NotificationPreferenceDetails"; +export * from "./RecipientPreferences"; +export * from "./Email"; diff --git a/src/api/resources/index.ts b/src/api/resources/index.ts new file mode 100644 index 0000000..7c09742 --- /dev/null +++ b/src/api/resources/index.ts @@ -0,0 +1,39 @@ +export * as audiences from "./audiences"; +export * from "./audiences/types"; +export * as auditEvents from "./auditEvents"; +export * from "./auditEvents/types"; +export * as authTokens from "./authTokens"; +export * from "./authTokens/types"; +export * as automations from "./automations"; +export * from "./automations/types"; +export * as brands from "./brands"; +export * from "./brands/types"; +export * as commons from "./commons"; +export * from "./commons/types"; +export * as bulk from "./bulk"; +export * from "./bulk/types"; +export * as lists from "./lists"; +export * from "./lists/types"; +export * as messages from "./messages"; +export * from "./messages/types"; +export * as profiles from "./profiles"; +export * from "./profiles/types"; +export * as send from "./send"; +export * from "./send/types"; +export * as templates from "./templates"; +export * from "./templates/types"; +export * as tenants from "./tenants"; +export * from "./tenants/types"; +export * as tokenManagement from "./tokenManagement"; +export * from "./tokenManagement/types"; +export * as userPreferences from "./userPreferences"; +export * from "./userPreferences/types"; +export * from "./commons/errors"; +export * as translations from "./translations"; +export * from "./audiences/client/requests"; +export * from "./auditEvents/client/requests"; +export * from "./brands/client/requests"; +export * from "./lists/client/requests"; +export * from "./messages/client/requests"; +export * from "./profiles/client/requests"; +export * from "./templates/client/requests"; diff --git a/src/api/resources/lists/client/Client.ts b/src/api/resources/lists/client/Client.ts new file mode 100644 index 0000000..c13e5f8 --- /dev/null +++ b/src/api/resources/lists/client/Client.ts @@ -0,0 +1,511 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Lists { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class Lists { + constructor(protected readonly _options: Lists.Options) {} + + /** + * Returns all of the lists, with the ability to filter based on a pattern. + * @throws {@link Courier.BadRequestError} + */ + public async list( + request: Courier.GetAllListsRequest = {}, + requestOptions?: Lists.RequestOptions + ): Promise { + const { cursor, pattern } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + if (pattern != null) { + _queryParams["pattern"] = pattern; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/lists" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.ListGetAllResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Returns a list based on the list ID provided. + * @throws {@link Courier.NotFoundError} + */ + public async get( + listId: string, + request: Courier.GetListRequest = {}, + requestOptions?: Lists.RequestOptions + ): Promise { + const { cursor, pattern } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + if (pattern != null) { + _queryParams["pattern"] = pattern; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/lists/${listId}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.List; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Courier.NotFoundError(_response.error.body as Courier.NotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Create or replace an existing list with the supplied values. + */ + public async update( + listId: string, + request: Courier.ListPutParams, + requestOptions?: Lists.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/lists/${listId}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.List; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Get the list's subscriptions. + * @throws {@link Courier.NotFoundError} + */ + public async getSubscriptions( + listId: string, + request: Courier.GetSubscriptionForListRequest = {}, + requestOptions?: Lists.RequestOptions + ): Promise { + const { cursor } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/lists/${listId}/subscriptions` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.ListGetSubscriptionsResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Courier.NotFoundError(_response.error.body as Courier.NotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Subscribes the users to the list, overwriting existing subscriptions. If the list does not exist, it will be automatically created. + * @throws {@link Courier.BadRequestError} + */ + public async putSubscriptions( + listId: string, + request: Courier.PutSubscriptionsRecipient[], + requestOptions?: Lists.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/lists/${listId}/subscriptions` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Subscribes additional users to the list, without modifying existing subscriptions. If the list does not exist, it will be automatically created. + * @throws {@link Courier.BadRequestError} + */ + public async postSubscriptions( + listId: string, + request: Courier.PutSubscriptionsRecipient[], + requestOptions?: Lists.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/lists/${listId}/subscriptions` + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Subscribe a user to an existing list (note: if the List does not exist, it will be automatically created). + */ + public async subscribe( + listId: string, + userId: string, + request: Courier.SubscribeUserToListRequest, + requestOptions?: Lists.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/lists/${listId}/subscriptions/${userId}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Delete a subscription to a list by list ID and user ID. + * @throws {@link Courier.NotFoundError} + */ + public async unsubscribe(listId: string, userId: string, requestOptions?: Lists.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/lists/${listId}/subscriptions/${userId}` + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Courier.NotFoundError(_response.error.body as Courier.NotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/lists/client/index.ts b/src/api/resources/lists/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/resources/lists/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/resources/lists/client/requests/GetAllListsRequest.ts b/src/api/resources/lists/client/requests/GetAllListsRequest.ts new file mode 100644 index 0000000..ce5bc60 --- /dev/null +++ b/src/api/resources/lists/client/requests/GetAllListsRequest.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetAllListsRequest { + /** + * A unique identifier that allows for fetching the next page of lists. + */ + cursor?: string; + /** + * "A pattern used to filter the list items returned. Pattern types supported: exact match on `list_id` or a pattern of one or more pattern parts. you may replace a part with either: `*` to match all parts in that position, or `**` to signify a wildcard `endsWith` pattern match." + * + */ + pattern?: string; +} diff --git a/src/api/resources/lists/client/requests/GetListRequest.ts b/src/api/resources/lists/client/requests/GetListRequest.ts new file mode 100644 index 0000000..3904f5c --- /dev/null +++ b/src/api/resources/lists/client/requests/GetListRequest.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetListRequest { + /** + * A unique identifier that allows for fetching the next page of lists. + */ + cursor?: string; + /** + * "A pattern used to filter the list items returned. Pattern types supported: exact match on `list_id` or a pattern of one or more pattern parts. you may replace a part with either: `*` to match all parts in that position, or `**` to signify a wildcard `endsWith` pattern match." + * + */ + pattern?: string; +} diff --git a/src/api/resources/lists/client/requests/GetSubscriptionForListRequest.ts b/src/api/resources/lists/client/requests/GetSubscriptionForListRequest.ts new file mode 100644 index 0000000..151dda1 --- /dev/null +++ b/src/api/resources/lists/client/requests/GetSubscriptionForListRequest.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetSubscriptionForListRequest { + /** + * A unique identifier that allows for fetching the next set of list subscriptions + */ + cursor?: string; +} diff --git a/src/api/resources/lists/client/requests/SubscribeUserToListRequest.ts b/src/api/resources/lists/client/requests/SubscribeUserToListRequest.ts new file mode 100644 index 0000000..e5b6cb8 --- /dev/null +++ b/src/api/resources/lists/client/requests/SubscribeUserToListRequest.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../../.."; + +export interface SubscribeUserToListRequest { + listId: string; + recipientId: string; + preferences?: Courier.RecipientPreferences; +} diff --git a/src/api/resources/lists/client/requests/index.ts b/src/api/resources/lists/client/requests/index.ts new file mode 100644 index 0000000..f4043dd --- /dev/null +++ b/src/api/resources/lists/client/requests/index.ts @@ -0,0 +1,4 @@ +export { GetAllListsRequest } from "./GetAllListsRequest"; +export { GetListRequest } from "./GetListRequest"; +export { GetSubscriptionForListRequest } from "./GetSubscriptionForListRequest"; +export { SubscribeUserToListRequest } from "./SubscribeUserToListRequest"; diff --git a/src/api/resources/lists/index.ts b/src/api/resources/lists/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/lists/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/lists/types/List.ts b/src/api/resources/lists/types/List.ts new file mode 100644 index 0000000..96e96ba --- /dev/null +++ b/src/api/resources/lists/types/List.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface List { + id: string; + name: string; + created?: number; + updated?: number; +} diff --git a/src/api/resources/lists/types/ListFindByRecipientIdParams.ts b/src/api/resources/lists/types/ListFindByRecipientIdParams.ts new file mode 100644 index 0000000..5e938bf --- /dev/null +++ b/src/api/resources/lists/types/ListFindByRecipientIdParams.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListFindByRecipientIdParams { + cursor?: string; +} diff --git a/src/api/resources/lists/types/ListFindByRecipientIdResponse.ts b/src/api/resources/lists/types/ListFindByRecipientIdResponse.ts new file mode 100644 index 0000000..2264af4 --- /dev/null +++ b/src/api/resources/lists/types/ListFindByRecipientIdResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListFindByRecipientIdResponse { + paging: Courier.Paging; + results: Courier.List[]; +} diff --git a/src/api/resources/lists/types/ListGetAllParams.ts b/src/api/resources/lists/types/ListGetAllParams.ts new file mode 100644 index 0000000..a156846 --- /dev/null +++ b/src/api/resources/lists/types/ListGetAllParams.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListGetAllParams { + cursor?: string; + pattern?: string; +} diff --git a/src/api/resources/lists/types/ListGetAllResponse.ts b/src/api/resources/lists/types/ListGetAllResponse.ts new file mode 100644 index 0000000..b329b65 --- /dev/null +++ b/src/api/resources/lists/types/ListGetAllResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListGetAllResponse { + paging: Courier.Paging; + items: Courier.List[]; +} diff --git a/src/api/resources/lists/types/ListGetSubscriptionsParams.ts b/src/api/resources/lists/types/ListGetSubscriptionsParams.ts new file mode 100644 index 0000000..5f6a1fd --- /dev/null +++ b/src/api/resources/lists/types/ListGetSubscriptionsParams.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListGetSubscriptionsParams { + cursor?: string; +} diff --git a/src/api/resources/lists/types/ListGetSubscriptionsResponse.ts b/src/api/resources/lists/types/ListGetSubscriptionsResponse.ts new file mode 100644 index 0000000..40463de --- /dev/null +++ b/src/api/resources/lists/types/ListGetSubscriptionsResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListGetSubscriptionsResponse { + paging: Courier.Paging; + items: Courier.ListSubscriptionRecipient[]; +} diff --git a/src/api/resources/lists/types/ListPutParams.ts b/src/api/resources/lists/types/ListPutParams.ts new file mode 100644 index 0000000..bb3d04c --- /dev/null +++ b/src/api/resources/lists/types/ListPutParams.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListPutParams { + name: string; + preferences?: Courier.RecipientPreferences; +} diff --git a/src/api/resources/lists/types/ListSubscriptionRecipient.ts b/src/api/resources/lists/types/ListSubscriptionRecipient.ts new file mode 100644 index 0000000..2d646d9 --- /dev/null +++ b/src/api/resources/lists/types/ListSubscriptionRecipient.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListSubscriptionRecipient { + recipientId: string; + created?: string; + preferences?: Courier.RecipientPreferences; +} diff --git a/src/api/resources/lists/types/PutSubscriptionsRecipient.ts b/src/api/resources/lists/types/PutSubscriptionsRecipient.ts new file mode 100644 index 0000000..bf65fd0 --- /dev/null +++ b/src/api/resources/lists/types/PutSubscriptionsRecipient.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface PutSubscriptionsRecipient { + recipientId: string; + preferences?: Courier.RecipientPreferences; +} diff --git a/src/api/resources/lists/types/RecipientSubscriptionsResponse.ts b/src/api/resources/lists/types/RecipientSubscriptionsResponse.ts new file mode 100644 index 0000000..02cffe9 --- /dev/null +++ b/src/api/resources/lists/types/RecipientSubscriptionsResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RecipientSubscriptionsResponse { + paging: Courier.Paging; + results: Courier.List[]; +} diff --git a/src/api/resources/lists/types/index.ts b/src/api/resources/lists/types/index.ts new file mode 100644 index 0000000..dce6bc1 --- /dev/null +++ b/src/api/resources/lists/types/index.ts @@ -0,0 +1,11 @@ +export * from "./List"; +export * from "./RecipientSubscriptionsResponse"; +export * from "./ListPutParams"; +export * from "./ListGetAllParams"; +export * from "./ListGetAllResponse"; +export * from "./ListGetSubscriptionsParams"; +export * from "./ListSubscriptionRecipient"; +export * from "./ListGetSubscriptionsResponse"; +export * from "./ListFindByRecipientIdParams"; +export * from "./ListFindByRecipientIdResponse"; +export * from "./PutSubscriptionsRecipient"; diff --git a/src/api/resources/messages/client/Client.ts b/src/api/resources/messages/client/Client.ts new file mode 100644 index 0000000..3399def --- /dev/null +++ b/src/api/resources/messages/client/Client.ts @@ -0,0 +1,424 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Messages { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class Messages { + constructor(protected readonly _options: Messages.Options) {} + + /** + * Fetch the statuses of messages you've previously sent. + */ + public async list( + request: Courier.ListMessagesRequest = {}, + requestOptions?: Messages.RequestOptions + ): Promise { + const { + archived, + cursor, + event, + list, + messageId, + notification, + recipient, + status, + tags, + enqueuedAfter, + traceId, + } = request; + const _queryParams: Record = {}; + if (archived != null) { + _queryParams["archived"] = archived.toString(); + } + + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + if (event != null) { + _queryParams["event"] = event; + } + + if (list != null) { + _queryParams["list"] = list; + } + + if (messageId != null) { + _queryParams["messageId"] = messageId; + } + + if (notification != null) { + _queryParams["notification"] = notification; + } + + if (recipient != null) { + _queryParams["recipient"] = recipient; + } + + if (status != null) { + _queryParams["status"] = status; + } + + if (tags != null) { + _queryParams["tags"] = tags; + } + + if (enqueuedAfter != null) { + _queryParams["enqueued_after"] = enqueuedAfter; + } + + if (traceId != null) { + _queryParams["traceId"] = traceId; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "messages" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.ListMessagesResponse; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Fetch the status of a message you've previously sent. + * @throws {@link Courier.BadRequestError} + * @throws {@link Courier.MessageNotFoundError} + */ + public async get(messageId: string, requestOptions?: Messages.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `messages/${messageId}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.MessageDetails; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + case 404: + throw new Courier.MessageNotFoundError(_response.error.body as Courier.MessageNotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Cancel a message that is currently in the process of being delivered. A well-formatted API call to the cancel message API will return either `200` status code for a successful cancellation or `409` status code for an unsuccessful cancellation. Both cases will include the actual message record in the response body (see details below). + */ + public async cancel( + messageId: string, + requestOptions?: Messages.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `messages/${messageId}/cancel` + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.MessageDetails; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Fetch the array of events of a message you've previously sent. + * @throws {@link Courier.BadRequestError} + * @throws {@link Courier.MessageNotFoundError} + */ + public async getHistory( + messageId: string, + request: Courier.GetMessageHistoryRequest = {}, + requestOptions?: Messages.RequestOptions + ): Promise { + const { type: type_ } = request; + const _queryParams: Record = {}; + if (type_ != null) { + _queryParams["type"] = type_; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `messages/${messageId}/history` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.MessageHistoryResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + case 404: + throw new Courier.MessageNotFoundError(_response.error.body as Courier.MessageNotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * @throws {@link Courier.BadRequestError} + * @throws {@link Courier.MessageNotFoundError} + */ + public async getContent( + messageId: string, + requestOptions?: Messages.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `messages/${messageId}/output` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.RenderOutputResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + case 404: + throw new Courier.MessageNotFoundError(_response.error.body as Courier.MessageNotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + public async archive(requestId: string, requestOptions?: Messages.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `messages/${requestId}/output` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/messages/client/index.ts b/src/api/resources/messages/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/resources/messages/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/resources/messages/client/requests/GetMessageHistoryRequest.ts b/src/api/resources/messages/client/requests/GetMessageHistoryRequest.ts new file mode 100644 index 0000000..4eaff10 --- /dev/null +++ b/src/api/resources/messages/client/requests/GetMessageHistoryRequest.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetMessageHistoryRequest { + /** + * A supported Message History type that will filter the events returned. + */ + type?: string; +} diff --git a/src/api/resources/messages/client/requests/ListMessagesRequest.ts b/src/api/resources/messages/client/requests/ListMessagesRequest.ts new file mode 100644 index 0000000..eafec40 --- /dev/null +++ b/src/api/resources/messages/client/requests/ListMessagesRequest.ts @@ -0,0 +1,50 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListMessagesRequest { + /** + * A boolean value that indicates whether archived messages should be included in the response. + */ + archived?: boolean; + /** + * A unique identifier that allows for fetching the next set of message statuses. + */ + cursor?: string; + /** + * A unique identifier representing the event that was used to send the event. + */ + event?: string; + /** + * A unique identifier representing the list the message was sent to. + */ + list?: string; + /** + * A unique identifier representing the message_id returned from either /send or /send/list. + */ + messageId?: string; + /** + * A unique identifier representing the notification that was used to send the event. + */ + notification?: string; + /** + * A unique identifier representing the recipient associated with the requested profile. + */ + recipient?: string; + /** + * An indicator of the current status of the message. Multiple status values can be passed in. + */ + status?: string; + /** + * A comma delimited list of 'tags'. Messages will be returned if they match any of the tags passed in. + */ + tags?: string; + /** + * The enqueued datetime of a message to filter out messages received before. + */ + enqueuedAfter?: string; + /** + * The unique identifier used to trace the requests + */ + traceId?: string; +} diff --git a/src/api/resources/messages/client/requests/index.ts b/src/api/resources/messages/client/requests/index.ts new file mode 100644 index 0000000..868e079 --- /dev/null +++ b/src/api/resources/messages/client/requests/index.ts @@ -0,0 +1,2 @@ +export { ListMessagesRequest } from "./ListMessagesRequest"; +export { GetMessageHistoryRequest } from "./GetMessageHistoryRequest"; diff --git a/src/api/resources/messages/index.ts b/src/api/resources/messages/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/messages/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/messages/types/ListMessagesResponse.ts b/src/api/resources/messages/types/ListMessagesResponse.ts new file mode 100644 index 0000000..b4db183 --- /dev/null +++ b/src/api/resources/messages/types/ListMessagesResponse.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListMessagesResponse { + /** Paging information for the result set. */ + paging: Courier.Paging; + /** An array of messages with their details. */ + results: Courier.MessageDetails[]; +} diff --git a/src/api/resources/messages/types/MessageDetails.ts b/src/api/resources/messages/types/MessageDetails.ts new file mode 100644 index 0000000..06158a8 --- /dev/null +++ b/src/api/resources/messages/types/MessageDetails.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface MessageDetails { + /** A unique identifier associated with the message you wish to retrieve (results from a send). */ + id: string; + /** The current status of the message. */ + status: Courier.MessageStatus; + /** A UTC timestamp at which Courier received the message request. Stored as a millisecond representation of the Unix epoch. */ + enqueued: number; + /** A UTC timestamp at which Courier passed the message to the Integration provider. Stored as a millisecond representation of the Unix epoch. */ + sent: number; + /** A UTC timestamp at which the Integration provider delivered the message. Stored as a millisecond representation of the Unix epoch. */ + delivered: number; + /** A UTC timestamp at which the recipient opened a message for the first time. Stored as a millisecond representation of the Unix epoch. */ + opened: number; + /** A UTC timestamp at which the recipient clicked on a tracked link for the first time. Stored as a millisecond representation of the Unix epoch. */ + clicked: number; + /** A unique identifier associated with the recipient of the delivered message. */ + recipient: string; + /** A unique identifier associated with the event of the delivered message. */ + event: string; + /** A unique identifier associated with the notification of the delivered message. */ + notification: string; + /** A message describing the error that occurred. */ + error?: string; + /** The reason for the current status of the message. */ + reason?: Courier.Reason; +} diff --git a/src/api/resources/messages/types/MessageHistoryResponse.ts b/src/api/resources/messages/types/MessageHistoryResponse.ts new file mode 100644 index 0000000..d65066f --- /dev/null +++ b/src/api/resources/messages/types/MessageHistoryResponse.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface MessageHistoryResponse { + results: Courier.MessageDetails[]; +} diff --git a/src/api/resources/messages/types/MessageStatus.ts b/src/api/resources/messages/types/MessageStatus.ts new file mode 100644 index 0000000..6d16151 --- /dev/null +++ b/src/api/resources/messages/types/MessageStatus.ts @@ -0,0 +1,44 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MessageStatus = + /** + * The recipient has clicked on any link in the message at least one time. */ + | "CLICKED" + /** + * The provider successfully delivered the message to the recipient. */ + | "DELIVERED" + /** + * The request has been received to send a message, is waiting in the work queue. */ + | "ENQUEUED" + /** + * The recipient has opened the message at least one time. */ + | "OPENED" + /** + * The message has been canceled such that it will not be delivered. */ + | "CANCELED" + /** + * The message has been accepted by the provider. */ + | "SENT" + /** + * The message could not be delivered to at least one provider, or the provider could not deliver the message to the recipient. This can happen for multiple reasons: an error, insufficient profile data, invalid notification setup, invalid integration configuration, etc. */ + | "UNDELIVERABLE" + /** + * Could not find a corresponding notification or event for the messages. */ + | "UNMAPPED" + /** + * The message could not be routed to any channel or provider. This can happen for multiple reasons: insufficient profile data, invalid notification setup, invalid integration configuration, etc. */ + | "UNROUTABLE"; + +export const MessageStatus = { + Clicked: "CLICKED", + Delivered: "DELIVERED", + Enqueued: "ENQUEUED", + Opened: "OPENED", + Canceled: "CANCELED", + Sent: "SENT", + Undeliverable: "UNDELIVERABLE", + Unmapped: "UNMAPPED", + Unroutable: "UNROUTABLE", +} as const; diff --git a/src/api/resources/messages/types/Reason.ts b/src/api/resources/messages/types/Reason.ts new file mode 100644 index 0000000..9b354d3 --- /dev/null +++ b/src/api/resources/messages/types/Reason.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type Reason = + /** + * The recipient did not receive the notification because of a condition that passed. */ + | "FILTERED" + /** + * The notification did not contain any valid channels. */ + | "NO_CHANNELS" + /** + * The notification did not contain a configured provider for a channel. */ + | "NO_PROVIDERS" + /** + * The Integration provider had an error when sending a notification. */ + | "PROVIDER_ERROR" + /** + * The notification hasn't been published yet. */ + | "UNPUBLISHED" + /** + * The recipient did not receive the notification because they chose to unsubscribe from it. */ + | "UNSUBSCRIBED"; + +export const Reason = { + Filtered: "FILTERED", + NoChannels: "NO_CHANNELS", + NoProviders: "NO_PROVIDERS", + ProviderError: "PROVIDER_ERROR", + Unpublished: "UNPUBLISHED", + Unsubscribed: "UNSUBSCRIBED", +} as const; diff --git a/src/api/resources/messages/types/RenderOutput.ts b/src/api/resources/messages/types/RenderOutput.ts new file mode 100644 index 0000000..8637084 --- /dev/null +++ b/src/api/resources/messages/types/RenderOutput.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RenderOutput { + /** The channel used for rendering the message. */ + channel: string; + /** The ID of channel used for rendering the message. */ + channel_id: string; + /** Content details of the rendered message. */ + content: Courier.RenderedMessageContent; +} diff --git a/src/api/resources/messages/types/RenderOutputResponse.ts b/src/api/resources/messages/types/RenderOutputResponse.ts new file mode 100644 index 0000000..50b2fc4 --- /dev/null +++ b/src/api/resources/messages/types/RenderOutputResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RenderOutputResponse { + /** An array of render output of a previously sent message. */ + results: Courier.RenderOutput[]; +} diff --git a/src/api/resources/messages/types/RenderedMessageBlock.ts b/src/api/resources/messages/types/RenderedMessageBlock.ts new file mode 100644 index 0000000..0246354 --- /dev/null +++ b/src/api/resources/messages/types/RenderedMessageBlock.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface RenderedMessageBlock { + /** The block type of the rendered message block. */ + type: string; + /** The block text of the rendered message block. */ + text: string; +} diff --git a/src/api/resources/messages/types/RenderedMessageContent.ts b/src/api/resources/messages/types/RenderedMessageContent.ts new file mode 100644 index 0000000..9cb9f4b --- /dev/null +++ b/src/api/resources/messages/types/RenderedMessageContent.ts @@ -0,0 +1,20 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RenderedMessageContent { + /** The html content of the rendered message. */ + html: string; + /** The title of the rendered message. */ + title: string; + /** The body of the rendered message. */ + body: string; + /** The subject of the rendered message. */ + subject: string; + /** The text of the rendered message. */ + text: string; + /** The blocks of the rendered message. */ + blocks: Courier.RenderedMessageBlock[]; +} diff --git a/src/api/resources/messages/types/index.ts b/src/api/resources/messages/types/index.ts new file mode 100644 index 0000000..1c51711 --- /dev/null +++ b/src/api/resources/messages/types/index.ts @@ -0,0 +1,9 @@ +export * from "./MessageStatus"; +export * from "./MessageDetails"; +export * from "./Reason"; +export * from "./ListMessagesResponse"; +export * from "./MessageHistoryResponse"; +export * from "./RenderOutputResponse"; +export * from "./RenderedMessageBlock"; +export * from "./RenderedMessageContent"; +export * from "./RenderOutput"; diff --git a/src/api/resources/profiles/client/Client.ts b/src/api/resources/profiles/client/Client.ts new file mode 100644 index 0000000..fa68070 --- /dev/null +++ b/src/api/resources/profiles/client/Client.ts @@ -0,0 +1,448 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Profiles { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } + + interface IdempotentRequestOptions extends RequestOptions { + idempotencyKey?: string | undefined; + idempotencyExpiry?: number | undefined; + } +} + +export class Profiles { + constructor(protected readonly _options: Profiles.Options) {} + + /** + * Returns the specified user profile. + * @throws {@link Courier.BadRequestError} + */ + public async get(userId: string, requestOptions?: Profiles.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/profiles/${userId}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.ProfileGetResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Merge the supplied values with an existing profile or create a new profile if one doesn't already exist. + * @throws {@link Courier.BadRequestError} + */ + public async merge( + userId: string, + request: Courier.MergeProfileRequest, + requestOptions?: Profiles.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/profiles/${userId}` + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.MergeProfileResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * When using `PUT`, be sure to include all the key-value pairs required by the recipient's profile. + * Any key-value pairs that exist in the profile but fail to be included in the `PUT` request will be + * removed from the profile. Remember, a `PUT` update is a full replacement of the data. For partial updates, + * use the [Patch](https://www.courier.com/docs/reference/profiles/patch/) request. + * + * @throws {@link Courier.BadRequestError} + */ + public async replace( + userId: string, + request: Courier.ReplaceProfileRequest, + requestOptions?: Profiles.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/profiles/${userId}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.ReplaceProfileResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Deletes the specified user profile. + * @throws {@link Courier.BadRequestError} + */ + public async delete(userId: string, requestOptions?: Profiles.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/profiles/${userId}` + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Returns the subscribed lists for a specified user. + * @throws {@link Courier.BadRequestError} + */ + public async getListSubscriptions( + userId: string, + request: Courier.GetListSubscriptionsRequest = {}, + requestOptions?: Profiles.RequestOptions + ): Promise { + const { cursor } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/profiles/${userId}/lists` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Subscribes the given user to one or more lists. If the list does not exist, it will be created. + * @throws {@link Courier.BadRequestError} + */ + public async subscribeToLists( + userId: string, + request: Courier.SubscribeToListsRequest, + requestOptions?: Profiles.IdempotentRequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/profiles/${userId}/lists` + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + "Idempotency-Key": requestOptions?.idempotencyKey != null ? requestOptions?.idempotencyKey : undefined, + "X-Idempotency-Expiration": + requestOptions?.idempotencyExpiry != null + ? requestOptions?.idempotencyExpiry.toString() + : undefined, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.SubscribeToListsResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Removes all list subscriptions for given user. + * @throws {@link Courier.BadRequestError} + */ + public async deleteListSubscription( + userId: string, + requestOptions?: Profiles.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/profiles/${userId}/lists` + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.DeleteListSubscriptionResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/profiles/client/index.ts b/src/api/resources/profiles/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/resources/profiles/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/resources/profiles/client/requests/GetListSubscriptionsRequest.ts b/src/api/resources/profiles/client/requests/GetListSubscriptionsRequest.ts new file mode 100644 index 0000000..c8433be --- /dev/null +++ b/src/api/resources/profiles/client/requests/GetListSubscriptionsRequest.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetListSubscriptionsRequest { + /** + * A unique identifier that allows for fetching the next set of message statuses. + */ + cursor?: string; +} diff --git a/src/api/resources/profiles/client/requests/MergeProfileRequest.ts b/src/api/resources/profiles/client/requests/MergeProfileRequest.ts new file mode 100644 index 0000000..8982de7 --- /dev/null +++ b/src/api/resources/profiles/client/requests/MergeProfileRequest.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface MergeProfileRequest { + recipientId: string; + profile: Record; +} diff --git a/src/api/resources/profiles/client/requests/ReplaceProfileRequest.ts b/src/api/resources/profiles/client/requests/ReplaceProfileRequest.ts new file mode 100644 index 0000000..8cf6813 --- /dev/null +++ b/src/api/resources/profiles/client/requests/ReplaceProfileRequest.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ReplaceProfileRequest { + recipientId: string; + profile: Record; +} diff --git a/src/api/resources/profiles/client/requests/index.ts b/src/api/resources/profiles/client/requests/index.ts new file mode 100644 index 0000000..a0e61c8 --- /dev/null +++ b/src/api/resources/profiles/client/requests/index.ts @@ -0,0 +1,3 @@ +export { MergeProfileRequest } from "./MergeProfileRequest"; +export { ReplaceProfileRequest } from "./ReplaceProfileRequest"; +export { GetListSubscriptionsRequest } from "./GetListSubscriptionsRequest"; diff --git a/src/api/resources/profiles/index.ts b/src/api/resources/profiles/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/profiles/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/profiles/types/Address.ts b/src/api/resources/profiles/types/Address.ts new file mode 100644 index 0000000..764197d --- /dev/null +++ b/src/api/resources/profiles/types/Address.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Address { + formatted: string; + street_address: string; + locality: string; + region: string; + postal_code: string; + country: string; +} diff --git a/src/api/resources/profiles/types/AirshipProfile.ts b/src/api/resources/profiles/types/AirshipProfile.ts new file mode 100644 index 0000000..ae0454b --- /dev/null +++ b/src/api/resources/profiles/types/AirshipProfile.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AirshipProfile { + audience: Courier.AirshipProfileAudience; + device_types: (Courier.DeviceType | undefined)[]; +} diff --git a/src/api/resources/profiles/types/AirshipProfileAudience.ts b/src/api/resources/profiles/types/AirshipProfileAudience.ts new file mode 100644 index 0000000..ad9ba5e --- /dev/null +++ b/src/api/resources/profiles/types/AirshipProfileAudience.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AirshipProfileAudience { + named_user: string; +} diff --git a/src/api/resources/profiles/types/DeleteListSubscriptionResponse.ts b/src/api/resources/profiles/types/DeleteListSubscriptionResponse.ts new file mode 100644 index 0000000..e1448c6 --- /dev/null +++ b/src/api/resources/profiles/types/DeleteListSubscriptionResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface DeleteListSubscriptionResponse { + status: "SUCCESS"; +} diff --git a/src/api/resources/profiles/types/DeviceType.ts b/src/api/resources/profiles/types/DeviceType.ts new file mode 100644 index 0000000..4e78f88 --- /dev/null +++ b/src/api/resources/profiles/types/DeviceType.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type DeviceType = any; diff --git a/src/api/resources/profiles/types/Discord.ts b/src/api/resources/profiles/types/Discord.ts new file mode 100644 index 0000000..74efd54 --- /dev/null +++ b/src/api/resources/profiles/types/Discord.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Discord = Courier.SendToChannel | Courier.SendDirectMessage; diff --git a/src/api/resources/profiles/types/Expo.ts b/src/api/resources/profiles/types/Expo.ts new file mode 100644 index 0000000..f7b11a5 --- /dev/null +++ b/src/api/resources/profiles/types/Expo.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Expo = Courier.Token | Courier.MultipleTokens; diff --git a/src/api/resources/profiles/types/Intercom.ts b/src/api/resources/profiles/types/Intercom.ts new file mode 100644 index 0000000..887e1a9 --- /dev/null +++ b/src/api/resources/profiles/types/Intercom.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Intercom { + from: string; + to: Courier.IntercomeRecipient; +} diff --git a/src/api/resources/profiles/types/IntercomeRecipient.ts b/src/api/resources/profiles/types/IntercomeRecipient.ts new file mode 100644 index 0000000..a073746 --- /dev/null +++ b/src/api/resources/profiles/types/IntercomeRecipient.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface IntercomeRecipient { + id: string; +} diff --git a/src/api/resources/profiles/types/MergeProfileResponse.ts b/src/api/resources/profiles/types/MergeProfileResponse.ts new file mode 100644 index 0000000..f443ffa --- /dev/null +++ b/src/api/resources/profiles/types/MergeProfileResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface MergeProfileResponse { + status: "SUCCESS"; +} diff --git a/src/api/resources/profiles/types/MsTeams.ts b/src/api/resources/profiles/types/MsTeams.ts new file mode 100644 index 0000000..81d15b0 --- /dev/null +++ b/src/api/resources/profiles/types/MsTeams.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type MsTeams = Courier.SendToMsTeamsChannel | Courier.SendToMsTeamsUser; diff --git a/src/api/resources/profiles/types/MultipleTokens.ts b/src/api/resources/profiles/types/MultipleTokens.ts new file mode 100644 index 0000000..dc73553 --- /dev/null +++ b/src/api/resources/profiles/types/MultipleTokens.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface MultipleTokens { + tokens: Courier.Token[]; +} diff --git a/src/api/resources/profiles/types/ProfileGetParameters.ts b/src/api/resources/profiles/types/ProfileGetParameters.ts new file mode 100644 index 0000000..c3972e7 --- /dev/null +++ b/src/api/resources/profiles/types/ProfileGetParameters.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ProfileGetParameters { + recipientId: string; +} diff --git a/src/api/resources/profiles/types/ProfileGetResponse.ts b/src/api/resources/profiles/types/ProfileGetResponse.ts new file mode 100644 index 0000000..e19d442 --- /dev/null +++ b/src/api/resources/profiles/types/ProfileGetResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ProfileGetResponse { + profile: Record; +} diff --git a/src/api/resources/profiles/types/ReplaceProfileResponse.ts b/src/api/resources/profiles/types/ReplaceProfileResponse.ts new file mode 100644 index 0000000..bc9ed1f --- /dev/null +++ b/src/api/resources/profiles/types/ReplaceProfileResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ReplaceProfileResponse { + status: "SUCCESS"; +} diff --git a/src/api/resources/profiles/types/SendDirectMessage.ts b/src/api/resources/profiles/types/SendDirectMessage.ts new file mode 100644 index 0000000..b917e89 --- /dev/null +++ b/src/api/resources/profiles/types/SendDirectMessage.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface SendDirectMessage { + user_id: string; +} diff --git a/src/api/resources/profiles/types/SendToChannel.ts b/src/api/resources/profiles/types/SendToChannel.ts new file mode 100644 index 0000000..2eb0333 --- /dev/null +++ b/src/api/resources/profiles/types/SendToChannel.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface SendToChannel { + channel_id: string; +} diff --git a/src/api/resources/profiles/types/SendToMsTeamsChannel.ts b/src/api/resources/profiles/types/SendToMsTeamsChannel.ts new file mode 100644 index 0000000..ff16aaf --- /dev/null +++ b/src/api/resources/profiles/types/SendToMsTeamsChannel.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface SendToMsTeamsChannel { + conversation_id: string; + tenant_id: string; + service_url: string; +} diff --git a/src/api/resources/profiles/types/SendToMsTeamsUser.ts b/src/api/resources/profiles/types/SendToMsTeamsUser.ts new file mode 100644 index 0000000..9ad3763 --- /dev/null +++ b/src/api/resources/profiles/types/SendToMsTeamsUser.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface SendToMsTeamsUser { + user_id: string; + tenant_id: string; + service_url: string; +} diff --git a/src/api/resources/profiles/types/SnoozeRule.ts b/src/api/resources/profiles/types/SnoozeRule.ts new file mode 100644 index 0000000..b64dbae --- /dev/null +++ b/src/api/resources/profiles/types/SnoozeRule.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface SnoozeRule { + type: Courier.SnoozeRuleType; + start: string; + until: string; +} diff --git a/src/api/resources/profiles/types/SnoozeRuleType.ts b/src/api/resources/profiles/types/SnoozeRuleType.ts new file mode 100644 index 0000000..25ec01e --- /dev/null +++ b/src/api/resources/profiles/types/SnoozeRuleType.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type SnoozeRuleType = "snooze"; + +export const SnoozeRuleType = { + Snooze: "snooze", +} as const; diff --git a/src/api/resources/profiles/types/SubscribeToListsRequest.ts b/src/api/resources/profiles/types/SubscribeToListsRequest.ts new file mode 100644 index 0000000..e0a894c --- /dev/null +++ b/src/api/resources/profiles/types/SubscribeToListsRequest.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface SubscribeToListsRequest { + lists?: Courier.List[]; + preferences?: Courier.RecipientPreferences; +} diff --git a/src/api/resources/profiles/types/SubscribeToListsResponse.ts b/src/api/resources/profiles/types/SubscribeToListsResponse.ts new file mode 100644 index 0000000..c063c2a --- /dev/null +++ b/src/api/resources/profiles/types/SubscribeToListsResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface SubscribeToListsResponse { + status: "SUCCESS"; +} diff --git a/src/api/resources/profiles/types/Token.ts b/src/api/resources/profiles/types/Token.ts new file mode 100644 index 0000000..e140bba --- /dev/null +++ b/src/api/resources/profiles/types/Token.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Token { + token: string; +} diff --git a/src/api/resources/profiles/types/UserProfile.ts b/src/api/resources/profiles/types/UserProfile.ts new file mode 100644 index 0000000..9d43133 --- /dev/null +++ b/src/api/resources/profiles/types/UserProfile.ts @@ -0,0 +1,39 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface UserProfile { + address: Courier.Address; + birthdate: string; + email: string; + email_verified: boolean; + family_name: string; + gender: string; + given_name: string; + locale: string; + middle_name: string; + name: string; + nickname: string; + phone_number: string; + phone_number_verified: boolean; + picture: string; + preferred_name: string; + profile: string; + sub: string; + updated_at: string; + website: string; + zoneinfo: string; + /** A free form object. Due to a limitation of the API Explorer, you can only enter string key/values below, but this API accepts more complex object structures. */ + custom?: any; + airship: Courier.AirshipProfile; + apn: string; + target_arn: string; + discord: Courier.Discord; + expo: Courier.Expo; + facebookPSID: string; + firebaseToken: string; + intercom: Courier.Intercom; + ms_teams: Courier.MsTeams; +} diff --git a/src/api/resources/profiles/types/index.ts b/src/api/resources/profiles/types/index.ts new file mode 100644 index 0000000..47de25b --- /dev/null +++ b/src/api/resources/profiles/types/index.ts @@ -0,0 +1,25 @@ +export * from "./Address"; +export * from "./UserProfile"; +export * from "./AirshipProfile"; +export * from "./AirshipProfileAudience"; +export * from "./DeviceType"; +export * from "./SnoozeRuleType"; +export * from "./SnoozeRule"; +export * from "./Discord"; +export * from "./SendToChannel"; +export * from "./SendDirectMessage"; +export * from "./Expo"; +export * from "./Token"; +export * from "./MultipleTokens"; +export * from "./Intercom"; +export * from "./IntercomeRecipient"; +export * from "./MsTeams"; +export * from "./SendToMsTeamsUser"; +export * from "./SendToMsTeamsChannel"; +export * from "./ProfileGetParameters"; +export * from "./ProfileGetResponse"; +export * from "./MergeProfileResponse"; +export * from "./ReplaceProfileResponse"; +export * from "./SubscribeToListsRequest"; +export * from "./SubscribeToListsResponse"; +export * from "./DeleteListSubscriptionResponse"; diff --git a/src/api/resources/send/index.ts b/src/api/resources/send/index.ts new file mode 100644 index 0000000..eea524d --- /dev/null +++ b/src/api/resources/send/index.ts @@ -0,0 +1 @@ +export * from "./types"; diff --git a/src/api/resources/send/types/Attachment.ts b/src/api/resources/send/types/Attachment.ts new file mode 100644 index 0000000..eaf7587 --- /dev/null +++ b/src/api/resources/send/types/Attachment.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type Attachment = Record; diff --git a/src/api/resources/send/types/AudienceFilter.ts b/src/api/resources/send/types/AudienceFilter.ts new file mode 100644 index 0000000..92a652f --- /dev/null +++ b/src/api/resources/send/types/AudienceFilter.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AudienceFilter { + /** Send to users only if they are member of the account */ + operator: "MEMBER_OF"; + path: "account_id"; + value: string; +} diff --git a/src/api/resources/send/types/AudienceRecipient.ts b/src/api/resources/send/types/AudienceRecipient.ts new file mode 100644 index 0000000..d410818 --- /dev/null +++ b/src/api/resources/send/types/AudienceRecipient.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface AudienceRecipient { + /** A unique identifier associated with an Audience. A message will be sent to each user in the audience. */ + audience_id: string; + data?: Courier.MessageData; + filters?: Courier.AudienceFilter[]; +} diff --git a/src/api/resources/send/types/BaseMessage.ts b/src/api/resources/send/types/BaseMessage.ts new file mode 100644 index 0000000..f39c59e --- /dev/null +++ b/src/api/resources/send/types/BaseMessage.ts @@ -0,0 +1,39 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BaseMessage { + /** The recipient or a list of recipients of the message */ + to: Courier.MessageRecipient; + /** + * An arbitrary object that includes any data you want to pass to the message. + * The data will populate the corresponding template or elements variables. + * + */ + data?: Courier.MessageData; + brand_id?: string; + /** + * "Define run-time configuration for one or more channels. If you don't specify channels, the default configuration for each channel will be used. Valid ChannelId's are: email, sms, push, inbox, direct_message, banner, and webhook." + * + */ + channels?: Courier.MessageChannels; + /** Context to load with this recipient. Will override any context set on message.context. */ + context?: Courier.MessageContext; + /** Metadata such as utm tracking attached with the notification through this channel. */ + metadata?: Courier.MessageMetadata; + /** An object whose keys are valid provider identifiers which map to an object. */ + providers?: Courier.MessageProviders; + routing?: Courier.Routing; + /** Time in ms to attempt the channel before failing over to the next available channel. */ + timeout?: Courier.Timeout; + /** Defines the time to wait before delivering the message. */ + delay?: Courier.Delay; + /** + * "Expiry allows you to set an absolute or relative time in which a message expires. + * Note: This is only valid for the Courier Inbox channel as of 12-08-2022." + * + */ + expiry?: Courier.Expiry; +} diff --git a/src/api/resources/send/types/BaseSocialPresence.ts b/src/api/resources/send/types/BaseSocialPresence.ts new file mode 100644 index 0000000..f159f15 --- /dev/null +++ b/src/api/resources/send/types/BaseSocialPresence.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BaseSocialPresence { + url: string; +} diff --git a/src/api/resources/send/types/BrandSettingsEmail.ts b/src/api/resources/send/types/BrandSettingsEmail.ts new file mode 100644 index 0000000..0a23f24 --- /dev/null +++ b/src/api/resources/send/types/BrandSettingsEmail.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandSettingsEmail { + templateOverride?: Courier.BrandTemplateOverride; + head?: Courier.EmailHead; + footer?: Courier.EmailFooter; + header?: Courier.EmailHeader; +} diff --git a/src/api/resources/send/types/BrandSettingsInApp.ts b/src/api/resources/send/types/BrandSettingsInApp.ts new file mode 100644 index 0000000..d610cca --- /dev/null +++ b/src/api/resources/send/types/BrandSettingsInApp.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandSettingsInApp { + borderRadius?: string; + disableMessageIcon?: boolean; + fontFamily?: string; + placement?: Courier.InAppPlacement; + widgetBackground: Courier.WidgetBackground; + colors: Courier.BrandColors; + icons: Courier.Icons; + preferences: Courier.Preferences; +} diff --git a/src/api/resources/send/types/BrandSettingsSocialPresence.ts b/src/api/resources/send/types/BrandSettingsSocialPresence.ts new file mode 100644 index 0000000..119e44e --- /dev/null +++ b/src/api/resources/send/types/BrandSettingsSocialPresence.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandSettingsSocialPresence { + inheritDefault?: boolean; + facebook?: Courier.BaseSocialPresence; + instagram?: Courier.BaseSocialPresence; + linkedin?: Courier.BaseSocialPresence; + medium?: Courier.BaseSocialPresence; + twitter?: Courier.BaseSocialPresence; +} diff --git a/src/api/resources/send/types/BrandTemplate.ts b/src/api/resources/send/types/BrandTemplate.ts new file mode 100644 index 0000000..6da9132 --- /dev/null +++ b/src/api/resources/send/types/BrandTemplate.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BrandTemplate { + backgroundColor?: string; + blocksBackgroundColor?: string; + enabled: boolean; + footer?: string; + head?: string; + header?: string; + width?: string; +} diff --git a/src/api/resources/send/types/BrandTemplateOverride.ts b/src/api/resources/send/types/BrandTemplateOverride.ts new file mode 100644 index 0000000..24a0a84 --- /dev/null +++ b/src/api/resources/send/types/BrandTemplateOverride.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface BrandTemplateOverride extends Courier.BrandTemplate { + mjml: Courier.BrandTemplate; + footerBackgroundColor?: string; + footerFullWidth?: boolean; +} diff --git a/src/api/resources/send/types/Channel.ts b/src/api/resources/send/types/Channel.ts new file mode 100644 index 0000000..0d946c0 --- /dev/null +++ b/src/api/resources/send/types/Channel.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Channel { + /** + * Id of the brand that should be used for rendering the message. + * If not specified, the brand configured as default brand will be used. + * + */ + brand_id?: string; + /** + * A list of providers enabled for this channel. Courier will select + * one provider to send through unless routing_method is set to all. + * + */ + providers?: string[]; + /** + * The method for selecting the providers to send the message with. + * Single will send to one of the available providers for this channel, + * all will send the message through all channels. Defaults to `single`. + * + */ + routing_method?: Courier.RoutingMethod; + /** + * A JavaScript conditional expression to determine if the message should + * be sent through the channel. Has access to the data and profile object. + * For example, `data.name === profile.name` + * + */ + if?: string; + timeouts?: Courier.Timeouts; + /** Channel specific overrides. */ + override?: Courier.Override; + metadata?: Courier.ChannelMetadata; +} diff --git a/src/api/resources/send/types/ChannelMetadata.ts b/src/api/resources/send/types/ChannelMetadata.ts new file mode 100644 index 0000000..cf57e8d --- /dev/null +++ b/src/api/resources/send/types/ChannelMetadata.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ChannelMetadata { + utm?: Courier.Utm; +} diff --git a/src/api/resources/send/types/ChannelSource.ts b/src/api/resources/send/types/ChannelSource.ts new file mode 100644 index 0000000..56b8ca0 --- /dev/null +++ b/src/api/resources/send/types/ChannelSource.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ChannelSource = "subscription" | "list" | "recipient"; + +export const ChannelSource = { + Subscription: "subscription", + List: "list", + Recipient: "recipient", +} as const; diff --git a/src/api/resources/send/types/Content.ts b/src/api/resources/send/types/Content.ts new file mode 100644 index 0000000..94859e4 --- /dev/null +++ b/src/api/resources/send/types/Content.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Content = Courier.ElementalContent | Courier.ElementalContentSugar; diff --git a/src/api/resources/send/types/ContentMessage.ts b/src/api/resources/send/types/ContentMessage.ts new file mode 100644 index 0000000..ce8e9b6 --- /dev/null +++ b/src/api/resources/send/types/ContentMessage.ts @@ -0,0 +1,19 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * The message property has the following primary top-level properties. They define the destination and content of the message. + * Additional advanced configuration fields [are defined below](https://www.courier.com/docs/reference/send/message/#other-message-properties). + * + */ +export interface ContentMessage extends Courier.BaseMessage { + /** + * Describes the content of the message in a way that will work for email, push, + * chat, or any channel. Either this or template must be specified. + * + */ + content: Courier.Content; +} diff --git a/src/api/resources/send/types/Criteria.ts b/src/api/resources/send/types/Criteria.ts new file mode 100644 index 0000000..fba77c9 --- /dev/null +++ b/src/api/resources/send/types/Criteria.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type Criteria = "no-escalation" | "delivered" | "viewed" | "engaged"; + +export const Criteria = { + NoEscalation: "no-escalation", + Delivered: "delivered", + Viewed: "viewed", + Engaged: "engaged", +} as const; diff --git a/src/api/resources/send/types/Delay.ts b/src/api/resources/send/types/Delay.ts new file mode 100644 index 0000000..fb09856 --- /dev/null +++ b/src/api/resources/send/types/Delay.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Delay { + /** The duration of the delay in milliseconds. */ + duration: number; +} diff --git a/src/api/resources/send/types/ElementalActionNode.ts b/src/api/resources/send/types/ElementalActionNode.ts new file mode 100644 index 0000000..a32a501 --- /dev/null +++ b/src/api/resources/send/types/ElementalActionNode.ts @@ -0,0 +1,25 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * Allows the user to execute an action. Can be a button or a link. + */ +export interface ElementalActionNode extends Courier.ElementalBaseNode { + /** The text content of the action shown to the user. */ + content: string; + /** The target URL of the action. */ + href: string; + /** A unique id used to identify the action when it is executed. */ + action_id?: string; + /** The alignment of the action button. Defaults to "center". */ + align?: Courier.IAlignment; + /** The background color of the action button. */ + background_color?: string; + /** Defaults to `button`. */ + style?: Courier.IActionButtonStyle; + /** Region specific content. See [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) for more details. */ + locales?: Courier.Locales; +} diff --git a/src/api/resources/send/types/ElementalBaseNode.ts b/src/api/resources/send/types/ElementalBaseNode.ts new file mode 100644 index 0000000..6d3b1e0 --- /dev/null +++ b/src/api/resources/send/types/ElementalBaseNode.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ElementalBaseNode { + channels?: string[]; + ref?: string; + if?: string; + loop?: string; +} diff --git a/src/api/resources/send/types/ElementalChannelNode.ts b/src/api/resources/send/types/ElementalChannelNode.ts new file mode 100644 index 0000000..d888415 --- /dev/null +++ b/src/api/resources/send/types/ElementalChannelNode.ts @@ -0,0 +1,37 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * The channel element allows a notification to be customized based on which channel it is sent through. + * For example, you may want to display a detailed message when the notification is sent through email, + * and a more concise message in a push notification. Channel elements are only valid as top-level + * elements; you cannot nest channel elements. If there is a channel element specified at the top-level + * of the document, all sibling elements must be channel elements. + * Note: As an alternative, most elements support a `channel` property. Which allows you to selectively + * display an individual element on a per channel basis. See the + * [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. + * + */ +export interface ElementalChannelNode extends Courier.ElementalBaseNode { + /** + * The channel the contents of this element should be applied to. Can be `email`, + * `push`, `direct_message`, `sms` or a provider such as slack + * + */ + channel: string; + /** + * An array of elements to apply to the channel. If `raw` has not been + * specified, `elements` is `required`. + * + */ + elements?: Courier.ElementalNode[]; + /** + * Raw data to apply to the channel. If `elements` has not been + * specified, `raw` is `required`. + * + */ + raw?: Record; +} diff --git a/src/api/resources/send/types/ElementalContent.ts b/src/api/resources/send/types/ElementalContent.ts new file mode 100644 index 0000000..82c71db --- /dev/null +++ b/src/api/resources/send/types/ElementalContent.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ElementalContent { + /** For example, "2022-01-01" */ + version: string; + brand?: any; + elements: Courier.ElementalNode[]; +} diff --git a/src/api/resources/send/types/ElementalContentSugar.ts b/src/api/resources/send/types/ElementalContentSugar.ts new file mode 100644 index 0000000..5fa7b7a --- /dev/null +++ b/src/api/resources/send/types/ElementalContentSugar.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Syntatic Sugar to provide a fast shorthand for Courier Elemental Blocks. + */ +export interface ElementalContentSugar { + /** The title to be displayed by supported channels i.e. push, email (as subject) */ + title: string; + /** The text content displayed in the notification. */ + body: string; +} diff --git a/src/api/resources/send/types/ElementalDividerNode.ts b/src/api/resources/send/types/ElementalDividerNode.ts new file mode 100644 index 0000000..3cb1b5c --- /dev/null +++ b/src/api/resources/send/types/ElementalDividerNode.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * Renders a dividing line between elements. + */ +export interface ElementalDividerNode extends Courier.ElementalBaseNode { + /** The CSS color to render the line with. For example, `#fff` */ + color?: string; +} diff --git a/src/api/resources/send/types/ElementalGroupNode.ts b/src/api/resources/send/types/ElementalGroupNode.ts new file mode 100644 index 0000000..920a756 --- /dev/null +++ b/src/api/resources/send/types/ElementalGroupNode.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * Allows you to group elements together. This can be useful when used in combination with "if" or "loop". See [control flow docs](https://www.courier.com/docs/platform/content/elemental/control-flow/) for more details. + */ +export interface ElementalGroupNode extends Courier.ElementalBaseNode { + /** Sub elements to render. */ + elements: Courier.ElementalNode[]; +} diff --git a/src/api/resources/send/types/ElementalImageNode.ts b/src/api/resources/send/types/ElementalImageNode.ts new file mode 100644 index 0000000..d43b5b3 --- /dev/null +++ b/src/api/resources/send/types/ElementalImageNode.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * Used to embed an image into the notification. + */ +export interface ElementalImageNode extends Courier.ElementalBaseNode { + /** The source of the image. */ + src: string; + /** A URL to link to when the image is clicked. */ + href?: string; + /** The alignment of the image. */ + align?: Courier.IAlignment; + /** Alternate text for the image. */ + altText?: string; + /** CSS width properties to apply to the image. For example, 50px */ + width?: string; +} diff --git a/src/api/resources/send/types/ElementalMetaNode.ts b/src/api/resources/send/types/ElementalMetaNode.ts new file mode 100644 index 0000000..846b4d0 --- /dev/null +++ b/src/api/resources/send/types/ElementalMetaNode.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * The meta element contains information describing the notification that may + * be used by a particular channel or provider. One important field is the title + * field which will be used as the title for channels that support it. + * + */ +export interface ElementalMetaNode extends Courier.ElementalBaseNode { + /** The title to be displayed by supported channels. For example, the email subject. */ + title?: string; +} diff --git a/src/api/resources/send/types/ElementalNode.ts b/src/api/resources/send/types/ElementalNode.ts new file mode 100644 index 0000000..4e58ccf --- /dev/null +++ b/src/api/resources/send/types/ElementalNode.ts @@ -0,0 +1,49 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type ElementalNode = + | Courier.ElementalNode.Text + | Courier.ElementalNode.Meta + | Courier.ElementalNode.Channel + | Courier.ElementalNode.Image + | Courier.ElementalNode.Action + | Courier.ElementalNode.Divider + | Courier.ElementalNode.Group + | Courier.ElementalNode.Quote; + +export declare namespace ElementalNode { + interface Text extends Courier.ElementalTextNode { + type: "text"; + } + + interface Meta extends Courier.ElementalMetaNode { + type: "meta"; + } + + interface Channel extends Courier.ElementalChannelNode { + type: "channel"; + } + + interface Image extends Courier.ElementalImageNode { + type: "image"; + } + + interface Action extends Courier.ElementalActionNode { + type: "action"; + } + + interface Divider extends Courier.ElementalDividerNode { + type: "divider"; + } + + interface Group extends Courier.ElementalGroupNode { + type: "group"; + } + + interface Quote extends Courier.ElementalQuoteNode { + type: "quote"; + } +} diff --git a/src/api/resources/send/types/ElementalQuoteNode.ts b/src/api/resources/send/types/ElementalQuoteNode.ts new file mode 100644 index 0000000..e4c203b --- /dev/null +++ b/src/api/resources/send/types/ElementalQuoteNode.ts @@ -0,0 +1,20 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * Renders a quote block. + */ +export interface ElementalQuoteNode extends Courier.ElementalBaseNode { + /** The text value of the quote. */ + content: string; + /** Alignment of the quote. */ + align?: Courier.IAlignment; + /** CSS border color property. For example, `#fff` */ + borderColor?: string; + text_style: Courier.TextStyle; + /** Region specific content. See [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) for more details. */ + locales?: Courier.Locales; +} diff --git a/src/api/resources/send/types/ElementalTextNode.ts b/src/api/resources/send/types/ElementalTextNode.ts new file mode 100644 index 0000000..b10d188 --- /dev/null +++ b/src/api/resources/send/types/ElementalTextNode.ts @@ -0,0 +1,34 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * Represents a body of text to be rendered inside of the notification. + */ +export interface ElementalTextNode extends Courier.ElementalBaseNode { + /** + * The text content displayed in the notification. Either this + * field must be specified, or the elements field + * + */ + content: string; + /** Text alignment. */ + align: Courier.TextAlign; + /** Allows the text to be rendered as a heading level. */ + text_style?: Courier.TextStyle; + /** Specifies the color of text. Can be any valid css color value */ + color?: string; + /** Apply bold to the text */ + bold?: string; + /** Apply italics to the text */ + italic?: string; + /** Apply a strike through the text */ + strikethrough?: string; + /** Apply an underline to the text */ + underline?: string; + /** Region specific content. See [locales docs](https://www.courier.com/docs/platform/content/elemental/locales/) for more details. */ + locales?: Courier.Locales | undefined; + format?: "markdown"; +} diff --git a/src/api/resources/send/types/EmailFooter.ts b/src/api/resources/send/types/EmailFooter.ts new file mode 100644 index 0000000..79f42bc --- /dev/null +++ b/src/api/resources/send/types/EmailFooter.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface EmailFooter { + content?: any; + inheritDefault?: boolean; +} diff --git a/src/api/resources/send/types/EmailHead.ts b/src/api/resources/send/types/EmailHead.ts new file mode 100644 index 0000000..2b5096d --- /dev/null +++ b/src/api/resources/send/types/EmailHead.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface EmailHead { + inheritDefault: boolean; + content?: string; +} diff --git a/src/api/resources/send/types/EmailHeader.ts b/src/api/resources/send/types/EmailHeader.ts new file mode 100644 index 0000000..a9a1a82 --- /dev/null +++ b/src/api/resources/send/types/EmailHeader.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface EmailHeader { + inheritDefault?: boolean; + barColor?: string; + logo: Courier.Logo; +} diff --git a/src/api/resources/send/types/ExpiresInType.ts b/src/api/resources/send/types/ExpiresInType.ts new file mode 100644 index 0000000..6d9b76f --- /dev/null +++ b/src/api/resources/send/types/ExpiresInType.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ExpiresInType = string | number; diff --git a/src/api/resources/send/types/Expiry.ts b/src/api/resources/send/types/Expiry.ts new file mode 100644 index 0000000..1e4f346 --- /dev/null +++ b/src/api/resources/send/types/Expiry.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Expiry { + /** An epoch timestamp or ISO8601 timestamp with timezone `(YYYY-MM-DDThh:mm:ss.sTZD)` that describes the time in which a message expires. */ + expires_at?: string; + /** A duration in the form of milliseconds or an ISO8601 Duration format (i.e. P1DT4H). */ + expires_in: Courier.ExpiresInType; +} diff --git a/src/api/resources/send/types/IActionButtonStyle.ts b/src/api/resources/send/types/IActionButtonStyle.ts new file mode 100644 index 0000000..782fde0 --- /dev/null +++ b/src/api/resources/send/types/IActionButtonStyle.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type IActionButtonStyle = "button" | "link"; + +export const IActionButtonStyle = { + Button: "button", + Link: "link", +} as const; diff --git a/src/api/resources/send/types/IAlignment.ts b/src/api/resources/send/types/IAlignment.ts new file mode 100644 index 0000000..1a85727 --- /dev/null +++ b/src/api/resources/send/types/IAlignment.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type IAlignment = "center" | "left" | "right" | "full"; + +export const IAlignment = { + Center: "center", + Left: "left", + Right: "right", + Full: "full", +} as const; diff --git a/src/api/resources/send/types/IPreferences.ts b/src/api/resources/send/types/IPreferences.ts new file mode 100644 index 0000000..bcd2d31 --- /dev/null +++ b/src/api/resources/send/types/IPreferences.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type IPreferences = Record; diff --git a/src/api/resources/send/types/IProfilePreferences.ts b/src/api/resources/send/types/IProfilePreferences.ts new file mode 100644 index 0000000..2ee2592 --- /dev/null +++ b/src/api/resources/send/types/IProfilePreferences.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface IProfilePreferences { + categories?: Courier.IPreferences; + notifications: Courier.IPreferences; + templateId?: string; +} diff --git a/src/api/resources/send/types/Icons.ts b/src/api/resources/send/types/Icons.ts new file mode 100644 index 0000000..abd9da8 --- /dev/null +++ b/src/api/resources/send/types/Icons.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Icons { + bell?: string; + message?: string; +} diff --git a/src/api/resources/send/types/InAppPlacement.ts b/src/api/resources/send/types/InAppPlacement.ts new file mode 100644 index 0000000..31ed9f2 --- /dev/null +++ b/src/api/resources/send/types/InAppPlacement.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type InAppPlacement = "top" | "bottom" | "left" | "right"; + +export const InAppPlacement = { + Top: "top", + Bottom: "bottom", + Left: "left", + Right: "right", +} as const; diff --git a/src/api/resources/send/types/InvalidListPatternRecipient.ts b/src/api/resources/send/types/InvalidListPatternRecipient.ts new file mode 100644 index 0000000..0142aa3 --- /dev/null +++ b/src/api/resources/send/types/InvalidListPatternRecipient.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface InvalidListPatternRecipient { + user_id: string; + list_id: string; +} diff --git a/src/api/resources/send/types/InvalidListRecipient.ts b/src/api/resources/send/types/InvalidListRecipient.ts new file mode 100644 index 0000000..465cde5 --- /dev/null +++ b/src/api/resources/send/types/InvalidListRecipient.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface InvalidListRecipient { + user_id: string; + list_pattern: string; +} diff --git a/src/api/resources/send/types/InvalidUserRecipient.ts b/src/api/resources/send/types/InvalidUserRecipient.ts new file mode 100644 index 0000000..ff5f63a --- /dev/null +++ b/src/api/resources/send/types/InvalidUserRecipient.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface InvalidUserRecipient { + list_id: string; + list_pattern: string; +} diff --git a/src/api/resources/send/types/ListFilter.ts b/src/api/resources/send/types/ListFilter.ts new file mode 100644 index 0000000..c58621d --- /dev/null +++ b/src/api/resources/send/types/ListFilter.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListFilter { + /** Send to users only if they are member of the account */ + operator: "MEMBER_OF"; + path: "account_id"; + value: string; +} diff --git a/src/api/resources/send/types/ListPatternRecipient.ts b/src/api/resources/send/types/ListPatternRecipient.ts new file mode 100644 index 0000000..0d41884 --- /dev/null +++ b/src/api/resources/send/types/ListPatternRecipient.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListPatternRecipient extends Courier.ListPatternRecipientType { + list_pattern?: string; + data?: Courier.MessageData; +} diff --git a/src/api/resources/send/types/ListPatternRecipientType.ts b/src/api/resources/send/types/ListPatternRecipientType.ts new file mode 100644 index 0000000..166e48c --- /dev/null +++ b/src/api/resources/send/types/ListPatternRecipientType.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListPatternRecipientType {} diff --git a/src/api/resources/send/types/ListRecipient.ts b/src/api/resources/send/types/ListRecipient.ts new file mode 100644 index 0000000..6047b56 --- /dev/null +++ b/src/api/resources/send/types/ListRecipient.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListRecipient extends Courier.ListRecipientType { + list_id?: string; + data?: Courier.MessageData; + filters?: Courier.ListFilter[]; +} diff --git a/src/api/resources/send/types/ListRecipientType.ts b/src/api/resources/send/types/ListRecipientType.ts new file mode 100644 index 0000000..ba7a092 --- /dev/null +++ b/src/api/resources/send/types/ListRecipientType.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListRecipientType {} diff --git a/src/api/resources/send/types/Locale.ts b/src/api/resources/send/types/Locale.ts new file mode 100644 index 0000000..a59b713 --- /dev/null +++ b/src/api/resources/send/types/Locale.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Locale { + content: string; +} diff --git a/src/api/resources/send/types/Locales.ts b/src/api/resources/send/types/Locales.ts new file mode 100644 index 0000000..c4504fd --- /dev/null +++ b/src/api/resources/send/types/Locales.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Locales = Record | undefined; diff --git a/src/api/resources/send/types/Logo.ts b/src/api/resources/send/types/Logo.ts new file mode 100644 index 0000000..3b14edc --- /dev/null +++ b/src/api/resources/send/types/Logo.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Logo { + href?: string; + image?: string; +} diff --git a/src/api/resources/send/types/Message.ts b/src/api/resources/send/types/Message.ts new file mode 100644 index 0000000..9849ebe --- /dev/null +++ b/src/api/resources/send/types/Message.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Message = + /** + * Describes the content of the message in a way that will work for email, push, chat, or any channel. */ + | Courier.ContentMessage + /** + * A template for a type of message that can be sent more than once. For example, you might create an "Appointment Reminder" Notification or “Reset Password” Notifications. */ + | Courier.TemplateMessage; diff --git a/src/api/resources/send/types/MessageChannelEmailOverride.ts b/src/api/resources/send/types/MessageChannelEmailOverride.ts new file mode 100644 index 0000000..3b1bb00 --- /dev/null +++ b/src/api/resources/send/types/MessageChannelEmailOverride.ts @@ -0,0 +1,18 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface MessageChannelEmailOverride { + attachments?: Courier.Attachment[]; + bcc?: string; + brand?: Courier.Brand; + cc?: string; + from?: string; + html?: string; + reply_to?: string; + subject?: string; + text?: string; + tracking: Courier.TrackingOverride; +} diff --git a/src/api/resources/send/types/MessageChannels.ts b/src/api/resources/send/types/MessageChannels.ts new file mode 100644 index 0000000..4198735 --- /dev/null +++ b/src/api/resources/send/types/MessageChannels.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type MessageChannels = Record; diff --git a/src/api/resources/send/types/MessageContext.ts b/src/api/resources/send/types/MessageContext.ts new file mode 100644 index 0000000..1e902f8 --- /dev/null +++ b/src/api/resources/send/types/MessageContext.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface MessageContext { + /** + * An id of a tenant, see [tenants api docs](https://www.courier.com/docs/reference/tenants/). + * Will load brand, default preferences and any other base context data associated with this tenant. + * + */ + tenant_id?: string; +} diff --git a/src/api/resources/send/types/MessageData.ts b/src/api/resources/send/types/MessageData.ts new file mode 100644 index 0000000..d7e947b --- /dev/null +++ b/src/api/resources/send/types/MessageData.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MessageData = Record; diff --git a/src/api/resources/send/types/MessageMetadata.ts b/src/api/resources/send/types/MessageMetadata.ts new file mode 100644 index 0000000..b5990e9 --- /dev/null +++ b/src/api/resources/send/types/MessageMetadata.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface MessageMetadata { + /** An arbitrary string to tracks the event that generated this request (e.g. 'signup'). */ + event?: string; + /** An array of up to 9 tags you wish to associate with this request (and corresponding messages) for later analysis. Individual tags cannot be more than 30 characters in length. */ + tags?: string[]; + /** Identify the campaign that refers traffic to a specific website, and attributes the browser's website session. */ + utm?: Courier.Utm; + /** A unique ID used to correlate this request to processing on your servers. Note: Courier does not verify the uniqueness of this ID. */ + trace_id?: string; +} diff --git a/src/api/resources/send/types/MessageProviders.ts b/src/api/resources/send/types/MessageProviders.ts new file mode 100644 index 0000000..0c6f60e --- /dev/null +++ b/src/api/resources/send/types/MessageProviders.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type MessageProviders = Record; diff --git a/src/api/resources/send/types/MessageProvidersType.ts b/src/api/resources/send/types/MessageProvidersType.ts new file mode 100644 index 0000000..dfa84cd --- /dev/null +++ b/src/api/resources/send/types/MessageProvidersType.ts @@ -0,0 +1,19 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface MessageProvidersType { + /** Provider specific overrides. */ + override?: Record; + /** + * A JavaScript conditional expression to determine if the message should be sent + * through the channel. Has access to the data and profile object. For example, + * `data.name === profile.name` + * + */ + if?: string; + timeouts?: number; + metadata?: Courier.Metadata; +} diff --git a/src/api/resources/send/types/MessageRecipient.ts b/src/api/resources/send/types/MessageRecipient.ts new file mode 100644 index 0000000..8cc1e2d --- /dev/null +++ b/src/api/resources/send/types/MessageRecipient.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type MessageRecipient = Courier.Recipient | Courier.Recipient[]; diff --git a/src/api/resources/send/types/Metadata.ts b/src/api/resources/send/types/Metadata.ts new file mode 100644 index 0000000..fec58ba --- /dev/null +++ b/src/api/resources/send/types/Metadata.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Metadata { + utm?: Courier.Utm; +} diff --git a/src/api/resources/send/types/Override.ts b/src/api/resources/send/types/Override.ts new file mode 100644 index 0000000..2d5e63f --- /dev/null +++ b/src/api/resources/send/types/Override.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type Override = "MessageChannelEmailOverride" | "MessageChannelPushOverride"; + +export const Override = { + MessageChannelEmailOverride: "MessageChannelEmailOverride", + MessageChannelPushOverride: "MessageChannelPushOverride", +} as const; diff --git a/src/api/resources/send/types/Preference.ts b/src/api/resources/send/types/Preference.ts new file mode 100644 index 0000000..cc1d6c1 --- /dev/null +++ b/src/api/resources/send/types/Preference.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Preference { + status: Courier.PreferenceStatus; + rules?: Courier.Rule[]; + channel_preferences?: Courier.ChannelPreference[]; + source?: Courier.ChannelSource; +} diff --git a/src/api/resources/send/types/Preferences.ts b/src/api/resources/send/types/Preferences.ts new file mode 100644 index 0000000..972478a --- /dev/null +++ b/src/api/resources/send/types/Preferences.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Preferences { + templateIds: string[]; +} diff --git a/src/api/resources/send/types/Recipient.ts b/src/api/resources/send/types/Recipient.ts new file mode 100644 index 0000000..01ce69e --- /dev/null +++ b/src/api/resources/send/types/Recipient.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type Recipient = + | Courier.AudienceRecipient + | Courier.ListRecipient + | Courier.ListPatternRecipient + | Courier.UserRecipient; diff --git a/src/api/resources/send/types/Routing.ts b/src/api/resources/send/types/Routing.ts new file mode 100644 index 0000000..9e7337d --- /dev/null +++ b/src/api/resources/send/types/Routing.ts @@ -0,0 +1,22 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * Allows you to customize which channel(s) Courier will potentially deliver the message. + * If no routing key is specified, Courier will use the default routing configuration or + * routing defined by the template. + * + */ +export interface Routing { + method: Courier.RoutingMethod; + /** + * A list of channels or providers to send the message through. Can also recursively define + * sub-routing methods, which can be useful for defining advanced push notification + * delivery strategies. + * + */ + channels: Courier.RoutingChannel[]; +} diff --git a/src/api/resources/send/types/RoutingChannel.ts b/src/api/resources/send/types/RoutingChannel.ts new file mode 100644 index 0000000..392a528 --- /dev/null +++ b/src/api/resources/send/types/RoutingChannel.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export type RoutingChannel = Courier.RoutingStrategyChannel | Courier.RoutingStrategyProvider | string; diff --git a/src/api/resources/send/types/RoutingMethod.ts b/src/api/resources/send/types/RoutingMethod.ts new file mode 100644 index 0000000..3108f41 --- /dev/null +++ b/src/api/resources/send/types/RoutingMethod.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type RoutingMethod = "all" | "single"; + +export const RoutingMethod = { + All: "all", + Single: "single", +} as const; diff --git a/src/api/resources/send/types/RoutingStrategyChannel.ts b/src/api/resources/send/types/RoutingStrategyChannel.ts new file mode 100644 index 0000000..b564439 --- /dev/null +++ b/src/api/resources/send/types/RoutingStrategyChannel.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RoutingStrategyChannel { + channel: string; + config?: Record; + method?: Courier.RoutingMethod; + providers?: Courier.MessageProviders; + if?: string; +} diff --git a/src/api/resources/send/types/RoutingStrategyProvider.ts b/src/api/resources/send/types/RoutingStrategyProvider.ts new file mode 100644 index 0000000..6340371 --- /dev/null +++ b/src/api/resources/send/types/RoutingStrategyProvider.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RoutingStrategyProvider { + name: string; + config?: Record; + if?: string; + metadata: Courier.Metadata; +} diff --git a/src/api/resources/send/types/RuleType.ts b/src/api/resources/send/types/RuleType.ts new file mode 100644 index 0000000..8966309 --- /dev/null +++ b/src/api/resources/send/types/RuleType.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type RuleType = "snooze" | "channel_preferences" | "status"; + +export const RuleType = { + Snooze: "snooze", + ChannelPreferences: "channel_preferences", + Status: "status", +} as const; diff --git a/src/api/resources/send/types/TemplateMessage.ts b/src/api/resources/send/types/TemplateMessage.ts new file mode 100644 index 0000000..71552ad --- /dev/null +++ b/src/api/resources/send/types/TemplateMessage.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface TemplateMessage extends Courier.BaseMessage { + /** + * The id of the notification template to be rendered and sent to the recipient(s). + * This field or the content field must be supplied. + * + */ + template: string; +} diff --git a/src/api/resources/send/types/TextAlign.ts b/src/api/resources/send/types/TextAlign.ts new file mode 100644 index 0000000..add2ac7 --- /dev/null +++ b/src/api/resources/send/types/TextAlign.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TextAlign = "left" | "center" | "right"; + +export const TextAlign = { + Left: "left", + Center: "center", + Right: "right", +} as const; diff --git a/src/api/resources/send/types/TextStyle.ts b/src/api/resources/send/types/TextStyle.ts new file mode 100644 index 0000000..e2d5f7c --- /dev/null +++ b/src/api/resources/send/types/TextStyle.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TextStyle = "text" | "h1" | "h2" | "subtext"; + +export const TextStyle = { + Text: "text", + H1: "h1", + H2: "h2", + Subtext: "subtext", +} as const; diff --git a/src/api/resources/send/types/Timeout.ts b/src/api/resources/send/types/Timeout.ts new file mode 100644 index 0000000..2f49e51 --- /dev/null +++ b/src/api/resources/send/types/Timeout.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Timeout { + provider?: Record; + channel?: Record; + message?: number; + escalation?: number; + criteria?: Courier.Criteria; +} diff --git a/src/api/resources/send/types/Timeouts.ts b/src/api/resources/send/types/Timeouts.ts new file mode 100644 index 0000000..7758cc6 --- /dev/null +++ b/src/api/resources/send/types/Timeouts.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Timeouts { + provider?: number; + channel?: number; +} diff --git a/src/api/resources/send/types/TrackingOverride.ts b/src/api/resources/send/types/TrackingOverride.ts new file mode 100644 index 0000000..b192a68 --- /dev/null +++ b/src/api/resources/send/types/TrackingOverride.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface TrackingOverride { + open: boolean; +} diff --git a/src/api/resources/send/types/UserRecipient.ts b/src/api/resources/send/types/UserRecipient.ts new file mode 100644 index 0000000..68057ee --- /dev/null +++ b/src/api/resources/send/types/UserRecipient.ts @@ -0,0 +1,25 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface UserRecipient extends Courier.UserRecipientType { + /** Use `tenant_id` instad. */ + account_id?: string; + /** Context information such as tenant_id to send the notification with. */ + context?: Courier.MessageContext; + data?: Courier.MessageData; + email?: string; + /** The user's preferred ISO 639-1 language code. */ + locale?: string; + user_id?: string; + phone_number?: string; + preferences?: Courier.IProfilePreferences; + /** + * An id of a tenant, [see tenants api docs](https://www.courier.com/docs/reference/tenants). + * Will load brand, default preferences and any other base context data associated with this tenant. + * + */ + tenant_id?: string; +} diff --git a/src/api/resources/send/types/UserRecipientType.ts b/src/api/resources/send/types/UserRecipientType.ts new file mode 100644 index 0000000..a2f51dd --- /dev/null +++ b/src/api/resources/send/types/UserRecipientType.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface UserRecipientType {} diff --git a/src/api/resources/send/types/Utm.ts b/src/api/resources/send/types/Utm.ts new file mode 100644 index 0000000..342039a --- /dev/null +++ b/src/api/resources/send/types/Utm.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Utm { + source?: string; + medium?: string; + campaign?: string; + term?: string; + content?: string; +} diff --git a/src/api/resources/send/types/WidgetBackground.ts b/src/api/resources/send/types/WidgetBackground.ts new file mode 100644 index 0000000..1e16c35 --- /dev/null +++ b/src/api/resources/send/types/WidgetBackground.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface WidgetBackground { + topColor?: string; + bottomColor?: string; +} diff --git a/src/api/resources/send/types/index.ts b/src/api/resources/send/types/index.ts new file mode 100644 index 0000000..f122892 --- /dev/null +++ b/src/api/resources/send/types/index.ts @@ -0,0 +1,81 @@ +export * from "./Message"; +export * from "./TemplateMessage"; +export * from "./ContentMessage"; +export * from "./BaseMessage"; +export * from "./MessageRecipient"; +export * from "./Recipient"; +export * from "./AudienceRecipient"; +export * from "./InvalidListPatternRecipient"; +export * from "./ListPatternRecipientType"; +export * from "./ListPatternRecipient"; +export * from "./InvalidListRecipient"; +export * from "./ListRecipientType"; +export * from "./ListRecipient"; +export * from "./InvalidUserRecipient"; +export * from "./UserRecipientType"; +export * from "./UserRecipient"; +export * from "./MessageData"; +export * from "./AudienceFilter"; +export * from "./MessageContext"; +export * from "./ListFilter"; +export * from "./Expiry"; +export * from "./ExpiresInType"; +export * from "./Delay"; +export * from "./Routing"; +export * from "./MessageChannels"; +export * from "./Channel"; +export * from "./ChannelMetadata"; +export * from "./Timeout"; +export * from "./Criteria"; +export * from "./RoutingMethod"; +export * from "./Timeouts"; +export * from "./Override"; +export * from "./MessageChannelEmailOverride"; +export * from "./Attachment"; +export * from "./MessageMetadata"; +export * from "./Utm"; +export * from "./TrackingOverride"; +export * from "./Content"; +export * from "./ElementalContent"; +export * from "./ElementalNode"; +export * from "./ElementalContentSugar"; +export * from "./ElementalActionNode"; +export * from "./Locales"; +export * from "./Locale"; +export * from "./IActionButtonStyle"; +export * from "./IAlignment"; +export * from "./ElementalDividerNode"; +export * from "./ElementalGroupNode"; +export * from "./ElementalChannelNode"; +export * from "./ElementalTextNode"; +export * from "./ElementalQuoteNode"; +export * from "./TextStyle"; +export * from "./ElementalMetaNode"; +export * from "./ElementalImageNode"; +export * from "./ElementalBaseNode"; +export * from "./Preference"; +export * from "./RuleType"; +export * from "./ChannelSource"; +export * from "./IPreferences"; +export * from "./IProfilePreferences"; +export * from "./BrandTemplate"; +export * from "./BrandTemplateOverride"; +export * from "./BrandSettingsSocialPresence"; +export * from "./BaseSocialPresence"; +export * from "./BrandSettingsEmail"; +export * from "./EmailHead"; +export * from "./EmailFooter"; +export * from "./EmailHeader"; +export * from "./Logo"; +export * from "./BrandSettingsInApp"; +export * from "./InAppPlacement"; +export * from "./TextAlign"; +export * from "./WidgetBackground"; +export * from "./Icons"; +export * from "./Preferences"; +export * from "./RoutingStrategyProvider"; +export * from "./Metadata"; +export * from "./RoutingStrategyChannel"; +export * from "./MessageProviders"; +export * from "./MessageProvidersType"; +export * from "./RoutingChannel"; diff --git a/src/api/resources/templates/client/Client.ts b/src/api/resources/templates/client/Client.ts new file mode 100644 index 0000000..1f88857 --- /dev/null +++ b/src/api/resources/templates/client/Client.ts @@ -0,0 +1,92 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Templates { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } +} + +export class Templates { + constructor(protected readonly _options: Templates.Options) {} + + /** + * Returns a list of notification templates + */ + public async list( + request: Courier.ListTemplatesRequest = {}, + requestOptions?: Templates.RequestOptions + ): Promise { + const { cursor } = request; + const _queryParams: Record = {}; + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + "/notifications" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.ListTemplatesResponse; + } + + if (_response.error.reason === "status-code") { + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/templates/client/index.ts b/src/api/resources/templates/client/index.ts new file mode 100644 index 0000000..415726b --- /dev/null +++ b/src/api/resources/templates/client/index.ts @@ -0,0 +1 @@ +export * from "./requests"; diff --git a/src/api/resources/templates/client/requests/ListTemplatesRequest.ts b/src/api/resources/templates/client/requests/ListTemplatesRequest.ts new file mode 100644 index 0000000..4ba6eb1 --- /dev/null +++ b/src/api/resources/templates/client/requests/ListTemplatesRequest.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListTemplatesRequest { + /** + * A unique identifier that allows for fetching the next set of templates + */ + cursor?: string; +} diff --git a/src/api/resources/templates/client/requests/index.ts b/src/api/resources/templates/client/requests/index.ts new file mode 100644 index 0000000..dd129f9 --- /dev/null +++ b/src/api/resources/templates/client/requests/index.ts @@ -0,0 +1 @@ +export { ListTemplatesRequest } from "./ListTemplatesRequest"; diff --git a/src/api/resources/templates/index.ts b/src/api/resources/templates/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/templates/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/templates/types/ChannelIdentifier.ts b/src/api/resources/templates/types/ChannelIdentifier.ts new file mode 100644 index 0000000..11fecc5 --- /dev/null +++ b/src/api/resources/templates/types/ChannelIdentifier.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ChannelIdentifier = string; diff --git a/src/api/resources/templates/types/ListTemplatesResponse.ts b/src/api/resources/templates/types/ListTemplatesResponse.ts new file mode 100644 index 0000000..1c503bc --- /dev/null +++ b/src/api/resources/templates/types/ListTemplatesResponse.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface ListTemplatesResponse { + paging: Courier.Paging; + /** An array of Notification Templates */ + results: Courier.NotificationTemplates[]; +} diff --git a/src/api/resources/templates/types/NotificationTemplates.ts b/src/api/resources/templates/types/NotificationTemplates.ts new file mode 100644 index 0000000..225a3f1 --- /dev/null +++ b/src/api/resources/templates/types/NotificationTemplates.ts @@ -0,0 +1,20 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface NotificationTemplates { + /** A UTC timestamp at which notification was created. This is stored as a millisecond representation of the Unix epoch (the time passed since January 1, 1970). */ + created_at: number; + /** A unique identifier associated with the notification. */ + id: string; + /** Routing strategy used by this notification. */ + routing: Courier.RoutingStrategy; + /** A list of tags attached to the notification. */ + tags: Courier.Tag[]; + /** The title of the notification. */ + title: string; + /** A UTC timestamp at which notification was updated. This is stored as a millisecond representation of the Unix epoch (the time passed since January 1, 1970). */ + updated_at: number; +} diff --git a/src/api/resources/templates/types/RoutingStrategy.ts b/src/api/resources/templates/types/RoutingStrategy.ts new file mode 100644 index 0000000..30fa442 --- /dev/null +++ b/src/api/resources/templates/types/RoutingStrategy.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface RoutingStrategy { + /** The method for selecting channels to send the message with. Value can be either 'single' or 'all'. If not provided will default to 'single' */ + method: Courier.RoutingStrategyMethod; + /** An array of valid channel identifiers (like email, push, sms, etc.) and additional routing nodes. */ + channels: Courier.ChannelIdentifier[]; +} diff --git a/src/api/resources/templates/types/RoutingStrategyMethod.ts b/src/api/resources/templates/types/RoutingStrategyMethod.ts new file mode 100644 index 0000000..bbde1e3 --- /dev/null +++ b/src/api/resources/templates/types/RoutingStrategyMethod.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type RoutingStrategyMethod = "all" | "single"; + +export const RoutingStrategyMethod = { + All: "all", + Single: "single", +} as const; diff --git a/src/api/resources/templates/types/Tag.ts b/src/api/resources/templates/types/Tag.ts new file mode 100644 index 0000000..f4be223 --- /dev/null +++ b/src/api/resources/templates/types/Tag.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface Tag { + data: Courier.TagData[]; +} diff --git a/src/api/resources/templates/types/TagData.ts b/src/api/resources/templates/types/TagData.ts new file mode 100644 index 0000000..b8f4373 --- /dev/null +++ b/src/api/resources/templates/types/TagData.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface TagData { + /** A unique identifier of the tag. */ + id: string; + /** Name of the tag. */ + name: string; +} diff --git a/src/api/resources/templates/types/index.ts b/src/api/resources/templates/types/index.ts new file mode 100644 index 0000000..8e59cb9 --- /dev/null +++ b/src/api/resources/templates/types/index.ts @@ -0,0 +1,7 @@ +export * from "./ListTemplatesResponse"; +export * from "./NotificationTemplates"; +export * from "./RoutingStrategy"; +export * from "./RoutingStrategyMethod"; +export * from "./ChannelIdentifier"; +export * from "./Tag"; +export * from "./TagData"; diff --git a/src/api/resources/tenants/client/Client.ts b/src/api/resources/tenants/client/Client.ts new file mode 100644 index 0000000..348860b --- /dev/null +++ b/src/api/resources/tenants/client/Client.ts @@ -0,0 +1,92 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Tenants { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } +} + +export class Tenants { + constructor(protected readonly _options: Tenants.Options) {} + + /** + * @throws {@link Courier.BadRequestError} + */ + public async createOrReplace( + tenantId: string, + request: Courier.CreateOrReplaceTenantRequest, + requestOptions?: Tenants.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/tenants/${tenantId}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.CreateOrReplaceTenantResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/tenants/client/index.ts b/src/api/resources/tenants/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/tenants/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/tenants/index.ts b/src/api/resources/tenants/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/tenants/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/tenants/types/CreateOrReplaceTenantRequest.ts b/src/api/resources/tenants/types/CreateOrReplaceTenantRequest.ts new file mode 100644 index 0000000..744834e --- /dev/null +++ b/src/api/resources/tenants/types/CreateOrReplaceTenantRequest.ts @@ -0,0 +1,20 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface CreateOrReplaceTenantRequest { + /** Name of the tenant. */ + name: string; + /** Tenant's parent id (if any). */ + parent_tenant_id: string; + /** Defines the preferences used for the tenant when the user hasn't specified their own. */ + default_preferences: Courier.DefaultPreferences; + /** Arbitrary properties accessible to a template. */ + properties: (Courier.TemplateProperty | undefined)[]; + /** A user profile object merged with user profile on send. */ + user_profile?: any; + /** Brand to be used for the account when one is not specified by the send call. */ + brand_id: string; +} diff --git a/src/api/resources/tenants/types/CreateOrReplaceTenantResponse.ts b/src/api/resources/tenants/types/CreateOrReplaceTenantResponse.ts new file mode 100644 index 0000000..1c1fa9f --- /dev/null +++ b/src/api/resources/tenants/types/CreateOrReplaceTenantResponse.ts @@ -0,0 +1,22 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface CreateOrReplaceTenantResponse { + /** Id of the tenant. */ + id: string; + /** Name of the tenant. */ + name: string; + /** Tenant's parent id (if any). */ + parent_tenant_id?: string; + /** Defines the preferences used for the account when the user hasn't specified their own. */ + default_preferences?: Courier.DefaultPreferences; + /** Arbitrary properties accessible to a template. */ + properties?: Courier.TemplateProperty | undefined; + /** A user profile object merged with user profile on send. */ + user_profile?: any; + /** Brand to be used for the account when one is not specified by the send call. */ + brand_id: string; +} diff --git a/src/api/resources/tenants/types/DefaultPreferences.ts b/src/api/resources/tenants/types/DefaultPreferences.ts new file mode 100644 index 0000000..db8bff1 --- /dev/null +++ b/src/api/resources/tenants/types/DefaultPreferences.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface DefaultPreferences { + items: Courier.SubscriptionTopic[]; +} diff --git a/src/api/resources/tenants/types/SubscriptionTopic.ts b/src/api/resources/tenants/types/SubscriptionTopic.ts new file mode 100644 index 0000000..1a8a6a2 --- /dev/null +++ b/src/api/resources/tenants/types/SubscriptionTopic.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface SubscriptionTopic { + /** Topic ID */ + id: string; + status: Courier.SubscriptionTopicStatus; +} diff --git a/src/api/resources/tenants/types/SubscriptionTopicStatus.ts b/src/api/resources/tenants/types/SubscriptionTopicStatus.ts new file mode 100644 index 0000000..244671e --- /dev/null +++ b/src/api/resources/tenants/types/SubscriptionTopicStatus.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type SubscriptionTopicStatus = "OPTED_OUT" | "OPTED_IN" | "REQUIRED"; + +export const SubscriptionTopicStatus = { + OptedOut: "OPTED_OUT", + OptedIn: "OPTED_IN", + Required: "REQUIRED", +} as const; diff --git a/src/api/resources/tenants/types/TemplateProperty.ts b/src/api/resources/tenants/types/TemplateProperty.ts new file mode 100644 index 0000000..25bd334 --- /dev/null +++ b/src/api/resources/tenants/types/TemplateProperty.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TemplateProperty = any; diff --git a/src/api/resources/tenants/types/index.ts b/src/api/resources/tenants/types/index.ts new file mode 100644 index 0000000..a21cfd7 --- /dev/null +++ b/src/api/resources/tenants/types/index.ts @@ -0,0 +1,6 @@ +export * from "./CreateOrReplaceTenantRequest"; +export * from "./DefaultPreferences"; +export * from "./SubscriptionTopic"; +export * from "./SubscriptionTopicStatus"; +export * from "./CreateOrReplaceTenantResponse"; +export * from "./TemplateProperty"; diff --git a/src/api/resources/tokenManagement/client/Client.ts b/src/api/resources/tokenManagement/client/Client.ts new file mode 100644 index 0000000..31eba06 --- /dev/null +++ b/src/api/resources/tokenManagement/client/Client.ts @@ -0,0 +1,315 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace TokenManagement { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } +} + +export class TokenManagement { + constructor(protected readonly _options: TokenManagement.Options) {} + + /** + * Adds multiple tokens to a user and overwrites matching existing tokens. + * @throws {@link Courier.BadRequestError} + */ + public async addMultipleTokens(userId: string, requestOptions?: TokenManagement.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/tokens` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Adds a single token to a user and overwrites a matching existing token. + * @throws {@link Courier.BadRequestError} + */ + public async add( + userId: string, + token: string, + request: Courier.UserToken, + requestOptions?: TokenManagement.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/tokens/${token}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Apply a JSON Patch (RFC 6902) to the specified token. + * @throws {@link Courier.BadRequestError} + */ + public async update( + userId: string, + token: string, + request: Courier.PatchUserTokenOpts, + requestOptions?: TokenManagement.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/tokens/${token}` + ), + method: "PATCH", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Get single token available for a `:token` + * @throws {@link Courier.BadRequestError} + */ + public async get( + userId: string, + token: string, + requestOptions?: TokenManagement.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/tokens/${token}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.GetUserTokenResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Gets all tokens available for a :user_id + * @throws {@link Courier.BadRequestError} + */ + public async list( + userId: string, + requestOptions?: TokenManagement.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/tokens` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.GetAllTokensResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/tokenManagement/client/index.ts b/src/api/resources/tokenManagement/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/tokenManagement/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/tokenManagement/index.ts b/src/api/resources/tokenManagement/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/tokenManagement/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/tokenManagement/types/DeleteUserTokenOpts.ts b/src/api/resources/tokenManagement/types/DeleteUserTokenOpts.ts new file mode 100644 index 0000000..a3bcd56 --- /dev/null +++ b/src/api/resources/tokenManagement/types/DeleteUserTokenOpts.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface DeleteUserTokenOpts { + user_id: string; + token: string; +} diff --git a/src/api/resources/tokenManagement/types/Device.ts b/src/api/resources/tokenManagement/types/Device.ts new file mode 100644 index 0000000..082c7f6 --- /dev/null +++ b/src/api/resources/tokenManagement/types/Device.ts @@ -0,0 +1,18 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Device { + /** Id of the application the token is used for */ + app_id?: string; + /** Id of the advertising identifier */ + ad_id?: string; + /** Id of the device the token is associated with */ + device_id?: string; + /** The device platform i.e. android, ios, web */ + platform?: string; + /** The device manufacturer */ + manufacturer?: string; + /** The device model */ + model?: string; +} diff --git a/src/api/resources/tokenManagement/types/ExpiryDate.ts b/src/api/resources/tokenManagement/types/ExpiryDate.ts new file mode 100644 index 0000000..d5a8cb7 --- /dev/null +++ b/src/api/resources/tokenManagement/types/ExpiryDate.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ExpiryDate = string | boolean; diff --git a/src/api/resources/tokenManagement/types/GetAllTokensResponse.ts b/src/api/resources/tokenManagement/types/GetAllTokensResponse.ts new file mode 100644 index 0000000..2c2b7f7 --- /dev/null +++ b/src/api/resources/tokenManagement/types/GetAllTokensResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +/** + * A list of tokens registered with the user. + */ +export type GetAllTokensResponse = Courier.UserToken[]; diff --git a/src/api/resources/tokenManagement/types/GetUserTokenOpts.ts b/src/api/resources/tokenManagement/types/GetUserTokenOpts.ts new file mode 100644 index 0000000..4d2e2a4 --- /dev/null +++ b/src/api/resources/tokenManagement/types/GetUserTokenOpts.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetUserTokenOpts { + user_id: string; + token: string; +} diff --git a/src/api/resources/tokenManagement/types/GetUserTokenResponse.ts b/src/api/resources/tokenManagement/types/GetUserTokenResponse.ts new file mode 100644 index 0000000..ed89b52 --- /dev/null +++ b/src/api/resources/tokenManagement/types/GetUserTokenResponse.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface GetUserTokenResponse extends Courier.UserToken { + status?: Courier.TokenStatus; + /** The reason for the token status. */ + status_reason?: string; +} diff --git a/src/api/resources/tokenManagement/types/GetUserTokensOpts.ts b/src/api/resources/tokenManagement/types/GetUserTokensOpts.ts new file mode 100644 index 0000000..3915c71 --- /dev/null +++ b/src/api/resources/tokenManagement/types/GetUserTokensOpts.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetUserTokensOpts { + user_id: string; +} diff --git a/src/api/resources/tokenManagement/types/PatchOp.ts b/src/api/resources/tokenManagement/types/PatchOp.ts new file mode 100644 index 0000000..2392207 --- /dev/null +++ b/src/api/resources/tokenManagement/types/PatchOp.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type PatchOp = "replace" | "add" | "remove" | "copy" | "move" | "test"; + +export const PatchOp = { + Replace: "replace", + Add: "add", + Remove: "remove", + Copy: "copy", + Move: "move", + Test: "test", +} as const; diff --git a/src/api/resources/tokenManagement/types/PatchOperation.ts b/src/api/resources/tokenManagement/types/PatchOperation.ts new file mode 100644 index 0000000..37cba4b --- /dev/null +++ b/src/api/resources/tokenManagement/types/PatchOperation.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface PatchOperation { + /** The operation to perform. */ + op: string; + /** The JSON path specifying the part of the profile to operate on. */ + path: string; + /** The value for the operation. */ + value?: string; +} diff --git a/src/api/resources/tokenManagement/types/PatchUserTokenOpts.ts b/src/api/resources/tokenManagement/types/PatchUserTokenOpts.ts new file mode 100644 index 0000000..7bfc30d --- /dev/null +++ b/src/api/resources/tokenManagement/types/PatchUserTokenOpts.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface PatchUserTokenOpts { + patch: Courier.PatchOperation[]; +} diff --git a/src/api/resources/tokenManagement/types/ProviderKey.ts b/src/api/resources/tokenManagement/types/ProviderKey.ts new file mode 100644 index 0000000..f09f359 --- /dev/null +++ b/src/api/resources/tokenManagement/types/ProviderKey.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ProviderKey = "firebase-fcm" | "apn" | "expo" | "onesignal"; + +export const ProviderKey = { + FirebaseFcm: "firebase-fcm", + Apn: "apn", + Expo: "expo", + Onesignal: "onesignal", +} as const; diff --git a/src/api/resources/tokenManagement/types/PutUserTokenOpts.ts b/src/api/resources/tokenManagement/types/PutUserTokenOpts.ts new file mode 100644 index 0000000..84053cc --- /dev/null +++ b/src/api/resources/tokenManagement/types/PutUserTokenOpts.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface PutUserTokenOpts { + user_id: string; + token: Courier.UserToken; +} diff --git a/src/api/resources/tokenManagement/types/PutUserTokensOpts.ts b/src/api/resources/tokenManagement/types/PutUserTokensOpts.ts new file mode 100644 index 0000000..4224349 --- /dev/null +++ b/src/api/resources/tokenManagement/types/PutUserTokensOpts.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface PutUserTokensOpts { + user_id: string; + tokens: Courier.UserToken[]; +} diff --git a/src/api/resources/tokenManagement/types/TokenStatus.ts b/src/api/resources/tokenManagement/types/TokenStatus.ts new file mode 100644 index 0000000..4b7656b --- /dev/null +++ b/src/api/resources/tokenManagement/types/TokenStatus.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TokenStatus = "active" | "unknown" | "failed" | "revoked"; + +export const TokenStatus = { + Active: "active", + Unknown: "unknown", + Failed: "failed", + Revoked: "revoked", +} as const; diff --git a/src/api/resources/tokenManagement/types/Tracking.ts b/src/api/resources/tokenManagement/types/Tracking.ts new file mode 100644 index 0000000..030accf --- /dev/null +++ b/src/api/resources/tokenManagement/types/Tracking.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface Tracking { + /** The operating system version */ + os_version?: string; + /** The IP address of the device */ + ip?: string; + /** The latitude of the device */ + lat?: string; + /** The longitude of the device */ + long?: string; +} diff --git a/src/api/resources/tokenManagement/types/UserToken.ts b/src/api/resources/tokenManagement/types/UserToken.ts new file mode 100644 index 0000000..a6b0cfc --- /dev/null +++ b/src/api/resources/tokenManagement/types/UserToken.ts @@ -0,0 +1,19 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface UserToken { + /** Full body of the token. Must match token in URL. */ + token?: string; + provider_key: Courier.ProviderKey; + /** ISO 8601 formatted date the token expires. Defaults to 2 months. Set to false to disable expiration. */ + expiry_date?: Courier.ExpiryDate; + /** Properties sent to the provider along with the token */ + properties?: any; + /** Information about the device the token is associated with. */ + device?: Courier.Device; + /** Information about the device the token is associated with. */ + tracking?: Courier.Tracking; +} diff --git a/src/api/resources/tokenManagement/types/index.ts b/src/api/resources/tokenManagement/types/index.ts new file mode 100644 index 0000000..bd6a9c4 --- /dev/null +++ b/src/api/resources/tokenManagement/types/index.ts @@ -0,0 +1,16 @@ +export * from "./ProviderKey"; +export * from "./TokenStatus"; +export * from "./PatchOp"; +export * from "./Device"; +export * from "./Tracking"; +export * from "./UserToken"; +export * from "./GetUserTokenResponse"; +export * from "./PutUserTokensOpts"; +export * from "./PutUserTokenOpts"; +export * from "./PatchUserTokenOpts"; +export * from "./PatchOperation"; +export * from "./GetUserTokenOpts"; +export * from "./GetUserTokensOpts"; +export * from "./DeleteUserTokenOpts"; +export * from "./ExpiryDate"; +export * from "./GetAllTokensResponse"; diff --git a/src/api/resources/translations/client/Client.ts b/src/api/resources/translations/client/Client.ts new file mode 100644 index 0000000..cc24604 --- /dev/null +++ b/src/api/resources/translations/client/Client.ts @@ -0,0 +1,146 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace Translations { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } +} + +export class Translations { + constructor(protected readonly _options: Translations.Options) {} + + /** + * Get translations by locale + * @throws {@link Courier.NotFoundError} + */ + public async get(domain: string, locale: string, requestOptions?: Translations.RequestOptions): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/translations/${domain}/${locale}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as string; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Courier.NotFoundError(_response.error.body as Courier.NotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Update a translation + * @throws {@link Courier.NotFoundError} + */ + public async update( + domain: string, + locale: string, + request: string, + requestOptions?: Translations.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/translations/${domain}/${locale}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Courier.NotFoundError(_response.error.body as Courier.NotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/translations/client/index.ts b/src/api/resources/translations/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/translations/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/translations/index.ts b/src/api/resources/translations/index.ts new file mode 100644 index 0000000..5ec7692 --- /dev/null +++ b/src/api/resources/translations/index.ts @@ -0,0 +1 @@ +export * from "./client"; diff --git a/src/api/resources/userPreferences/client/Client.ts b/src/api/resources/userPreferences/client/Client.ts new file mode 100644 index 0000000..9761b0c --- /dev/null +++ b/src/api/resources/userPreferences/client/Client.ts @@ -0,0 +1,205 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as Courier from "../../.."; +import urlJoin from "url-join"; +import * as errors from "../../../../errors"; + +export declare namespace UserPreferences { + interface Options { + environment?: core.Supplier; + authorizationToken: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + } +} + +export class UserPreferences { + constructor(protected readonly _options: UserPreferences.Options) {} + + /** + * Fetch all user preferences. + * @throws {@link Courier.BadRequestError} + */ + public async getPreferences( + userId: string, + requestOptions?: UserPreferences.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/preferences` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.UserPreferences; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Fetch user preferences for a specific subscription topic. + * @throws {@link Courier.NotFoundError} + */ + public async getSubscriptionTopic( + userId: string, + topicId: string, + requestOptions?: UserPreferences.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/preferences/${topicId}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.TopicPreference; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Courier.NotFoundError(_response.error.body as Courier.NotFound); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * Fetch user preferences for a specific subscription topic. + * @throws {@link Courier.BadRequestError} + */ + public async updateSubscriptionTopic( + userId: string, + topicId: string, + request: Courier.UpdateSubscriptionTopicRequest, + requestOptions?: UserPreferences.RequestOptions + ): Promise { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.CourierEnvironment.Production, + `/users/${userId}/preferences/${topicId}` + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@trycourier/courier", + "X-Fern-SDK-Version": "v6.0.0", + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + }); + if (_response.ok) { + return _response.body as Courier.UpdateSubscriptionTopicResponse; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Courier.BadRequestError(_response.error.body as Courier.BadRequest); + default: + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.CourierError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.CourierTimeoutError(); + case "unknown": + throw new errors.CourierError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader() { + const bearer = (await core.Supplier.get(this._options.authorizationToken)) ?? process.env["COURIER_AUTH_TOKEN"]; + if (bearer == null) { + throw new errors.CourierError({ + message: "Please specify COURIER_AUTH_TOKEN when instantiating the client.", + }); + } + + return `Bearer ${bearer}`; + } +} diff --git a/src/api/resources/userPreferences/client/index.ts b/src/api/resources/userPreferences/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/userPreferences/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/userPreferences/index.ts b/src/api/resources/userPreferences/index.ts new file mode 100644 index 0000000..c9240f8 --- /dev/null +++ b/src/api/resources/userPreferences/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/src/api/resources/userPreferences/types/TopicPreference.ts b/src/api/resources/userPreferences/types/TopicPreference.ts new file mode 100644 index 0000000..d65148a --- /dev/null +++ b/src/api/resources/userPreferences/types/TopicPreference.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface TopicPreference { + /** Should contain unique items. */ + custom_routing?: Courier.ChannelClassification[]; + default_status: Courier.PreferenceStatus; + has_custom_routing?: boolean; + status: Courier.PreferenceStatus; + topic_id: string; + topic_name: string; +} diff --git a/src/api/resources/userPreferences/types/UpdateSubscriptionTopicRequest.ts b/src/api/resources/userPreferences/types/UpdateSubscriptionTopicRequest.ts new file mode 100644 index 0000000..9134552 --- /dev/null +++ b/src/api/resources/userPreferences/types/UpdateSubscriptionTopicRequest.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface UpdateSubscriptionTopicRequest { + status?: Courier.PreferenceStatus; + /** Should contain unique items. */ + custom_routing?: Courier.ChannelClassification[]; + default_status: Courier.PreferenceStatus; + has_custom_routing?: boolean; +} diff --git a/src/api/resources/userPreferences/types/UpdateSubscriptionTopicResponse.ts b/src/api/resources/userPreferences/types/UpdateSubscriptionTopicResponse.ts new file mode 100644 index 0000000..b8d09a2 --- /dev/null +++ b/src/api/resources/userPreferences/types/UpdateSubscriptionTopicResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface UpdateSubscriptionTopicResponse { + message: string; +} diff --git a/src/api/resources/userPreferences/types/UserPreferences.ts b/src/api/resources/userPreferences/types/UserPreferences.ts new file mode 100644 index 0000000..2db920f --- /dev/null +++ b/src/api/resources/userPreferences/types/UserPreferences.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Courier from "../../.."; + +export interface UserPreferences { + paging: Courier.Paging; + /** The Preferences associated with the user_id. */ + items: Courier.TopicPreference[]; +} diff --git a/src/api/resources/userPreferences/types/index.ts b/src/api/resources/userPreferences/types/index.ts new file mode 100644 index 0000000..cebd0c1 --- /dev/null +++ b/src/api/resources/userPreferences/types/index.ts @@ -0,0 +1,4 @@ +export * from "./UserPreferences"; +export * from "./TopicPreference"; +export * from "./UpdateSubscriptionTopicRequest"; +export * from "./UpdateSubscriptionTopicResponse"; diff --git a/src/api/types/SendMessageResponse.ts b/src/api/types/SendMessageResponse.ts new file mode 100644 index 0000000..8644374 --- /dev/null +++ b/src/api/types/SendMessageResponse.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface SendMessageResponse { + /** + * A successful call to `POST /send` returns a `202` status code along with a `requestId` in the response body. + * + * For send requests that have a single recipient, the `requestId` is assigned to the derived message as its message_id. Therefore the `requestId` can be supplied to the Message's API for single recipient messages. + * + * For send requests that have multiple recipients (accounts, audiences, lists, etc.), Courier assigns a unique id to each derived message as its `message_id`. Therefore the `requestId` cannot be supplied to the Message's API for single-recipient messages. + * + */ + requestId: string; +} diff --git a/src/api/types/index.ts b/src/api/types/index.ts new file mode 100644 index 0000000..a28526a --- /dev/null +++ b/src/api/types/index.ts @@ -0,0 +1 @@ +export * from "./SendMessageResponse"; diff --git a/src/audiences/index.ts b/src/audiences/index.ts deleted file mode 100644 index c8c100e..0000000 --- a/src/audiences/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import * as AudienceTypes from "./types"; - -const deleteAudience = (options: ICourierClientConfiguration) => async ( - audienceId: string -): Promise => { - await options.httpClient.delete(`/audiences/${audienceId}`); -}; - -const getAudience = (options: ICourierClientConfiguration) => { - return async (audienceId: string): Promise => { - const response = await options.httpClient.get<{ - audience: AudienceTypes.IAudience; - }>(`/audiences/${audienceId}`); - return response.data.audience; - }; -}; - -const listAudiences = (options: ICourierClientConfiguration) => { - return async (params?: { - cursor: string; - }): Promise => { - const response = await options.httpClient.get< - AudienceTypes.IAudienceListResponse>( - "/audiences", - params - ); - return response.data; - }; -}; - -const listMembers = (options: ICourierClientConfiguration) => { - return async ( - audienceId: string, - params?: { - cursor: string; - } - ): Promise => { - const response = await options.httpClient.get< - AudienceTypes.IAudienceMemberListResponse - >( - `/audiences/${audienceId}/members`, - params); - return response.data; - }; -}; - -const putAudience = (options: ICourierClientConfiguration) => { - return async ( - audience: Omit - ): Promise => { - const response = await options.httpClient.put<{ - audience: AudienceTypes.IAudience; - }>(`/audiences/${audience.id}`, audience); - return response.data.audience; - }; -}; - -export const audiences = (options: ICourierClientConfiguration) => ({ - delete: deleteAudience(options), - get: getAudience(options), - listAudiences: listAudiences(options), - listMembers: listMembers(options), - put: putAudience(options) -}); diff --git a/src/audiences/types.ts b/src/audiences/types.ts deleted file mode 100644 index 529aa5b..0000000 --- a/src/audiences/types.ts +++ /dev/null @@ -1,88 +0,0 @@ -export type ComparisonOperator = - | "EQ" - | "GT" - | "GTE" - | "INCLUDES" - | "LT" - | "LTE" - | "NEQ" - | "OMIT"; - -export type LogicalOperator = "AND" | "OR"; - -export type Operator = ComparisonOperator | LogicalOperator; - -type Without = { [P in Exclude]?: never }; -type XOR = T | U extends object - ? (Without & U) | (Without & T) - : T | U; - -interface IBaseFilterConfig { - operator: Operator; -} - -interface ISingleFilterConfig extends IBaseFilterConfig { - path: string; - value: string; -} - -interface INestedFilterConfig extends IBaseFilterConfig { - rules: FilterConfig[]; -} - -export type FilterConfig = XOR; - -export interface IAudience { - created_at: string; - description?: string; - id: string; - name?: string; - filter: FilterConfig; - updated_at: string; -} - -export interface IAudienceMember { - added_at: string; - audience_id: string; - audience_version: number; - member_id: string; - reason: string; -} - -export interface IAudienceListResponse { - items: IAudience[]; - paging: { - cursor: string; - more: boolean; - }; -} - -export interface IAudienceMemberGetResponse { - audienceMember: IAudienceMember; -} - -export interface IAudienceMemberListResponse { - items: IAudienceMember[]; - paging: { - cursor: string; - more: boolean; - }; -} - -export interface IAudiencePutResponse { - audience: IAudience; -} - -export interface ICourierClientAudiences { - delete: (id: string) => Promise; - get: (id: string) => Promise; - listAudiences: (params?: { - cursor: string; - }) => Promise; - listMembers: (id: string, params?: { - cursor: string; - }) => Promise; - put: ( - audience: Omit - ) => Promise; -} diff --git a/src/audit-events/index.ts b/src/audit-events/index.ts deleted file mode 100644 index 2634a7b..0000000 --- a/src/audit-events/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - IAuditEvent, - ICourierGetAuditEventParams, - ICourierListAuditEventsParams, - ICourierListAuditEventsResponse -} from "./types"; - -const list = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierListAuditEventsParams - ): Promise => { - const res = await options.httpClient.get( - `/audit-events`, - { - params: { - cursor: params.cursor - } - } - ); - return res.data; - }; -}; - -const get = (options: ICourierClientConfiguration) => { - return async (params: ICourierGetAuditEventParams): Promise => { - const res = await options.httpClient.get( - `/audit-events/${params.auditEventId}` - ); - return res.data; - }; -}; - -export const auditEvents = (options: ICourierClientConfiguration) => { - return { - get: get(options), - list: list(options) - }; -}; diff --git a/src/audit-events/types.ts b/src/audit-events/types.ts deleted file mode 100644 index 49faed2..0000000 --- a/src/audit-events/types.ts +++ /dev/null @@ -1,30 +0,0 @@ -export interface ICourierListAuditEventsParams { - cursor?: string; -} - -export interface ICourierGetAuditEventParams { - auditEventId: string; -} - -export interface ICourierListAuditEventsResponse { - paging: { - cursor?: string; - more: boolean; - }; - results: IAuditEvent[]; -} - -export interface IAuditEvent { - actor?: { - id?: string; - email?: string; - }; - target?: { - id?: string; - email?: string; - }; - auditEventId: string; - source: string; - timestamp: string; - type: string; -} diff --git a/src/automations/index.ts b/src/automations/index.ts deleted file mode 100644 index b0dd11e..0000000 --- a/src/automations/index.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - ICourierAutomationAdHocInvokeParams, - ICourierAutomationConfig, - ICourierAutomationInvokeResponse, - ICourierAutomationInvokeTemplateParams, - ICourierClientAutomations -} from "./types"; - -const invokeAdHocAutomation = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierAutomationAdHocInvokeParams, - config?: ICourierAutomationConfig - ): Promise => { - const res = await options.httpClient.post( - "/automations/invoke", - { - automation: params.automation, - brand: params.brand, - data: params.data, - profile: params.profile, - recipient: params.recipient, - template: params.template - }, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - - return res.data; - }; -}; - -const invokeAutomationTemplate = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierAutomationInvokeTemplateParams, - config?: ICourierAutomationConfig - ): Promise => { - const res = await options.httpClient.post( - `/automations/${params.templateId}/invoke`, - { - brand: params.brand, - data: params.data, - profile: params.profile, - recipient: params.recipient, - template: params.template - }, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - - return res.data; - }; -}; - -export const automations = ( - options: ICourierClientConfiguration -): ICourierClientAutomations => { - return { - invokeAdHocAutomation: invokeAdHocAutomation(options), - invokeAutomationTemplate: invokeAutomationTemplate(options) - }; -}; diff --git a/src/automations/types.ts b/src/automations/types.ts deleted file mode 100644 index a1536d1..0000000 --- a/src/automations/types.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { Message } from "../send/types"; - -export type AutomationStepAction = - | "cancel" - | "delay" - | "invoke" - | "send" - | "send-list" - | "update-profile"; - -export type MergeAlgorithm = "replace" | "none" | "overwrite" | "soft-merge"; - -export interface IAutomationRunContext { - brand?: string; - data?: any; - profile?: any; - template?: string; - recipient?: string; -} -export interface IAutomationStep { - action: AutomationStepAction; - if?: string; - ref?: string; -} - -export interface IAutomationCancelStep extends IAutomationStep { - action: "cancel"; - cancelation_token?: string; -} - -export interface IAutomationDelayStep extends IAutomationStep { - action: "delay"; - duration?: string; - until?: string; -} - -export interface IAutomationInvokeStep extends IAutomationStep { - action: "invoke"; - context?: IAutomationRunContext; - template: string; - if?: string; - ref?: string; -} - -export interface IAutomationSendStep extends IAutomationStep { - action: "send"; - brand?: string; - data?: Record; - override?: Record; - profile?: object; - recipient?: string; - template?: string; -} - -export interface IAutomationV2SendStep extends IAutomationStep { - action: "send"; - message: Message; -} - -export interface IAutomationSendListStep extends IAutomationStep { - action: "send-list"; - brand?: string; - data?: Record; - list: string; - override?: Record; - template?: string; -} - -export interface IAutomationUpdateProfileStep extends IAutomationStep { - action: "update-profile"; - recipient_id: string; - profile: object; - merge: MergeAlgorithm; -} - -export type AutomationStep = - | IAutomationCancelStep - | IAutomationDelayStep - | IAutomationInvokeStep - | IAutomationSendStep - | IAutomationV2SendStep - | IAutomationSendListStep - | IAutomationUpdateProfileStep; - -export interface IAutomation { - cancelation_token?: string; - steps: AutomationStep[]; -} - -export interface ICourierAutomationInvokeParams { - brand?: string; - data?: Record; - profile?: object; - recipient?: string; - template?: string; -} - -export interface ICourierAutomationAdHocInvokeParams - extends ICourierAutomationInvokeParams { - automation: IAutomation; -} - -export interface ICourierAutomationConfig { - idempotencyKey?: string; - idempotencyExpiry?: number; -} - -export interface ICourierAutomationInvokeTemplateParams - extends ICourierAutomationInvokeParams { - templateId: string; -} - -export interface ICourierAutomationInvokeResponse { - runId: string; -} - -export interface ICourierClientAutomations { - invokeAdHocAutomation: ( - params: ICourierAutomationAdHocInvokeParams, - config?: ICourierAutomationConfig - ) => Promise; - invokeAutomationTemplate: ( - params: ICourierAutomationInvokeTemplateParams, - config?: ICourierAutomationConfig - ) => Promise; -} diff --git a/src/brands.ts b/src/brands.ts deleted file mode 100644 index b9a2f6e..0000000 --- a/src/brands.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - ICourierBrand, - ICourierBrandGetAllResponse, - ICourierBrandParameters, - ICourierBrandPostConfig, - ICourierBrandPutParameters, - ICourierClientConfiguration -} from "./types"; - -export const getBrands = (options: ICourierClientConfiguration) => { - return async (params?: { - cursor: string; - }): Promise => { - const res = await options.httpClient.get( - `/brands`, - params - ); - return res.data; - }; -}; - -export const getBrand = (options: ICourierClientConfiguration) => { - return async (brandId: string): Promise => { - const res = await options.httpClient.get( - `/brands/${brandId}` - ); - return res.data; - }; -}; - -export const createBrand = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierBrandParameters, - config?: ICourierBrandPostConfig - ): Promise => { - const res = await options.httpClient.post( - `/brands`, - params, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - return res.data; - }; -}; - -export const replaceBrand = (options: ICourierClientConfiguration) => { - return async (params: ICourierBrandPutParameters): Promise => { - const { id, ...rest } = params; - const res = await options.httpClient.put( - `/brands/${id}`, - rest - ); - return res.data; - }; -}; - -export const deleteBrand = (options: ICourierClientConfiguration) => { - return async (brandId: string): Promise => { - await options.httpClient.delete(`/brands/${brandId}`); - }; -}; diff --git a/src/bulk/index.ts b/src/bulk/index.ts deleted file mode 100644 index 63660ec..0000000 --- a/src/bulk/index.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - ICourierBulkConfig, - ICourierBulkCreateJobParams, - ICourierBulkCreateJobResponse, - ICourierBulkGetJobParams, - ICourierBulkGetJobResponse, - ICourierBulkGetJobUsersParams, - ICourierBulkGetJobUsersResponse, - ICourierBulkIngestUsersParams, - ICourierBulkIngestUsersResponse, - ICourierBulkRunJobParams, - ICourierClientBulk -} from "./types"; - -const createJob = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierBulkCreateJobParams, - config?: ICourierBulkConfig - ): Promise => { - const res = await options.httpClient.post( - "/bulk", - { - message: params.message - }, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - - return res.data; - }; -}; - -const ingestUsers = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierBulkIngestUsersParams, - config?: ICourierBulkConfig - ): Promise => { - const res = await options.httpClient.post( - `/bulk/${params.jobId}`, - { - users: params.users - }, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - - return res.data; - }; -}; - -const runJob = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierBulkRunJobParams, - config?: ICourierBulkConfig - ): Promise => { - await options.httpClient.post( - `/bulk/${params.jobId}/run`, - {}, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - }; -}; - -const getJob = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierBulkGetJobParams - ): Promise => { - const res = await options.httpClient.get( - `/bulk/${params.jobId}` - ); - return res.data; - }; -}; - -const getJobUsers = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierBulkGetJobUsersParams - ): Promise => { - const res = await options.httpClient.get( - `/bulk/${params.jobId}/users`, - { - params: { - cursor: params.cursor - } - } - ); - return res.data; - }; -}; - -export const bulk = ( - options: ICourierClientConfiguration -): ICourierClientBulk => { - return { - createJob: createJob(options), - getJob: getJob(options), - getJobUsers: getJobUsers(options), - ingestUsers: ingestUsers(options), - runJob: runJob(options) - }; -}; diff --git a/src/bulk/types.ts b/src/bulk/types.ts deleted file mode 100644 index ffa4b69..0000000 --- a/src/bulk/types.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { IRecipientPreferences } from "../preferences/types"; -import { Message, UserRecipient } from "../send/types"; -interface IInboundBulkMessageApiV1 { - brand?: string; - data?: object; - event: string; - locale?: string; - override?: object; -} - -type InboundBulkMessageApiV2 = Omit; - -export interface IInboundBulkMessage extends IInboundBulkMessageApiV1 { - message?: InboundBulkMessageApiV2; -} - -export type InboundBulkMessage = IInboundBulkMessage; - -export interface ICourierBulkConfig { - idempotencyKey?: string; - idempotencyExpiry?: number; -} - -export interface ICourierBulkCreateJobParams { - message: IInboundBulkMessage; -} - -export interface ICourierBulkCreateJobResponse { - jobId: string; -} - -export interface IInboundBulkMessageUser { - preferences?: IRecipientPreferences; - profile?: object; - recipient?: string; - data?: object; - to?: UserRecipient; -} - -export type InboundBulkMessageUser = IInboundBulkMessageUser; - -export interface ICourierBulkIngestUsersParams { - jobId: string; - users: InboundBulkMessageUser[]; -} - -export interface ICourierBulkIngestError { - user: any; - error: any; -} - -export interface ICourierBulkIngestUsersResponse { - total: number; - errors?: ICourierBulkIngestError[]; -} - -export interface ICourierBulkRunJobParams { - jobId: string; -} - -export interface ICourierBulkGetJobParams { - jobId: string; -} - -export type BulkJobStatus = "CREATED" | "PROCESSING" | "COMPLETED" | "ERROR"; -export type BulkJobUserStatus = "PENDING" | "ENQUEUED" | "ERROR"; - -export interface ICourierBulkGetJobResponse { - job: { - definition: IInboundBulkMessage; - enqueued: number; - failures: number; - received: number; - status: BulkJobStatus; - }; -} - -export interface ICourierBulkGetJobUsersParams { - jobId: string; - cursor?: string; -} - -export interface ICourierBulkMessageUserResponse - extends InboundBulkMessageUser { - status: BulkJobUserStatus; - messageId?: string; -} - -export interface ICourierBulkGetJobUsersResponse { - items: ICourierBulkMessageUserResponse[]; - paging: { - cursor?: string; - more: boolean; - }; -} - -export interface ICourierClientBulk { - createJob: ( - params: ICourierBulkCreateJobParams, - config?: ICourierBulkConfig - ) => Promise; - ingestUsers: ( - params: ICourierBulkIngestUsersParams, - config?: ICourierBulkConfig - ) => Promise; - runJob: ( - params: ICourierBulkRunJobParams, - config?: ICourierBulkConfig - ) => Promise; - getJob: ( - params: ICourierBulkGetJobParams - ) => Promise; - getJobUsers: ( - params: ICourierBulkGetJobUsersParams - ) => Promise; -} diff --git a/src/client.ts b/src/client.ts deleted file mode 100644 index 58355c0..0000000 --- a/src/client.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { audiences } from "./audiences"; -import { auditEvents } from "./audit-events"; -import { automations } from "./automations"; -import { - createBrand, - deleteBrand, - getBrand, - getBrands, - replaceBrand -} from "./brands"; -import { bulk } from "./bulk"; -import { postIssueToken } from "./issue-token"; -import { lists } from "./lists"; -import { notifications } from "./notifications"; -import { preferences } from "./preferences"; -import { - addRecipientToLists, - deleteProfile, - getProfile, - getRecipientSubscriptions, - mergeProfile, - removeRecipientFromAllLists, - replaceProfile -} from "./profile"; -import { send } from "./send"; -import { tenants } from "./tenants"; -import { tokenManagement } from "./token-management"; -import { users } from "./users"; - -import { - ICourierClient, - ICourierClientConfiguration, - ICourierMessageCancelResponse, - ICourierMessageGetHistoryResponse, - ICourierMessageGetOutputResponse, - ICourierMessageGetResponse, - ICourierMessagesGetParameters, - ICourierMessagesGetResponse -} from "./types"; - -const cancelMessage = (options: ICourierClientConfiguration) => { - return async (messageId: string): Promise => { - const res = await options.httpClient.post( - `/messages/${messageId}/cancel` - ); - - return res.data; - }; -}; - -const getMessage = (options: ICourierClientConfiguration) => { - return async (messageId: string): Promise => { - const res = await options.httpClient.get( - `/messages/${messageId}` - ); - return res.data; - }; -}; - -const getMessageHistory = (options: ICourierClientConfiguration) => { - return async ( - messageId: string - ): Promise => { - const res = await options.httpClient.get( - `/messages/${messageId}/history` - ); - return res.data; - }; -}; - -const getMessageOutput = (options: ICourierClientConfiguration) => { - return async ( - messageId: string - ): Promise => { - const res = await options.httpClient.get( - `/messages/${messageId}/output` - ); - return res.data; - }; -}; - -const getMessages = (options: ICourierClientConfiguration) => { - return async ( - params?: ICourierMessagesGetParameters - ): Promise => { - const res = await options.httpClient.get( - "/messages", - { - params: { - cursor: params?.cursor, - event: params?.eventId, - list: params?.listId, - messageId: params?.messageId, - notification: params?.notificationId, - recipient: params?.recipientId, - status: params?.status, - tags: params?.tags, - traceId: params?.traceId - } - } - ); - return res.data; - }; -}; - -export const client = ( - options: ICourierClientConfiguration -): ICourierClient => { - return { - addRecipientToLists: addRecipientToLists(options), - audiences: audiences(options), - auditEvents: auditEvents(options), - automations: automations(options), - bulk: bulk(options), - cancelMessage: cancelMessage(options), - createBrand: createBrand(options), - deleteBrand: deleteBrand(options), - deleteProfile: deleteProfile(options), - getBrand: getBrand(options), - getBrands: getBrands(options), - getMessage: getMessage(options), - getMessageHistory: getMessageHistory(options), - getMessageOutput: getMessageOutput(options), - getMessages: getMessages(options), - getProfile: getProfile(options), - getRecipientSubscriptions: getRecipientSubscriptions(options), - issueToken: postIssueToken(options), - lists: lists(options), - mergeProfile: mergeProfile(options), - notifications: notifications(options), - preferences: preferences(options), - removeRecipientFromAllLists: removeRecipientFromAllLists(options), - replaceBrand: replaceBrand(options), - replaceProfile: replaceProfile(options), - send: send(options), - tenants: tenants(options), - tokenManagement: tokenManagement(options), - users: users(options) - }; -}; diff --git a/src/core/auth/BasicAuth.ts b/src/core/auth/BasicAuth.ts new file mode 100644 index 0000000..146df21 --- /dev/null +++ b/src/core/auth/BasicAuth.ts @@ -0,0 +1,31 @@ +import { Base64 } from "js-base64"; + +export interface BasicAuth { + username: string; + password: string; +} + +const BASIC_AUTH_HEADER_PREFIX = /^Basic /i; + +export const BasicAuth = { + toAuthorizationHeader: (basicAuth: BasicAuth | undefined): string | undefined => { + if (basicAuth == null) { + return undefined; + } + const token = Base64.encode(`${basicAuth.username}:${basicAuth.password}`); + return `Basic ${token}`; + }, + fromAuthorizationHeader: (header: string): BasicAuth => { + const credentials = header.replace(BASIC_AUTH_HEADER_PREFIX, ""); + const decoded = Base64.decode(credentials); + const [username, password] = decoded.split(":", 2); + + if (username == null || password == null) { + throw new Error("Invalid basic auth"); + } + return { + username, + password, + }; + }, +}; diff --git a/src/core/auth/BearerToken.ts b/src/core/auth/BearerToken.ts new file mode 100644 index 0000000..fe987fc --- /dev/null +++ b/src/core/auth/BearerToken.ts @@ -0,0 +1,15 @@ +export type BearerToken = string; + +const BEARER_AUTH_HEADER_PREFIX = /^Bearer /i; + +export const BearerToken = { + toAuthorizationHeader: (token: BearerToken | undefined): string | undefined => { + if (token == null) { + return undefined; + } + return `Bearer ${token}`; + }, + fromAuthorizationHeader: (header: string): BearerToken => { + return header.replace(BEARER_AUTH_HEADER_PREFIX, "").trim() as BearerToken; + }, +}; diff --git a/src/core/auth/index.ts b/src/core/auth/index.ts new file mode 100644 index 0000000..ee293b3 --- /dev/null +++ b/src/core/auth/index.ts @@ -0,0 +1,2 @@ +export { BasicAuth } from "./BasicAuth"; +export { BearerToken } from "./BearerToken"; diff --git a/src/core/fetcher/APIResponse.ts b/src/core/fetcher/APIResponse.ts new file mode 100644 index 0000000..ea838f3 --- /dev/null +++ b/src/core/fetcher/APIResponse.ts @@ -0,0 +1,11 @@ +export type APIResponse = SuccessfulResponse | FailedResponse; + +export interface SuccessfulResponse { + ok: true; + body: T; +} + +export interface FailedResponse { + ok: false; + error: T; +} diff --git a/src/core/fetcher/Fetcher.ts b/src/core/fetcher/Fetcher.ts new file mode 100644 index 0000000..96c7004 --- /dev/null +++ b/src/core/fetcher/Fetcher.ts @@ -0,0 +1,159 @@ +import axios, { AxiosAdapter, AxiosError, AxiosResponse } from "axios"; +import qs from "qs"; +import { APIResponse } from "./APIResponse"; + +export type FetchFunction = (args: Fetcher.Args) => Promise>; + +export declare namespace Fetcher { + export interface Args { + url: string; + method: string; + contentType?: string; + headers?: Record; + queryParameters?: Record; + body?: unknown; + timeoutMs?: number; + maxRetries?: number; + withCredentials?: boolean; + responseType?: "json" | "blob"; + adapter?: AxiosAdapter; + onUploadProgress?: (event: ProgressEvent) => void; + } + + export type Error = FailedStatusCodeError | NonJsonError | TimeoutError | UnknownError; + + export interface FailedStatusCodeError { + reason: "status-code"; + statusCode: number; + body: unknown; + } + + export interface NonJsonError { + reason: "non-json"; + statusCode: number; + rawBody: string; + } + + export interface TimeoutError { + reason: "timeout"; + } + + export interface UnknownError { + reason: "unknown"; + errorMessage: string; + } +} + +const INITIAL_RETRY_DELAY = 1; +const MAX_RETRY_DELAY = 60; +const DEFAULT_MAX_RETRIES = 2; + +async function fetcherImpl(args: Fetcher.Args): Promise> { + const headers: Record = {}; + if (args.body !== undefined && args.contentType != null) { + headers["Content-Type"] = args.contentType; + } + + if (args.headers != null) { + for (const [key, value] of Object.entries(args.headers)) { + if (value != null) { + headers[key] = value; + } + } + } + + const makeRequest = async (): Promise => + await axios({ + url: args.url, + params: args.queryParameters, + paramsSerializer: (params) => { + return qs.stringify(params, { arrayFormat: "repeat" }); + }, + method: args.method, + headers, + data: args.body, + validateStatus: () => true, + transformResponse: (response) => response, + timeout: args.timeoutMs, + transitional: { + clarifyTimeoutError: true, + }, + withCredentials: args.withCredentials, + adapter: args.adapter, + onUploadProgress: args.onUploadProgress, + maxBodyLength: Infinity, + maxContentLength: Infinity, + responseType: args.responseType ?? "json", + }); + + try { + let response = await makeRequest(); + + for (let i = 0; i < (args.maxRetries ?? DEFAULT_MAX_RETRIES); ++i) { + if ( + response.status === 408 || + response.status === 409 || + response.status === 429 || + response.status >= 500 + ) { + const delay = Math.min(INITIAL_RETRY_DELAY * Math.pow(i, 2), MAX_RETRY_DELAY); + response = await new Promise((resolve) => setTimeout(resolve, delay)); + } else { + break; + } + } + + let body: unknown; + if (args.responseType === "blob") { + body = response.data; + } else if (response.data != null && response.data.length > 0) { + try { + body = JSON.parse(response.data) ?? undefined; + } catch { + return { + ok: false, + error: { + reason: "non-json", + statusCode: response.status, + rawBody: response.data, + }, + }; + } + } + + if (response.status >= 200 && response.status < 400) { + return { + ok: true, + body: body as R, + }; + } else { + return { + ok: false, + error: { + reason: "status-code", + statusCode: response.status, + body, + }, + }; + } + } catch (error) { + if ((error as AxiosError).code === "ETIMEDOUT") { + return { + ok: false, + error: { + reason: "timeout", + }, + }; + } + + return { + ok: false, + error: { + reason: "unknown", + errorMessage: (error as AxiosError).message, + }, + }; + } +} + +export const fetcher: FetchFunction = fetcherImpl; diff --git a/src/core/fetcher/Supplier.ts b/src/core/fetcher/Supplier.ts new file mode 100644 index 0000000..867c931 --- /dev/null +++ b/src/core/fetcher/Supplier.ts @@ -0,0 +1,11 @@ +export type Supplier = T | Promise | (() => T | Promise); + +export const Supplier = { + get: async (supplier: Supplier): Promise => { + if (typeof supplier === "function") { + return (supplier as () => T)(); + } else { + return supplier; + } + }, +}; diff --git a/src/core/fetcher/index.ts b/src/core/fetcher/index.ts new file mode 100644 index 0000000..6becab2 --- /dev/null +++ b/src/core/fetcher/index.ts @@ -0,0 +1,4 @@ +export type { APIResponse } from "./APIResponse"; +export { fetcher } from "./Fetcher"; +export type { Fetcher, FetchFunction } from "./Fetcher"; +export { Supplier } from "./Supplier"; diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 0000000..994e8ef --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,2 @@ +export * from "./fetcher"; +export * from "./auth"; diff --git a/src/environments.ts b/src/environments.ts new file mode 100644 index 0000000..384e84c --- /dev/null +++ b/src/environments.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export const CourierEnvironment = { + Production: "https://api.courier.com", +} as const; + +export type CourierEnvironment = typeof CourierEnvironment.Production; diff --git a/src/errors/CourierError.ts b/src/errors/CourierError.ts new file mode 100644 index 0000000..680cd1e --- /dev/null +++ b/src/errors/CourierError.ts @@ -0,0 +1,45 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export class CourierError extends Error { + readonly statusCode?: number; + readonly body?: unknown; + + constructor({ message, statusCode, body }: { message?: string; statusCode?: number; body?: unknown }) { + super(buildMessage({ message, statusCode, body })); + Object.setPrototypeOf(this, CourierError.prototype); + if (statusCode != null) { + this.statusCode = statusCode; + } + + if (body !== undefined) { + this.body = body; + } + } +} + +function buildMessage({ + message, + statusCode, + body, +}: { + message: string | undefined; + statusCode: number | undefined; + body: unknown | undefined; +}): string { + let lines: string[] = []; + if (message != null) { + lines.push(message); + } + + if (statusCode != null) { + lines.push(`Status code: ${statusCode.toString()}`); + } + + if (body != null) { + lines.push(`Body: ${JSON.stringify(body, undefined, 2)}`); + } + + return lines.join("\n"); +} diff --git a/src/errors/CourierTimeoutError.ts b/src/errors/CourierTimeoutError.ts new file mode 100644 index 0000000..295eda6 --- /dev/null +++ b/src/errors/CourierTimeoutError.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export class CourierTimeoutError extends Error { + constructor() { + super("Timeout"); + Object.setPrototypeOf(this, CourierTimeoutError.prototype); + } +} diff --git a/src/errors/index.ts b/src/errors/index.ts new file mode 100644 index 0000000..6efd306 --- /dev/null +++ b/src/errors/index.ts @@ -0,0 +1,2 @@ +export { CourierError } from "./CourierError"; +export { CourierTimeoutError } from "./CourierTimeoutError"; diff --git a/src/http-client.ts b/src/http-client.ts deleted file mode 100644 index 104306d..0000000 --- a/src/http-client.ts +++ /dev/null @@ -1,79 +0,0 @@ -import crossFetch from "cross-fetch"; - -import { HttpMethodClient, IHttpClient, IInitHttpClientOptions } from "./types"; - -const fetch = globalThis.fetch ?? crossFetch; - -export class CourierHttpClientError extends Error { - public response?: Response; - public data?: any; - - constructor( - message: string, - { response, data }: { response?: Response; data?: any } - ) { - super(message); - Object.setPrototypeOf(this, CourierHttpClientError.prototype); - - this.response = response; - this.data = data; - } -} - -export const initHttpClient = ({ - baseUrl, - version, - authorizationToken -}: IInitHttpClientOptions): IHttpClient => { - const createHttpMethodClient = (method: string): HttpMethodClient => { - return async (...[url, body, config]: Parameters) => { - const searchParams = String(new URLSearchParams(config?.params)); - const searchQueryString = searchParams && `?${searchParams}`; - const fullUrl = encodeURI(`${baseUrl ?? ""}${url}${searchQueryString}`); - const contentTypeHeader = - body == null ? null : { "Content-Type": "application/json" }; - const idempotencyKeyHeader = config?.idempotencyKey - ? { "Idempotency-Key": config.idempotencyKey } - : null; - const idempotencyExpiryHeader = - config?.idempotencyExpiry == null - ? null - : { "x-idempotency-expiration": String(config.idempotencyExpiry) }; - - const response = await fetch(fullUrl, { - body: body != null ? JSON.stringify(body) : undefined, - headers: { - Authorization: `Bearer ${authorizationToken}`, - "User-Agent": `courier-node/${version}`, - ...contentTypeHeader, - ...idempotencyKeyHeader, - ...idempotencyExpiryHeader - }, - method - }); - - const parseAsJson = - response.headers.get("content-length") !== "0" && - response.headers.get("content-type") === "application/json"; - - const data = await (parseAsJson ? response.json() : response.text()); - - if (!response.ok) { - throw new CourierHttpClientError( - data.message || "An unexpected error has occurred", - { response, data } - ); - } - - return { data } as { data: T }; - }; - }; - - return { - delete: createHttpMethodClient("DELETE"), - get: (url, config) => createHttpMethodClient("GET")(url, undefined, config), - patch: createHttpMethodClient("PATCH"), - post: createHttpMethodClient("POST"), - put: createHttpMethodClient("PUT") - }; -}; diff --git a/src/index.ts b/src/index.ts index fd765a4..685b9ee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,39 +1,4 @@ -import { client } from "./client"; -import { ICourierClientOptions } from "./types"; -export { ICourierClient } from "./types"; -import { initHttpClient } from "./http-client"; -export { CourierHttpClientError } from "./http-client"; - -// cannot be `import` as it's not under TS root dir -// tslint:disable-next-line:no-var-requires -const { version } = require("../package.json"); - -const DEFAULTS = { - BASE_URL: "https://api.courier.com" -}; - -const getEnvVariable = (name: string) => globalThis?.process?.env?.[name]; - -export const CourierClient = (options: ICourierClientOptions = {}) => { - const authorizationToken = - options.authorizationToken || getEnvVariable("COURIER_AUTH_TOKEN"); - - if (!authorizationToken) { - throw new Error("Courier Auth Token is required."); - } - - const baseUrl = - options.baseUrl || getEnvVariable("COURIER_BASE_URL") || DEFAULTS.BASE_URL; - - const httpClient = initHttpClient({ - authorizationToken, - baseUrl, - version - }); - - const courier = client({ - httpClient - }); - - return courier; -}; +export * as Courier from "./api"; +export { CourierClient } from "./Client"; +export { CourierEnvironment } from "./environments"; +export { CourierError, CourierTimeoutError } from "./errors"; diff --git a/src/issue-token/index.ts b/src/issue-token/index.ts deleted file mode 100644 index 12c1c9a..0000000 --- a/src/issue-token/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - ICourierAuthIssueTokenParameters, - ICourierAuthIssueTokenResponse -} from "./types"; - -export const postIssueToken = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierAuthIssueTokenParameters - ): Promise => { - const res = await options.httpClient.post( - `/auth/issue-token`, - { - expires_in: params.expiresIn, - scope: params.scope - } - ); - return res.data; - }; -}; diff --git a/src/issue-token/types.ts b/src/issue-token/types.ts deleted file mode 100644 index f0a071a..0000000 --- a/src/issue-token/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface ICourierAuthIssueTokenParameters { - scope: string; - expiresIn: string; -} - -export interface ICourierAuthIssueTokenResponse { - token?: string; -} - -export interface ICourierClientAuth { - postIssueToken: ( - scope: string, - expiresIn?: string - ) => Promise; -} diff --git a/src/lists/index.ts b/src/lists/index.ts deleted file mode 100644 index 1bdc5b5..0000000 --- a/src/lists/index.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { - ICourierClientConfiguration, - ICourierSendConfig, - ICourierSendListOrPatternParams, - ICourierSendResponse -} from "../types"; -import { - ICourierClientLists, - ICourierList, - ICourierListFindByRecipientIdParams, - ICourierListFindByRecipientIdResponse, - ICourierListGetAllParams, - ICourierListGetAllResponse, - ICourierListGetSubscriptionsParams, - ICourierListGetSubscriptionsResponse, - ICourierListPutParams, - ICourierPutSubscriptionsRecipient, - ICourierRecipientPreferences -} from "./types"; - -const list = (options: ICourierClientConfiguration) => { - return async ( - params?: ICourierListGetAllParams - ): Promise => { - const res = await options.httpClient.get( - `/lists`, - params - ); - return res.data; - }; -}; - -const get = (options: ICourierClientConfiguration) => { - return async (listId: string): Promise => { - const res = await options.httpClient.get(`/lists/${listId}`); - return res.data; - }; -}; - -const put = (options: ICourierClientConfiguration) => { - // tslint:disable-next-line: no-shadowed-variable - return async ( - listId: string, - params: ICourierListPutParams - ): Promise => { - await options.httpClient.put(`/lists/${listId}`, params); - }; -}; - -const deleteList = (options: ICourierClientConfiguration) => { - return async (listId: string): Promise => { - await options.httpClient.delete(`/lists/${listId}`); - }; -}; - -const restore = (options: ICourierClientConfiguration) => { - return async (listId: string): Promise => { - await options.httpClient.put(`/lists/${listId}/restore`); - }; -}; - -const getSubscriptions = (options: ICourierClientConfiguration) => { - return async ( - listId: string, - params?: ICourierListGetSubscriptionsParams - ): Promise => { - const res = await options.httpClient.get< - ICourierListGetSubscriptionsResponse - >(`/lists/${listId}/subscriptions`, params); - return res.data; - }; -}; - -const putSubscriptions = (options: ICourierClientConfiguration) => { - return async ( - listId: string, - recipients: ICourierPutSubscriptionsRecipient[] - ): Promise => { - await options.httpClient.put(`/lists/${listId}/subscriptions`, { - recipients - }); - }; -}; - -const postSubscriptions = (options: ICourierClientConfiguration) => { - return async ( - listId: string, - recipients: ICourierPutSubscriptionsRecipient[] - ): Promise => { - await options.httpClient.post(`/lists/${listId}/subscriptions`, { - recipients - }); - }; -}; - -const subscribe = (options: ICourierClientConfiguration) => { - return async ( - listId: string, - recipientId: string, - preferences?: ICourierRecipientPreferences - ): Promise => { - await options.httpClient.put( - `/lists/${listId}/subscriptions/${recipientId}`, - { - preferences - } - ); - }; -}; - -const unsubscribe = (options: ICourierClientConfiguration) => { - return async (listId: string, recipientId: string): Promise => { - await options.httpClient.delete( - `/lists/${listId}/subscriptions/${recipientId}` - ); - }; -}; - -const findByRecipientId = (options: ICourierClientConfiguration) => { - return async ( - recipientId: string, - params?: ICourierListFindByRecipientIdParams - ): Promise => { - const res = await options.httpClient.get< - ICourierListFindByRecipientIdResponse - >(`/profiles/${recipientId}/lists`, params); - return res.data; - }; -}; - -const send = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierSendListOrPatternParams, - config?: ICourierSendConfig - ): Promise => { - const res = await options.httpClient.post( - `/send/list`, - params, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - return res.data; - }; -}; - -export const lists = ( - options: ICourierClientConfiguration -): ICourierClientLists => { - return { - delete: deleteList(options), - findByRecipientId: findByRecipientId(options), - get: get(options), - getSubscriptions: getSubscriptions(options), - list: list(options), - postSubscriptions: postSubscriptions(options), - put: put(options), - putSubscriptions: putSubscriptions(options), - restore: restore(options), - send: send(options), - subscribe: subscribe(options), - unsubscribe: unsubscribe(options) - }; -}; diff --git a/src/lists/types.ts b/src/lists/types.ts deleted file mode 100644 index 1600a20..0000000 --- a/src/lists/types.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { - ICourierNotificationPreferences, - IRecipientPreferences -} from "../preferences/types"; -import { - ICourierPaging, - ICourierSendConfig, - ICourierSendListOrPatternParams, - ICourierSendResponse -} from "../types"; - -export interface ICourierList { - created?: number; - id: string; - name: string; - updated?: number; -} - -export interface ICourierRecipientSubscriptionsResponse { - paging: ICourierPaging; - results: ICourierList[]; -} - -export interface ICourierListPutParams { - name: string; - preferences?: { - notifications: IRecipientPreferences; - categories?: IRecipientPreferences; - }; -} - -export interface ICourierListGetAllParams { - cursor?: string; - pattern?: string; -} - -export interface ICourierListGetAllResponse { - paging: ICourierPaging; - items: ICourierList[]; -} - -export interface ICourierListGetSubscriptionsParams { - cursor?: string; -} - -export interface ICourierListRecipient { - recipientId: string; - created?: string; - preferences?: ICourierRecipientPreferences; -} - -export interface ICourierListGetSubscriptionsResponse { - paging: ICourierPaging; - items: ICourierListRecipient[]; -} - -export interface ICourierListFindByRecipientIdParams { - curser?: string; -} - -export interface ICourierListFindByRecipientIdResponse { - paging: ICourierPaging; - results: ICourierList[]; -} - -export interface ICourierRecipientPreferences { - categories?: ICourierNotificationPreferences; - notifications: ICourierNotificationPreferences; -} - -export interface ICourierPutSubscriptionsRecipient { - recipientId: string; - preferences?: ICourierRecipientPreferences; -} - -export interface ICourierClientLists { - delete: (listId: string) => Promise; - findByRecipientId: ( - recipientId: string, - params?: ICourierListFindByRecipientIdParams - ) => Promise; - get: (listId: string) => Promise; - getSubscriptions: ( - listId: string, - params?: ICourierListGetSubscriptionsParams - ) => Promise; - list: ( - params?: ICourierListGetAllParams - ) => Promise; - postSubscriptions: ( - listId: string, - recipients: ICourierPutSubscriptionsRecipient[] - ) => Promise; - put: (listId: string, params: ICourierListPutParams) => Promise; - putSubscriptions: ( - listId: string, - recipients: ICourierPutSubscriptionsRecipient[] - ) => Promise; - restore: (listId: string) => Promise; - send: ( - params: ICourierSendListOrPatternParams, - config?: ICourierSendConfig - ) => Promise; - subscribe: ( - listId: string, - recipientId: string, - preferences?: ICourierRecipientPreferences - ) => Promise; - unsubscribe: (listId: string, recipientId: string) => Promise; -} diff --git a/src/notifications/index.ts b/src/notifications/index.ts deleted file mode 100644 index a06b196..0000000 --- a/src/notifications/index.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - ICourierClientNotifications, - ICourierNotificationGetContentResponse, - ICourierNotificationGetSubmissionChecksResponse, - ICourierNotificationListParams, - ICourierNotificationListResponse, - ICourierNotificationPostDraftVariationsParams, - ICourierNotificationPostVariationsParams, - ICourierNotificationPutSubmissionChecksParams, - ICourierNotificationPutSubmissionChecksResponse -} from "./types"; - -const list = (options: ICourierClientConfiguration) => { - return async ( - params?: ICourierNotificationListParams - ): Promise => { - const res = await options.httpClient.get( - `/notifications`, - params - ); - - return res.data; - }; -}; - -const getContent = (options: ICourierClientConfiguration) => { - return async ( - id: string - ): Promise => { - const res = await options.httpClient.get< - ICourierNotificationGetContentResponse - >(`/notifications/${id}/content`); - - return res.data; - }; -}; - -const getDraftContent = (options: ICourierClientConfiguration) => { - return async ( - id: string - ): Promise => { - const res = await options.httpClient.get< - ICourierNotificationGetContentResponse - >(`/notifications/${id}/draft/content`); - - return res.data; - }; -}; - -const postVariations = (options: ICourierClientConfiguration) => { - return async ( - id: string, - params: ICourierNotificationPostVariationsParams - ): Promise => { - await options.httpClient.post( - `/notifications/${id}/variations`, - params - ); - }; -}; - -const postDraftVariations = (options: ICourierClientConfiguration) => { - return async ( - id: string, - params: ICourierNotificationPostDraftVariationsParams - ): Promise => { - await options.httpClient.post( - `/notifications/${id}/draft/variations`, - params - ); - }; -}; - -const getSubmissionChecks = (options: ICourierClientConfiguration) => { - return async ( - id: string, - submissionId: string - ): Promise => { - const res = await options.httpClient.get< - ICourierNotificationGetSubmissionChecksResponse - >(`/notifications/${id}/${submissionId}/checks`); - - return res.data; - }; -}; - -const putSubmissionChecks = (options: ICourierClientConfiguration) => { - return async ( - id: string, - submissionId: string, - params: ICourierNotificationPutSubmissionChecksParams - ): Promise => { - const res = await options.httpClient.put< - ICourierNotificationPutSubmissionChecksResponse - >(`/notifications/${id}/${submissionId}/checks`, params); - - return res.data; - }; -}; - -const cancelSubmission = (options: ICourierClientConfiguration) => { - return async (id: string, submissionId: string): Promise => { - await options.httpClient.delete( - `/notifications/${id}/${submissionId}/checks` - ); - }; -}; - -export const notifications = ( - options: ICourierClientConfiguration -): ICourierClientNotifications => { - return { - cancelSubmission: cancelSubmission(options), - getContent: getContent(options), - getDraftContent: getDraftContent(options), - getSubmissionChecks: getSubmissionChecks(options), - list: list(options), - postDraftVariations: postDraftVariations(options), - postVariations: postVariations(options), - putSubmissionChecks: putSubmissionChecks(options) - }; -}; diff --git a/src/notifications/types.ts b/src/notifications/types.ts deleted file mode 100644 index df9c57e..0000000 --- a/src/notifications/types.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { ICourierPaging } from "../types"; - -export type MessageRoutingMethod = "all" | "single"; -export type MessageRoutingChannel = string | IMessageRouting; -export interface IMessageRouting { - method: MessageRoutingMethod; - channels: MessageRoutingChannel[]; -} - -export interface ICourierNotificationListResponse { - paging: ICourierPaging; - results: Array<{ - created_at: number; - id: string; - routing: IMessageRouting; - tags: { - data: Array<{ - id: string; - name: string; - }>; - }; - title: string; - updated_at: number; - }>; -} - -export interface ICourierNotificationListParams { - cursor?: string; -} - -export type BlockType = - | "action" - | "divider" - | "image" - | "jsonnet" - | "list" - | "markdown" - | "quote" - | "template" - | "text"; - -export interface ICourierNotificationBlock { - alias?: string; - context?: string; - id: string; - type: BlockType; - content?: string | { parent?: string; children?: string }; - locales?: { - [locale: string]: - | string - | { - parent?: string; - children?: string; - }; - }; - checksum?: string; -} - -export interface ICourierNotificationChannel { - id: string; - type?: string; - content?: { - subject?: string; - title?: string; - }; - locales?: { - [locale: string]: { - subject?: string; - title?: string; - }; - }; - checksum?: string; -} - -export interface ICourierNotificationGetContentResponse { - blocks?: ICourierNotificationBlock[]; - channels?: ICourierNotificationChannel[]; - checksum?: string; -} - -export interface ICourierNotificationPostVariationsParams { - blocks?: ICourierNotificationBlock[]; - channels?: ICourierNotificationChannel[]; -} - -export interface ICourierNotificationPostDraftVariationsParams { - blocks?: ICourierNotificationBlock[]; - channels?: ICourierNotificationChannel[]; -} - -export type CheckStatus = "RESOLVED" | "FAILED" | "PENDING"; - -export interface ICheck { - id: string; - status: CheckStatus; - type: "custom"; - updated: number; -} - -export interface ICourierNotificationGetSubmissionChecksResponse { - checks: ICheck[]; -} - -export interface ICourierNotificationPutSubmissionChecksParams { - checks: Array>; -} - -export interface ICourierNotificationPutSubmissionChecksResponse { - checks: ICheck[]; -} - -export interface ICourierClientNotifications { - list: ( - params: ICourierNotificationListParams - ) => Promise; - - getContent: (id: string) => Promise; - - getDraftContent: ( - id: string - ) => Promise; - - postVariations: ( - id: string, - params: ICourierNotificationPostVariationsParams - ) => Promise; - - postDraftVariations: ( - id: string, - params: ICourierNotificationPostDraftVariationsParams - ) => Promise; - - getSubmissionChecks: ( - id: string, - submissionId: string - ) => Promise; - - putSubmissionChecks: ( - id: string, - submissionId: string, - params: ICourierNotificationPutSubmissionChecksParams - ) => Promise; - - cancelSubmission: (id: string, submissionId: string) => Promise; -} diff --git a/src/preferences/index.ts b/src/preferences/index.ts deleted file mode 100644 index 099933d..0000000 --- a/src/preferences/index.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - ICourierClientPreferences, - ICourierPreferencesGetResponse, - ICourierPreferencesListResponse, - ICourierPreferencesPutResponse, - IRecipientPreferences -} from "./types"; - -const list = (options: ICourierClientConfiguration) => { - return async (): Promise => { - const res = await options.httpClient.get( - `/preferences` - ); - return res.data; - }; -}; - -const get = (options: ICourierClientConfiguration) => { - return async ( - recipientId: string - ): Promise => { - const res = await options.httpClient.get( - `/preferences/${recipientId}` - ); - return res.data; - }; -}; - -const put = (options: ICourierClientConfiguration) => { - return async ( - recipientId: string, - params?: IRecipientPreferences - ): Promise => { - const categories = params?.categories ?? {}; - const notifications = params?.notifications ?? {}; - - const res = await options.httpClient.put( - `/preferences/${recipientId}`, - { - categories, - notifications - } - ); - return res.data; - }; -}; - -export const preferences = ( - options: ICourierClientConfiguration -): ICourierClientPreferences => { - return { - get: get(options), - list: list(options), - put: put(options) - }; -}; diff --git a/src/preferences/types.ts b/src/preferences/types.ts deleted file mode 100644 index b7a74ed..0000000 --- a/src/preferences/types.ts +++ /dev/null @@ -1,59 +0,0 @@ -export type RuleType = "snooze"; - -export interface IRule { - type: T; -} - -export interface ISnoozeRule extends IRule<"snooze"> { - start?: string; - until: string; -} - -export type ChannelClassification = "direct_message" | "email" | "push"; - -export type Rule = ISnoozeRule; - -export type PreferenceStatus = "OPTED_OUT" | "OPTED_IN"; - -export interface ICourierNotificationPreferences { - [id: string]: { - status: PreferenceStatus; - rules?: Rule[]; - channel_preferences?: Array<{ - channel: ChannelClassification; - }>; - }; -} - -export interface ICourierPreferencesGetResponse { - categories?: ICourierNotificationPreferences; - notifications: ICourierNotificationPreferences; -} - -export interface ICourierPreferencesListResponse { - uncategorized: Array<{}>; - categories: Array<{ - id: string; - title: string; - config?: any; // TODO - notifications?: Array<{}>; - }>; -} - -export interface IRecipientPreferences { - categories?: ICourierNotificationPreferences; - notifications: ICourierNotificationPreferences; -} - -export interface ICourierPreferencesPutResponse { - status: "SUCCESS"; -} - -export interface ICourierClientPreferences { - get: (recipientId: string) => Promise; - list: () => Promise; - put: ( - recipientId: string, - params: IRecipientPreferences - ) => Promise; -} diff --git a/src/profile.ts b/src/profile.ts deleted file mode 100644 index 52cf95e..0000000 --- a/src/profile.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { ICourierRecipientSubscriptionsResponse } from "./lists/types"; -import { - ICourierClientConfiguration, - ICourierProfileDeleteParameters, - ICourierProfileGetParameters, - ICourierProfileGetResponse, - ICourierProfileListsPostParameters, - ICourierProfilePostConfig, - ICourierProfilePostParameters, - ICourierProfilePostResponse, - ICourierProfilePutParameters, - ICourierProfilePutResponse -} from "./types"; - -export const replaceProfile = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierProfilePutParameters - ): Promise => { - const res = await options.httpClient.put( - `/profiles/${params.recipientId}`, - { - profile: params.profile - } - ); - return res.data; - }; -}; - -export const mergeProfile = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierProfilePostParameters, - config?: ICourierProfilePostConfig - ): Promise => { - const res = await options.httpClient.post( - `/profiles/${params.recipientId}`, - { - profile: params.profile - }, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - return res.data; - }; -}; - -export const getProfile = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierProfileGetParameters - ): Promise => { - const res = await options.httpClient.get( - `/profiles/${params.recipientId}` - ); - return res.data; - }; -}; - -export const deleteProfile = (options: ICourierClientConfiguration) => { - return async (params: ICourierProfileDeleteParameters): Promise => { - await options.httpClient.delete(`/profiles/${params.recipientId}`); - }; -}; - -export const getRecipientSubscriptions = ( - options: ICourierClientConfiguration -) => { - return async ( - params: ICourierProfileGetParameters - ): Promise => { - const res = await options.httpClient.get< - ICourierRecipientSubscriptionsResponse - >(`/profiles/${params.recipientId}/lists`); - return res.data; - }; -}; - -export const addRecipientToLists = (options: ICourierClientConfiguration) => { - return async ( - params: ICourierProfileListsPostParameters - ): Promise => { - const res = await options.httpClient.post( - `/profiles/${params.recipientId}/lists`, - { - lists: params.lists - } - ); - return res.data; - }; -}; - -export const removeRecipientFromAllLists = ( - options: ICourierClientConfiguration -) => { - return async ( - params: ICourierProfileGetParameters - ): Promise => { - const res = await options.httpClient.delete( - `/profiles/${params.recipientId}/lists` - ); - return res.data; - }; -}; diff --git a/src/send/index.ts b/src/send/index.ts deleted file mode 100644 index 82fb40d..0000000 --- a/src/send/index.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { - ICourierClientConfiguration, - ICourierSendConfig, - ICourierSendMessageParameters, - ICourierSendMessageResponse, - ICourierSendParameters, - ICourierSendResponse, - SendResponse -} from "../types"; - -const sendCall = async ( - options: ICourierClientConfiguration, - params: ICourierSendParameters, - config?: ICourierSendConfig -) => { - const res = await options.httpClient.post( - "/send", - { - brand: params.brand, - data: params.data, - event: params.eventId, - override: params.override, - preferences: params.preferences, - profile: params.profile, - recipient: params.recipientId - }, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - - return res.data; -}; - -const sendMessageCall = async ( - options: ICourierClientConfiguration, - params: ICourierSendMessageParameters, - config?: ICourierSendConfig -) => { - const res = await options.httpClient.post( - "/send", - { - message: params.message - }, - { - idempotencyExpiry: config?.idempotencyExpiry, - idempotencyKey: config?.idempotencyKey - } - ); - - return res.data; -}; - -export const send = (options: ICourierClientConfiguration) => { - return async < - T extends ICourierSendParameters | ICourierSendMessageParameters - >( - params: T, - config?: ICourierSendConfig - ): Promise> => { - if ((params as ICourierSendMessageParameters).message) { - const v2Response = await sendMessageCall( - options, - params as ICourierSendMessageParameters, - config - ); - return v2Response as SendResponse; - } - - const v1Response = await sendCall( - options, - params as ICourierSendParameters, - config - ); - return v1Response as SendResponse; - }; -}; diff --git a/src/send/types.ts b/src/send/types.ts deleted file mode 100644 index 4c707fe..0000000 --- a/src/send/types.ts +++ /dev/null @@ -1,465 +0,0 @@ -/* tslint:disable:interface-name */ -export interface IBrandSnippet { - format: "handlebars"; // could support other formats in the future - name: string; - value: string; -} -export interface IBrandSnippets { - items: IBrandSnippet[]; -} - -export interface IBrandColors { - // CSS compliant color value - primary?: string; - secondary?: string; - tertiary?: string; -} - -interface IBrandTemplate { - backgroundColor?: string; - blocksBackgroundColor?: string; - enabled: boolean; - footer?: string; - head?: string; - header?: string; - width?: string; -} - -export interface IBrandTemplateOverride extends IBrandTemplate { - mjml?: IBrandTemplate; - footerBackgroundColor?: string; - footerFullWidth?: boolean; -} - -export interface IBrandSettingsSocialPresence { - inheritDefault?: boolean; - facebook?: { - url: string; - }; - instagram?: { - url: string; - }; - linkedin?: { - url: string; - }; - medium?: { - url: string; - }; - twitter?: { - url: string; - }; -} - -export interface IBrandSettingsEmail { - templateOverride?: IBrandTemplateOverride; - head?: { - inheritDefault: boolean; - content?: string; - }; - footer?: { - content?: object; - inheritDefault?: boolean; - markdown?: string; - social?: IBrandSettingsSocialPresence; - }; - header?: { - inheritDefault?: boolean; - barColor?: string; - logo?: { - href?: string; - image?: string; - }; - }; -} - -export interface IBrandSettingsInApp { - borderRadius?: string; - disableMessageIcon?: boolean; - fontFamily?: string; - placement?: "top" | "bottom" | "left" | "right"; - widgetBackground?: { - topColor?: string; - bottomColor?: string; - }; - colors?: { - invertHeader?: boolean; - invertButtons?: boolean; - }; - icons?: { - bell?: string; - message?: string; - }; - preferences?: { - templateIds: string[]; - }; -} - -export type IActionButtonStyle = "button" | "link"; -export type IAlignment = "center" | "left" | "right" | "full"; - -export interface ElementalContent { - version: "2022-01-01"; - brand?: any; // TODO - elements: ElementalNode[]; -} - -export type ElementalNode = - | ElementalTextNode - | ElementalMetaNode - | ElementalChannelNode - | ElementalImageNode - | ElementalActionNode - | ElementalDividerNode - | ElementalGroupNode - | ElementalQuoteNode; - -export interface ElementalTextNode extends ElementalBaseNode { - type: "text"; - content: string; - format?: "markdown"; - locales?: { - [locale: string]: { - content: string; - }; - }; -} - -export interface ElementalMetaNode extends ElementalBaseNode { - type: "meta"; - title?: string; -} - -export interface ElementalChannelNode extends ElementalBaseNode { - type: "channel"; - channel: string; - elements?: ElementalNode[]; - raw?: { [templateName: string]: any }; -} - -export interface ElementalImageNode extends ElementalBaseNode { - type: "image"; - src: string; - href?: string; - align?: IAlignment; - altText?: string; - width?: string; -} - -export interface ElementalActionNode extends ElementalBaseNode { - type: "action"; - content: string; - href: string; - actionId?: string; - style?: IActionButtonStyle; - align?: IAlignment; - backgroundColor?: string; - locales?: { - [locale: string]: { - content: string; - }; - }; -} - -export interface ElementalDividerNode extends ElementalBaseNode { - type: "divider"; - color?: string; -} - -export interface ElementalGroupNode extends ElementalBaseNode { - type: "group"; - elements: ElementalNode[]; -} - -export interface ElementalQuoteNode extends ElementalBaseNode { - type: "quote"; - content: string; - align?: IAlignment; - borderColor?: string; - textStyle?: "text" | "h1" | "h2" | "subtext"; - locales?: { - [locale: string]: { - content: string; - }; - }; -} - -interface ElementalBaseNode { - type: string; - channels?: string[]; - ref?: string; - if?: string; - loop?: string; -} - -export interface MessageContext { - tenant_id?: string; -} - -export interface MessageData extends Record {} - -export interface MessageDelay { - duration?: number; -} - -export type RuleType = "snooze" | "channel_preferences" | "status"; - -export interface IRule { - type: T; -} - -export interface ISnoozeRule extends IRule<"snooze"> { - start?: string; - until: string; -} - -export type Rule = ISnoozeRule; - -export type PreferenceStatus = "OPTED_IN" | "OPTED_OUT" | "REQUIRED"; - -export type ChannelClassification = "direct_message" | "email" | "push"; - -export interface IPreference { - status: PreferenceStatus; - rules?: Rule[]; - channel_preferences?: Array<{ - channel: ChannelClassification; - }>; - source?: "subscription" | "list" | "recipient"; -} - -export interface IPreferences { - [id: string]: IPreference; -} - -export interface IProfilePreferences { - categories?: IPreferences; - notifications: IPreferences; - templateId?: string; -} - -interface InvalidListRecipient { - user_id: string; - list_pattern: string; -} - -type ListRecipientType = Record & - { - [key in keyof InvalidListRecipient]?: never; - }; - -export interface ListFilter { - operator: "MEMBER_OF"; // send to users only if they are member of the account - path: "account_id"; - value: string; -} -export interface ListRecipient extends ListRecipientType { - list_id?: string; - data?: MessageData; - filters?: ListFilter[]; -} - -interface InvalidListPatternRecipient { - user_id: string; - list_id: string; -} - -type ListPatternRecipientType = Record & - { - [key in keyof InvalidListPatternRecipient]?: never; - }; -export interface ListPatternRecipient extends ListPatternRecipientType { - list_pattern?: string; - data?: MessageData; -} - -interface InvalidUserRecipient { - list_id: string; - list_pattern: string; -} - -type UserRecipientType = Record & - { - [key in keyof InvalidUserRecipient]?: never; - }; - -export interface AudienceFilter { - operator: "MEMBER_OF"; // send to users only if they are member of the account - path: "account_id"; - value: string; -} -export interface AudienceRecipient { - audience_id: string; - data?: MessageData; - filters?: AudienceFilter[]; -} - -export interface UserRecipient extends UserRecipientType { - // @deprecated - use tenant_id - account_id?: string; - context?: MessageContext; - data?: MessageData; - email?: string; - locale?: string; - user_id?: string; - phone_number?: string; - preferences?: IProfilePreferences; - tenant_id?: string; -} - -export type Recipient = - | AudienceRecipient - | ListRecipient - | ListPatternRecipient - | UserRecipient; - -export type MessageRecipient = Recipient | Recipient[]; - -export interface ElementalContentSugar { - body?: string; - title?: string; -} - -export interface Timeout { - provider?: { [provider: string]: number }; - channel?: { [channel: string]: number }; - message?: number; - escalation?: number; - criteria?: "no-escalation" | "delivered" | "viewed" | "engaged"; -} - -export type Content = ElementalContentSugar | ElementalContent; - -export interface BaseMessage { - brand_id?: string; - channels?: MessageChannels; - context?: MessageContext; - data?: MessageData; - delay?: MessageDelay; - metadata?: MessageMetadata; - providers?: MessageProviders; - routing?: Routing; - timeout?: Timeout; - to: MessageRecipient; -} - -interface TrackingOverride { - open: boolean; -} -export interface MessageProviders { - [key: string]: { - override?: Record; - if?: string; - timeouts?: number; - }; -} - -export interface MessageChannelEmailOverride { - /* tslint:disable-next-line:array-type */ - attachments?: Record[]; - bcc?: string; - // content?: Content; TODO: https://linear.app/trycourier/issue/C-4462/add-content-support-to-channel-overrides - brand?: { - snippets?: IBrandSnippets; - settings?: { - colors?: IBrandColors; - email?: IBrandSettingsEmail; - }; - }; - cc?: string; - from?: string; - html?: string; - reply_to?: string; - subject?: string; - text?: string; - tracking?: TrackingOverride; -} - -export interface MessageChannelPushOverride { - body?: string; - brand?: { - snippets?: IBrandSnippets; - settings?: { - colors?: IBrandColors; - inapp?: IBrandSettingsInApp; - }; - }; - // content?: Content; TODO: https://linear.app/trycourier/issue/C-4462/add-content-support-to-channel-overrides - click_action?: string; - data?: Record; - icon?: string; - title?: string; -} - -export interface MessageChannels { - [key: string]: { - brand_id?: string; - providers?: string[]; - routing_method?: "all" | "single"; - if?: string; - timeouts?: { - provider?: number; - channel?: number; - }; - override?: MessageChannelEmailOverride | MessageChannelPushOverride; - metadata?: { - utm?: UTM; - }; - }; -} - -export interface Routing { - method: "all" | "single"; - channels: RoutingChannel[]; -} - -export type RoutingChannel = - | RoutingStrategyChannel - | RoutingStrategyProvider - | string; - -export interface RoutingStrategyChannel> { - channel: string; - config?: T; - method?: "all" | "single"; - /* tslint:disable-next-line:array-type */ - providers?: (RoutingStrategyProvider | string)[]; - if?: string; -} - -export interface RoutingStrategyProvider> { - name: string; - config?: T; - if?: string; - metadata?: { - utm?: UTM; - }; -} - -export interface UTM { - source?: string; - medium?: string; - campaign?: string; - term?: string; - content?: string; -} - -export interface MessageMetadata { - event?: string; - tags?: string[]; - utm?: UTM; - trace_id?: string; -} - -export interface ContentMessage extends BaseMessage { - content: Content; -} - -export interface TemplateMessage extends BaseMessage { - template: string; -} - -export type Message = ContentMessage | TemplateMessage; - -export interface RequestV2 { - message: Message; -} diff --git a/src/tenants/index.ts b/src/tenants/index.ts deleted file mode 100644 index ff70578..0000000 --- a/src/tenants/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import * as TenantTypes from "./types"; - -const deleteTenant = (options: ICourierClientConfiguration) => async ( - tenantId: string -): Promise => { - await options.httpClient.delete(`/tenants/${tenantId}`); -}; - -const getTenant = (options: ICourierClientConfiguration) => { - return async (tenantId: string): Promise => { - const response = await options.httpClient.get( - `/tenants/${tenantId}` - ); - return response.data; - }; -}; - -const listTenants = (options: ICourierClientConfiguration) => { - return async ( - listOptions?: TenantTypes.ITenantListOptions - ): Promise> => { - const response = await options.httpClient.get< - TenantTypes.IPaginatedResult - >("/tenants", undefined, { - params: { - cursor: listOptions?.cursor || "", - limit: listOptions?.limit || "20" - } - }); - return response.data; - }; -}; - -const putTenant = (options: ICourierClientConfiguration) => { - return async ( - tenant: Omit - ): Promise => { - const response = await options.httpClient.put( - `/tenants/${tenant.id}`, - tenant - ); - return response.data; - }; -}; - -export const tenants = (options: ICourierClientConfiguration) => ({ - delete: deleteTenant(options), - get: getTenant(options), - listTenants: listTenants(options), - put: putTenant(options) -}); diff --git a/src/tenants/types.ts b/src/tenants/types.ts deleted file mode 100644 index 7a06c1a..0000000 --- a/src/tenants/types.ts +++ /dev/null @@ -1,38 +0,0 @@ -export interface ITenant { - brand_id?: string; - id: string; - name: string; - parent_tenant_id?: string; - default_preferences?: { - items: Array<{ - id: string; - status: "OPTED_IN" | "OPTED_OUT" | "REQUIRED"; - type: "subscription_topic"; - }>; - }; - properties?: { [key: string]: any }; - user_profile?: Record; - type: "tenant"; -} - -export interface IPaginatedResult { - cursor?: string; - has_more: boolean; - items: T[]; - next_url?: string; - type: "list"; - url: string; -} - -export interface ITenantListOptions { - cursor?: string; - limit?: string; -} -export interface ICourierClientTenants { - delete: (id: string) => Promise; - get: (id: string) => Promise; - listTenants: ( - options?: ITenantListOptions - ) => Promise>; - put: (tenant: Omit) => Promise; -} diff --git a/src/token-management/index.ts b/src/token-management/index.ts deleted file mode 100644 index 710a052..0000000 --- a/src/token-management/index.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - IDeleteUserTokenOpts, - IGetUserTokenOpts, - IGetUserTokenResponse, - IGetUserTokensOpts, - IPatchUserTokenOpts, - IPutUserTokenOpts, - IPutUserTokensOpts -} from "./types"; - -/** Associate a group of tokens with the supplied :user_id. Will overwrite any existing tokens associated with that user. */ -const putUserTokens = (options: ICourierClientConfiguration) => { - return async (opts: IPutUserTokensOpts): Promise => { - await options.httpClient.put(`/users/${opts.user_id}/tokens`, { - tokens: opts.tokens - }); - }; -}; - -/** Associate a token with the supplied :user_id. If token exists it's value will be replaced with the passed body, otherwise the token will be created. */ -const putUserToken = (options: ICourierClientConfiguration) => { - return async (opts: IPutUserTokenOpts): Promise => { - await options.httpClient.put( - `/users/${opts.user_id}/tokens/${opts.token.token}`, - opts.token - ); - }; -}; - -const patchUserToken = (options: ICourierClientConfiguration) => { - return async (opts: IPatchUserTokenOpts): Promise => { - await options.httpClient.patch( - `/users/${opts.user_id}/tokens/${opts.token}`, - { patch: opts.patch } - ); - }; -}; - -const getUserToken = (options: ICourierClientConfiguration) => { - return async (opts: IGetUserTokenOpts): Promise => { - const res = await options.httpClient.get( - `/users/${opts.user_id}/tokens/${opts.token}` - ); - return res.data as IGetUserTokenResponse; - }; -}; - -const getUserTokens = (options: ICourierClientConfiguration) => { - return async ( - opts: IGetUserTokensOpts - ): Promise<{ tokens: IGetUserTokenResponse[] }> => { - const res = await options.httpClient.get(`/users/${opts.user_id}/tokens`); - return res.data as { tokens: IGetUserTokenResponse[] }; - }; -}; - -const deleteUserToken = (options: ICourierClientConfiguration) => { - return async (opts: IDeleteUserTokenOpts): Promise => { - await options.httpClient.delete( - `/users/${opts.user_id}/tokens/${opts.token}` - ); - }; -}; - -export const tokenManagement = (options: ICourierClientConfiguration) => { - return { - deleteUserToken: deleteUserToken(options), - getUserToken: getUserToken(options), - getUserTokens: getUserTokens(options), - patchUserToken: patchUserToken(options), - putUserToken: putUserToken(options), - putUserTokens: putUserTokens(options) - }; -}; diff --git a/src/token-management/types.ts b/src/token-management/types.ts deleted file mode 100644 index 0ab59bd..0000000 --- a/src/token-management/types.ts +++ /dev/null @@ -1,66 +0,0 @@ -export interface IUserToken { - token: string; - - provider_key: "firebase-fcm" | "apn" | "expo" | "onesignal"; - - /** ISO 8601 Date. Set to false to disable expiration */ - expiry_date?: string | false; - - /** Additional properties to be passed to provider or to be generically associated with the token */ - properties?: { [key: string]: any }; - - device?: { - app_id?: string; - ad_id?: string; - device_id?: string; - platform?: string; - manufacturer?: string; - model?: string; - }; - - tracking?: { - os_version?: string; - ip?: string; - lat?: string; - long?: string; - }; -} - -export interface IGetUserTokenResponse extends IUserToken { - status: "active" | "unknown" | "failed" | "revoked"; - status_reason?: string; -} - -export interface IPutUserTokensOpts { - user_id: string; - tokens: IUserToken[]; -} - -export interface IPutUserTokenOpts { - user_id: string; - token: IUserToken; -} - -export interface IPatchUserTokenOpts { - user_id: string; - token: string; - patch: Array<{ - op: "replace" | "add" | "remove" | "copy" | "move" | "test"; - path: string; - value?: string; - }>; -} - -export interface IGetUserTokenOpts { - user_id: string; - token: string; -} - -export interface IGetUserTokensOpts { - user_id: string; -} - -export interface IDeleteUserTokenOpts { - user_id: string; - token: string; -} diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 3f82a9a..0000000 --- a/src/types.ts +++ /dev/null @@ -1,494 +0,0 @@ -import { ICourierClientAudiences } from "./audiences/types"; -import { auditEvents } from "./audit-events"; -import { ICourierClientAutomations } from "./automations/types"; -import { ICourierClientBulk } from "./bulk/types"; -import { - ICourierAuthIssueTokenParameters, - ICourierAuthIssueTokenResponse -} from "./issue-token/types"; -import { - ICourierClientLists, - ICourierList, - ICourierRecipientSubscriptionsResponse -} from "./lists/types"; -import { ICourierClientNotifications } from "./notifications/types"; -import { - ICourierClientPreferences, - IRecipientPreferences -} from "./preferences/types"; -import { Message } from "./send/types"; -import { ICourierClientTenants } from "./tenants/types"; -import { tokenManagement } from "./token-management"; -import { users } from "./users"; - -export interface IInitHttpClientOptions { - baseUrl: string; - version: string; - authorizationToken: string; -} - -export type HttpMethodClient = ( - url: string, - body?: object, - config?: { - params?: Record; - idempotencyKey?: string; - idempotencyExpiry?: number; - } -) => Promise<{ data: T }>; - -export interface IHttpClient { - post: HttpMethodClient; - patch: HttpMethodClient; - put: HttpMethodClient; - get: HttpMethodClient; - delete: HttpMethodClient; -} - -export interface ICourierClientOptions { - baseUrl?: string; - authorizationToken?: string; -} - -export interface ICourierClientConfiguration { - httpClient: IHttpClient; -} - -// POST /send - -export interface ICourierSendParameters { - eventId: string; - recipientId: string; - data?: object; - brand?: string; - preferences?: IRecipientPreferences; - profile?: object; - override?: object; -} - -export interface ICourierSendMessageParameters { - message: Message; -} - -export interface ICourierSendConfig { - idempotencyKey?: string; - idempotencyExpiry?: number; -} - -export interface ICourierSendResponse { - messageId: string; -} - -export interface ICourierSendMessageResponse { - requestId: string; -} - -export interface ICourierSendParams { - event: string; - data?: object; - brand?: string; - override?: object; -} -export interface ICourierSendListParams extends ICourierSendParams { - list: string; -} -export interface ICourierSendPatternParams extends ICourierSendParams { - pattern: string; -} - -export type ICourierSendListOrPatternParams = - | ICourierSendListParams - | ICourierSendPatternParams; -// PUT /profiles/{id} - -export interface ICourierProfilePutParameters { - recipientId: string; - profile: object; -} - -export interface ICourierProfilePutResponse { - status: "SUCCESS"; -} - -// POST /profiles/{id} - -export interface ICourierProfilePostParameters { - recipientId: string; - profile: object; -} -// POST /profiles/{id}/lists -export type List = Omit & { - listId: string; - preferences?: IRecipientPreferences; -}; - -export interface ICourierProfileListsPostParameters { - recipientId: string; - lists: List[]; -} - -export interface ICourierProfilePostConfig { - idempotencyKey?: string; - idempotencyExpiry?: number; -} - -export interface ICourierProfilePostResponse { - status: "SUCCESS"; -} - -// GET /profiles/{id} - -export interface ICourierProfileGetParameters { - recipientId: string; -} - -export interface ICourierProfileGetResponse { - profile: object; -} - -export interface ICourierMessagesGetParameters { - cursor?: string; - eventId?: string; - listId?: string; - messageId?: string; - notificationId?: string; - recipientId?: string; - status?: string | string[]; - tags?: string | string[]; - traceId?: string; -} - -export interface ICourierMessagesGetResponse { - paging: ICourierPaging; - results: Array<{ - enqueued?: number; - event?: string; - id: string; - notification?: string; - recipient: string; - sent?: number; - status: string; - tags?: string[]; - }>; -} - -export interface ICourierMessageCancelResponse { - canceledAt: number; // the milli second timestamp of the successful cancelation request - event: string; // event id of the notification - id: string; // the message id - recipient: string; // the recipient email or id - status: string; // the message status - - // optional - clicked?: number; // the milli-second timestamp of the clicked event - delivered?: number; // the milli-second timestamp of the deleivered event - enqueued?: number; // the milli-second timestamp of the enqueued event - error?: string; // the error message - jobId?: string; // the bulk job id - listId?: string; // the list id of the list - listMessageId?: string; // the request id from the sucessful list send request - notification?: string; // the notification id - opened?: number; // the milli-second timestamp of the opened event - runId?: string; // the automation run id - sent?: number; // the milli-second timestamp of the sent event -} - -export interface ICourierMessageGetResponse { - clicked?: number; - delivered?: number; - enqueued?: number; - error?: string; - event?: string; - id: string; - idempotencyKey?: string; - listId?: string; - listMessageId?: string; - notification?: string; - opened?: number; - providers?: Array<{ - channel: { - key?: string; - name?: string; - template: string; - }; - clicked?: number; - delivered?: number; - error?: string; - provider: string; - reference?: { [key: string]: string | number }; - sent: number; - status: MessageStatus; - }>; - reason?: MessageStatusReason; - reasonCode?: MessageStatusReasonCode; - reasonDetails?: string; - recipient: string; - runId?: string; - sent?: number; - status: MessageStatus; -} - -export type MessageStatus = - | "CLICKED" - | "DELIVERED" - | "ENQUEUED" - | "FILTERED" - | "OPENED" - | "SENT" - | "SIMULATED" - | "UNDELIVERABLE" - | "UNMAPPED" - | "UNROUTABLE"; - -export type MessageHistoryType = - | MessageStatus - | "DELIVERING" - | "FILTERED" - | "MAPPED" - | "PROFILE_LOADED" - | "RENDERED"; - -export type MessageStatusReason = - | "BOUNCED" - | "FAILED" - | "FILTERED" - | "NO_CHANNELS" - | "NO_PROVIDERS" - | "OPT_IN_REQUIRED" - | "PROVIDER_ERROR" - | "UNPUBLISHED" - | "UNSUBSCRIBED"; - -export type MessageStatusReasonCode = "HARD" | "SOFT"; - -export interface IMessageHistory { - ts: number; - type: T; -} - -export interface IEnqueuedMessageHistory extends IMessageHistory<"ENQUEUED"> { - data?: string | { [key: string]: string }; - event: string; - profile?: { [key: string]: any }; - override?: { [key: string]: any }; - recipient: string; -} - -export interface IMappedMessageHistory extends IMessageHistory<"MAPPED"> { - event_id: string; - notification_id: string; -} - -export interface IProfileLoadedMessageHistory - extends IMessageHistory<"PROFILE_LOADED"> { - merged_profile?: { [key: string]: any }; - received_profile?: { [key: string]: any }; - stored_profile?: { [key: string]: any }; -} - -export interface IRenderedMessageHistory - extends IRoutedMessageHistory<"RENDERED"> { - output: { - [key: string]: string; - }; -} - -export interface IUnroutableMessageHistory - extends IMessageHistory<"UNROUTABLE"> { - reason: MessageStatusReason; -} - -export interface IUndeliverableMessageHistory - extends IMessageHistory<"UNDELIVERABLE">, - Partial, "ts" | "type">> { - reason: MessageStatusReason; - reasonCode?: MessageStatusReasonCode; -} - -export type RoutedMessageHistoryTypes = Extract< - MessageHistoryType, - | "CLICKED" - | "DELIVERED" - | "DELIVERING" - | "OPENED" - | "RENDERED" - | "SENT" - | "UNDELIVERABLE" ->; - -export interface IRoutedMessageHistory - extends IMessageHistory { - channel: { id: string; label?: string }; - integration: { id: string; provider: string }; -} - -export interface IDeliveredMessageHistory - extends IRoutedMessageHistory<"DELIVERED"> { - reference: { [key: string]: string }; -} - -export interface IProviderErrorMessageHistory - extends IRoutedMessageHistory<"UNDELIVERABLE"> { - error_message: string; -} - -export interface ICourierMessageGetHistoryResponse { - results: Array< - | IEnqueuedMessageHistory - | IMappedMessageHistory - | IProfileLoadedMessageHistory - | IRenderedMessageHistory - | IRoutedMessageHistory - | IDeliveredMessageHistory - | IProviderErrorMessageHistory - | IUndeliverableMessageHistory - | IUnroutableMessageHistory - >; -} - -export interface IApiMessageOutputItem { - channel: string; - channel_id: string; - content: { - html?: string; - title?: string; - blocks?: any[]; - body?: string; - subject?: string; - text?: string; - }; -} - -export interface ICourierMessageGetOutputResponse { - results: IApiMessageOutputItem[]; -} - -// DELETE /profiles/{recipient_id} - -export interface ICourierProfileDeleteParameters { - recipientId: string; -} - -interface ICourierBrandSettings { - colors?: { - primary: string; - secondary: string; - tertiary: string; - }; - email?: { - footer: object; - header: object; - }; -} - -interface ICourierBrandSnippets { - items: Array<{ - format: string; - name: string; - value: string; - }>; -} - -export interface ICourierBrand { - created: number; - id?: string; - name: string; - published: number; - settings: ICourierBrandSettings; - updated: number; - snippets?: ICourierBrandSnippets; - version: string; -} - -export interface ICourierPaging { - cursor?: string; - more: boolean; -} - -export interface ICourierBrandParameters { - id?: string; - name: string; - settings: ICourierBrandSettings; - snippets?: ICourierBrandSnippets; -} - -export interface ICourierBrandPostConfig { - idempotencyKey?: string; - idempotencyExpiry?: number; -} - -export interface ICourierBrandPutParameters extends ICourierBrandParameters { - id: string; -} - -export interface ICourierBrandGetAllResponse { - paging: ICourierPaging; - results: ICourierBrand[]; -} - -export type SendResponse< - T extends ICourierSendParameters | ICourierSendMessageParameters -> = T extends ICourierSendParameters - ? ICourierSendResponse - : ICourierSendMessageResponse; - -export interface ICourierClient { - addRecipientToLists: ( - params: ICourierProfileListsPostParameters - ) => Promise; - tenants: ICourierClientTenants; - audiences: ICourierClientAudiences; - auditEvents: ReturnType; - automations: ICourierClientAutomations; - bulk: ICourierClientBulk; - cancelMessage: (messageId: string) => Promise; - createBrand: ( - params: ICourierBrandParameters, - config?: ICourierBrandPostConfig - ) => Promise; - deleteBrand: (brandId: string) => Promise; - getBrand: (brandId: string) => Promise; - getBrands: (params?: { - cursor: string; - }) => Promise; - getMessage: (messageId: string) => Promise; - getMessageHistory: ( - messageId: string - ) => Promise; - getMessageOutput: ( - messageId: string - ) => Promise; - getMessages: ( - params?: ICourierMessagesGetParameters - ) => Promise; - getProfile: ( - params: ICourierProfileGetParameters - ) => Promise; - deleteProfile: (params: ICourierProfileDeleteParameters) => Promise; - getRecipientSubscriptions: ( - params: ICourierProfileGetParameters - ) => Promise; - lists: ICourierClientLists; - mergeProfile: ( - params: ICourierProfilePostParameters, - config?: ICourierProfilePostConfig - ) => Promise; - notifications: ICourierClientNotifications; - preferences: ICourierClientPreferences; - removeRecipientFromAllLists: ( - params: ICourierProfileGetParameters - ) => Promise; - replaceBrand: (params: ICourierBrandPutParameters) => Promise; - replaceProfile: ( - params: ICourierProfilePutParameters - ) => Promise; - send: ( - params: T, - config?: ICourierSendConfig - ) => Promise>; - tokenManagement: ReturnType; - users: ReturnType; - issueToken: ( - params: ICourierAuthIssueTokenParameters - ) => Promise; -} diff --git a/src/users/index.ts b/src/users/index.ts deleted file mode 100644 index 79fdcf8..0000000 --- a/src/users/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ICourierClientConfiguration } from "../types"; -import { - IGetTopicPreferencesResponse, - ITopicPreference, - IUser, - IUserAccount, -} from "./types"; - -const put = (options: ICourierClientConfiguration) => { - return async (id: string, user: IUser): Promise => { - await options.httpClient.put(`/users/${id}`, user); - }; -}; - -const putAccounts = (options: ICourierClientConfiguration) => { - return async (id: string, accounts: IUserAccount[]): Promise => { - await options.httpClient.put<{ - accounts: IUserAccount[]; - }>(`/users/${id}/accounts`, accounts); - }; -}; - -const putUserPreferenceByTopic = (options: ICourierClientConfiguration) => { - return async ( - userId: string, - topicId: string, - topic: Omit - ): Promise => { - await options.httpClient.put( - `/users/${userId}/preferences/${topicId}`, - { - topic, - } - ); - }; -}; - -const getUserPreferenceByTopic = (options: ICourierClientConfiguration) => { - return async (userId: string, topicId: string): Promise => { - const res = await options.httpClient.get( - `/users/${userId}/preferences/${topicId}` - ); - return res.data?.topic; - }; -}; - -const getUserPreferenceByTopics = (options: ICourierClientConfiguration) => { - return async (userId: string): Promise => { - const res = await options.httpClient.get<{}>( - `/users/${userId}/preferences` - ); - return res.data; - }; -}; - -export const users = (options: ICourierClientConfiguration) => ({ - getUserPreferenceByTopic: getUserPreferenceByTopic(options), - getUserPreferenceByTopics: getUserPreferenceByTopics(options), - put: put(options), - putAccounts: putAccounts(options), - putUserPreferenceByTopic: putUserPreferenceByTopic(options), -}); diff --git a/src/users/types.ts b/src/users/types.ts deleted file mode 100644 index 1f77750..0000000 --- a/src/users/types.ts +++ /dev/null @@ -1,58 +0,0 @@ -export interface IUserAccount { - account_id: string; - profile: Record; -} - -export interface IUser { - accounts: IUserAccount[]; - profile: Record; -} - -export type ChannelClassification = - | "direct_message" - | "email" - | "push" - | "sms" - | "webhook" - | "inbox"; - -export interface ITopicPreference { - /** - * Should contain unique items. - */ - custom_routing?: ChannelClassification[]; - default_status: "OPTED_IN" | "OPTED_OUT"; - has_custom_routing?: boolean; - status: "OPTED_IN" | "OPTED_OUT"; - topic_id: string; - topic_name: string; -} - -interface IPagingInfo { - cursor: string; - more: boolean; -} - -export interface IGetTopicPreferencesResponse { - topic: ITopicPreference; -} - -export interface IGetTopicsResponse { - paging: IPagingInfo; - items: ITopicPreference[]; -} - -export interface ICourierClientUsers { - getUserPreferenceByTopic: ( - userId: string, - topicId: string - ) => Promise; - getUserPreferenceByTopics: (userId: string) => Promise; - put: (id: string, user: IUser) => Promise; - putAccounts: (id: string, accounts: IUserAccount[]) => Promise; - putUserPreferenceByTopic: ( - userId: string, - topicId: string, - topic: Omit - ) => Promise; -} diff --git a/tsconfig.json b/tsconfig.json index 44aa042..e65fa53 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,20 @@ { - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "declaration": true, - "outDir": "./lib", - "strict": true, - "lib": ["es2015", "es2016", "dom"], - "resolveJsonModule": true - }, - "include": ["src"], - "exclude": ["node_modules", "**/__tests__/*"] -} + "compilerOptions": { + "extendedDiagnostics": true, + "strict": true, + "target": "ES6", + "module": "CommonJS", + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "noUnusedParameters": true, + "outDir": "dist", + "rootDir": "src", + "baseUrl": "src" + }, + "include": [ + "src" + ], + "exclude": [] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 267f369..0000000 --- a/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["tslint:recommended", "tslint-config-prettier"] -} diff --git a/yarn.lock b/yarn.lock index 909efa7..fa08e94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,3446 +2,183 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/core@^7.1.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.4.tgz#780e8b83e496152f8dd7df63892b2e052bf1d51d" - integrity sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.10.4" - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.10.4", "@babel/generator@^7.4.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.4.tgz#e49eeed9fe114b62fa5b181856a43a5e32f5f243" - integrity sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng== - dependencies: - "@babel/types" "^7.10.4" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-get-function-arity@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-member-expression-to-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz#7cd04b57dfcf82fce9aeae7d4e4452fa31b8c7c4" - integrity sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-module-transforms@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz#ca1f01fdb84e48c24d7506bb818c961f1da8805d" - integrity sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - lodash "^4.17.13" - -"@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - -"@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== - dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-split-export-declaration@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1" - integrity sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/helpers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== - dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.4.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.4.tgz#9eedf27e1998d87739fb5028a5120557c06a1a64" - integrity sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA== - -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/template@^7.10.4", "@babel/template@^7.4.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.4.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.4.tgz#e642e5395a3b09cc95c8e74a27432b484b697818" - integrity sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" - -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.3.0", "@babel/types@^7.4.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.4.tgz#369517188352e18219981efd156bfdb199fff1ee" - integrity sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - -"@jest/console@^24.7.1", "@jest/console@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" - integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== - dependencies: - "@jest/source-map" "^24.9.0" - chalk "^2.0.1" - slash "^2.0.0" - -"@jest/core@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" - integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== - dependencies: - "@jest/console" "^24.7.1" - "@jest/reporters" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-changed-files "^24.9.0" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-resolve-dependencies "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - jest-watcher "^24.9.0" - micromatch "^3.1.10" - p-each-series "^1.0.0" - realpath-native "^1.1.0" - rimraf "^2.5.4" - slash "^2.0.0" - strip-ansi "^5.0.0" - -"@jest/environment@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" - integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== - dependencies: - "@jest/fake-timers" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - -"@jest/fake-timers@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" - integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== - dependencies: - "@jest/types" "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - -"@jest/reporters@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" - integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - exit "^0.1.2" - glob "^7.1.2" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.1" - istanbul-reports "^2.2.6" - jest-haste-map "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" - node-notifier "^5.4.2" - slash "^2.0.0" - source-map "^0.6.0" - string-length "^2.0.0" - -"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" - integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.1.15" - source-map "^0.6.0" - -"@jest/test-result@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" - integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== - dependencies: - "@jest/console" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/istanbul-lib-coverage" "^2.0.0" - -"@jest/test-sequencer@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" - integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== - dependencies: - "@jest/test-result" "^24.9.0" - jest-haste-map "^24.9.0" - jest-runner "^24.9.0" - jest-runtime "^24.9.0" - -"@jest/transform@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" - integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^24.9.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.15" - jest-haste-map "^24.9.0" - jest-regex-util "^24.9.0" - jest-util "^24.9.0" - micromatch "^3.1.10" - pirates "^4.0.1" - realpath-native "^1.1.0" - slash "^2.0.0" - source-map "^0.6.1" - write-file-atomic "2.4.1" - -"@jest/types@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" - integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^13.0.0" - -"@types/babel__core@^7.1.0": - version "7.1.9" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d" - integrity sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.1" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" - integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" - integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.13" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.13.tgz#1874914be974a492e1b4cb00585cabb274e8ba18" - integrity sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ== - dependencies: - "@babel/types" "^7.3.0" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" - integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" - integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== - dependencies: - "@types/istanbul-lib-coverage" "*" - "@types/istanbul-lib-report" "*" - -"@types/jest@^24.0.15": - version "24.9.1" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" - integrity sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q== - dependencies: - jest-diff "^24.3.0" - -"@types/node@^12.6.2": - version "12.12.48" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.48.tgz#4135f064eeed9fcfb4756deea5ba2caa11603391" - integrity sha512-m3Nmo/YaDUfYzdCQlxjF5pIy7TNyDTAJhIa//xtHcF0dlgYIBKULKnmloCPtByDxtZXrWV8Pge1AKT6/lRvVWg== - -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== - -"@types/yargs-parser@*": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" - integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== - -"@types/yargs@^13.0.0": - version "13.0.9" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.9.tgz#44028e974343c7afcf3960f1a2b1099c39a7b5e1" - integrity sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg== - dependencies: - "@types/yargs-parser" "*" - -abab@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" - integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== - -acorn-globals@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== - dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" - -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== - -acorn@^5.5.3: - version "5.7.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" - integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== - -acorn@^6.0.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== - -ajv@^6.5.5: - version "6.12.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" - integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.0.0, ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" +"@types/node@17.0.33": + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.33.tgz#3c1879b276dc63e73030bb91165e62a4509cd506" + integrity sha512-miWq2m2FiQZmaHfdZNcbpp9PuXg34W5JZ5CrJ/BaS70VuhoJENBEQybeiYSaPBRNq6KQGnjfEnc/F3PN++D+XQ== -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== +"@types/qs@6.9.8": + version "6.9.8" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" + integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +"@types/url-join@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/url-join/-/url-join-4.0.1.tgz#4989c97f969464647a8586c7252d97b449cdc045" + integrity sha512-wDXw9LEEUHyV+7UWy7U315nrJGJ7p1BzaCxDpEoLr789Dk1WDVMMlf3iBfbG2F8NdWnYyFbtTxUn2ZNbm1Q4LQ== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" - integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== - -babel-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" - integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== - dependencies: - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.9.0" - chalk "^2.4.2" - slash "^2.0.0" - -babel-plugin-istanbul@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" - integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - find-up "^3.0.0" - istanbul-lib-instrument "^3.3.0" - test-exclude "^5.2.3" - -babel-plugin-jest-hoist@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" - integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== - dependencies: - "@types/babel__traverse" "^7.0.6" - -babel-preset-jest@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" - integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.9.0" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" - -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@1.x, buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== +axios@0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" + follow-redirects "^1.14.9" + form-data "^4.0.0" -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== +call-bind@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commander@^2.12.1: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -convert-source-map@^1.4.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cross-fetch@^3.0.4, cross-fetch@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== - dependencies: - node-fetch "2.6.7" - -cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== - dependencies: - cssom "0.3.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -data-urls@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== - dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" - -debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diff-sequences@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" - integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== +follow-redirects@^1.14.9: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: - is-arrayish "^0.2.1" + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" -escodegen@^1.9.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + get-intrinsic "^1.1.3" -estraverse@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + get-intrinsic "^1.2.2" -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== -expect@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" - integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== - dependencies: - "@jest/types" "^24.9.0" - ansi-styles "^3.2.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-regex-util "^24.9.0" +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== dependencies: - is-extendable "^0.1.0" + function-bind "^1.1.2" -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" +js-base64@3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.2.tgz#816d11d81a8aff241603d19ce5761e13e41d7745" + integrity sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ== -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" + mime-db "1.52.0" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= +object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== - dependencies: - bser "2.1.1" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +prettier@2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= +qs@6.11.2: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" + side-channel "^1.0.4" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== dependencies: - locate-path "^3.0.0" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" +typescript@4.6.4: + version "4.6.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" + integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== - dependencies: - whatwg-encoding "^1.0.1" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" - integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" - integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== - dependencies: - has-symbols "^1.0.1" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== - -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" - -istanbul-lib-report@^2.0.4: - version "2.0.8" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" - integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== - dependencies: - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - supports-color "^6.1.0" - -istanbul-lib-source-maps@^3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" - integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^2.0.5" - make-dir "^2.1.0" - rimraf "^2.6.3" - source-map "^0.6.1" - -istanbul-reports@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" - integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== - dependencies: - html-escaper "^2.0.0" - -jest-changed-files@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" - integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== - dependencies: - "@jest/types" "^24.9.0" - execa "^1.0.0" - throat "^4.0.0" - -jest-cli@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" - integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== - dependencies: - "@jest/core" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - exit "^0.1.2" - import-local "^2.0.0" - is-ci "^2.0.0" - jest-config "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^13.3.0" - -jest-config@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" - integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== - dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.9.0" - "@jest/types" "^24.9.0" - babel-jest "^24.9.0" - chalk "^2.0.1" - glob "^7.1.1" - jest-environment-jsdom "^24.9.0" - jest-environment-node "^24.9.0" - jest-get-type "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - micromatch "^3.1.10" - pretty-format "^24.9.0" - realpath-native "^1.1.0" - -jest-diff@^24.3.0, jest-diff@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" - integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-docblock@^24.3.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" - integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== - dependencies: - detect-newline "^2.1.0" - -jest-each@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" - integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== - dependencies: - "@jest/types" "^24.9.0" - chalk "^2.0.1" - jest-get-type "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - -jest-environment-jsdom@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" - integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - jsdom "^11.5.1" - -jest-environment-node@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" - integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== - dependencies: - "@jest/environment" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - jest-util "^24.9.0" - -jest-fetch-mock@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz#31749c456ae27b8919d69824f1c2bd85fe0a1f3b" - integrity sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw== - dependencies: - cross-fetch "^3.0.4" - promise-polyfill "^8.1.3" - -jest-get-type@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" - integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== - -jest-haste-map@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" - integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== - dependencies: - "@jest/types" "^24.9.0" - anymatch "^2.0.0" - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.9.0" - micromatch "^3.1.10" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^1.2.7" - -jest-jasmine2@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" - integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== - dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - co "^4.6.0" - expect "^24.9.0" - is-generator-fn "^2.0.0" - jest-each "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-runtime "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - pretty-format "^24.9.0" - throat "^4.0.0" - -jest-leak-detector@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" - integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== - dependencies: - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-matcher-utils@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" - integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== - dependencies: - chalk "^2.0.1" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - pretty-format "^24.9.0" - -jest-message-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" - integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" - -jest-mock@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" - integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== - dependencies: - "@jest/types" "^24.9.0" - -jest-pnp-resolver@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== - -jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" - integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== - -jest-resolve-dependencies@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" - integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== - dependencies: - "@jest/types" "^24.9.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.9.0" - -jest-resolve@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" - integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== - dependencies: - "@jest/types" "^24.9.0" - browser-resolve "^1.11.3" - chalk "^2.0.1" - jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" - -jest-runner@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" - integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - chalk "^2.4.2" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-docblock "^24.3.0" - jest-haste-map "^24.9.0" - jest-jasmine2 "^24.9.0" - jest-leak-detector "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - jest-runtime "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.6.0" - source-map-support "^0.5.6" - throat "^4.0.0" - -jest-runtime@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" - integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.9.0" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - chalk "^2.0.1" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.9.0" - jest-haste-map "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.9.0" - jest-snapshot "^24.9.0" - jest-util "^24.9.0" - jest-validate "^24.9.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^13.3.0" - -jest-serializer@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" - integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== - -jest-snapshot@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" - integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== - dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^24.9.0" - chalk "^2.0.1" - expect "^24.9.0" - jest-diff "^24.9.0" - jest-get-type "^24.9.0" - jest-matcher-utils "^24.9.0" - jest-message-util "^24.9.0" - jest-resolve "^24.9.0" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - pretty-format "^24.9.0" - semver "^6.2.0" - -jest-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" - integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== - dependencies: - "@jest/console" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/source-map" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - -jest-validate@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" - integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== - dependencies: - "@jest/types" "^24.9.0" - camelcase "^5.3.1" - chalk "^2.0.1" - jest-get-type "^24.9.0" - leven "^3.1.0" - pretty-format "^24.9.0" - -jest-watcher@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" - integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== - dependencies: - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/yargs" "^13.0.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.9.0" - string-length "^2.0.0" - -jest-worker@^24.6.0, jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== - dependencies: - merge-stream "^2.0.0" - supports-color "^6.1.0" - -jest@^24.8.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" - integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== - dependencies: - import-local "^2.0.0" - jest-cli "^24.9.0" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" - xml-name-validator "^3.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@2.x, json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - -lodash@^4.17.13, lodash@^4.17.15: - version "4.17.19" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" - integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-error@1.x: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= - dependencies: - tmpl "1.0.x" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.x, mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -nan@^2.12.1: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-notifier@^5.4.2: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== - dependencies: - growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -nwsapi@^2.0.7: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - 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" - -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pirates@^4.0.1: +url-join@4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prettier@^1.18.2: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -pretty-format@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" - integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== - dependencies: - "@jest/types" "^24.9.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" - -promise-polyfill@^8.1.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.3.tgz#2edc7e4b81aff781c88a0d577e5fe9da822107c6" - integrity sha512-Og0+jCRQetV84U8wVjMNccfGCnMQ9mGs9Hv78QFe+pSDD3gWTpz0y+1QCuxy5d/vBFuZ3iwP2eycAkvqIMPmWg== - -prompts@^2.0.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068" - integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.4" - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -react-is@^16.8.4: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== - dependencies: - util.promisify "^1.0.0" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -request-promise-core@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" - integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== - dependencies: - lodash "^4.17.15" - -request-promise-native@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" - integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== - dependencies: - request-promise-core "1.1.3" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.87.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - -resolve@1.x, resolve@^1.10.0, resolve@^1.3.2: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@^2.5.4, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.0.0, semver@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -sisteransi@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.5.6: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.0, source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= - dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -symbol-tree@^3.2.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" - -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= - dependencies: - punycode "^2.1.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -ts-jest@^24.0.2: - version "24.3.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" - integrity sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ== - dependencies: - bs-logger "0.x" - buffer-from "1.x" - fast-json-stable-stringify "2.x" - json5 "2.x" - lodash.memoize "4.x" - make-error "1.x" - mkdirp "0.x" - resolve "1.x" - semver "^5.5" - yargs-parser "10.x" - -tslib@^1.8.0, tslib@^1.8.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== - -tslint-config-prettier@^1.18.0: - version "1.18.0" - resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" - integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== - -tslint@^5.18.0: - version "5.20.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" - integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg== - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - mkdirp "^0.5.1" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.29.0" - -tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -typescript@^3.5.3: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util.promisify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -w3c-hr-time@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.9, which@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" - -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yargs-parser@10.x: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - -yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs@^13.3.0: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - 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" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==