diff --git a/.eslintignore b/.eslintignore index 31cea6480..479c3a36f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ /node_modules coverage dist +tsconfig.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 1dd335bc6..3f4cdf4ed 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -46,7 +46,7 @@ module.exports = { } }, { - files: './packages/user-client/**/*.{ts,tsx}', + files: './packages/{project,user}-client/**/*.{ts,tsx}', rules: { '@typescript-eslint/no-empty-interface': 'off', '@typescript-eslint/no-unused-vars': 'off', diff --git a/example/package.json b/example/package.json index 1272ae7af..7687966ac 100644 --- a/example/package.json +++ b/example/package.json @@ -21,6 +21,7 @@ "@magicbell/embeddable": "../packages/embeddable", "@magicbell/in-app": "../packages/in-app", "@magicbell/magicbell-react": "../packages/react", + "@magicbell/project-client": "../packages/project-client", "@magicbell/react-headless": "../packages/react-headless", "@magicbell/user-client": "../packages/user-client", "@magicbell/utils": "../packages/utils", diff --git a/package.json b/package.json index 8ffafb4b6..943e376ce 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "start:example": "yarn --cwd example && yarn --cwd example start", "start:storybook": "cross-env NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6006", "start:playground": "yarn --cwd packages/playground start", - "codegen": "turbo run codegen --parallel --no-cache", + "codegen": "turbo run codegen --concurrency 1 --no-cache", "build": "turbo run build", "build:example": "yarn --cwd example && yarn --cwd example build", "build:storybook": "build-storybook", @@ -59,6 +59,7 @@ "@testing-library/user-event": "^14.5.2", "@tsconfig/create-react-app": "^2.0.5", "@types/jest": "^29.5.10", + "@types/node": "^20.14.8", "@types/react": "^18.2.42", "@types/react-dom": "^18.2.17", "@typescript-eslint/eslint-plugin": "^7.16.0", diff --git a/packages/codegen/package.json b/packages/codegen/package.json index f691b3f4a..914134f19 100644 --- a/packages/codegen/package.json +++ b/packages/codegen/package.json @@ -41,7 +41,7 @@ "dependencies": { "@apidevtools/swagger-parser": "^10.1.0", "ast-types": "^0.14.2", - "axios": "^1.0.0", + "axios": "^1.7.4", "eslint": "^8.57.0", "json-schema-merge-allof": "^0.8.1", "json5": "^2.2.3", diff --git a/packages/project-client/.gitignore b/packages/project-client/.gitignore new file mode 100644 index 000000000..8313d20b7 --- /dev/null +++ b/packages/project-client/.gitignore @@ -0,0 +1,2 @@ +magicbell-client.swagger.json +output diff --git a/packages/project-client/LICENSE b/packages/project-client/LICENSE new file mode 100644 index 000000000..2b3bdb112 --- /dev/null +++ b/packages/project-client/LICENSE @@ -0,0 +1,194 @@ +LICENSE AGREEMENT + +By downloading or using this software made available by MagicBell, Inc. +("MagicBell") or any documentation that accompanies it (collectively, the +"Software"), you and the company or entity that you represent (collectively, +"you" or "your") are consenting to be bound by and are becoming a party to this +License Agreement (this "Agreement"). You hereby represent and warrant that you +are authorized and lawfully able to bind such company or entity that you +represent to this Agreement. If you do not have such authority or do not agree +to all of the terms of this Agreement, you may not download or use the Software. + +LICENSE GRANT. Subject to your compliance with and the terms and conditions of +this Agreement, MagicBell, Inc. ("MagicBell") hereby grants you a limited, +personal, non-exclusive, non-sublicensable, non-transferable license to (a) use, +install, and run the Software solely to create and display a customized user +interface in connection with your internal use of MagicBell’s embeddable +notification inbox product (the "MagicBell Product"); and (b) modify the +Software (the results thereof, "Modifications") solely to customize your user +interface in connection with your use of the MagicBell Product; (c) compile and +execute object code versions of the Software (including as incorporating your +Modifications) solely to use internally your customized MagicBell Product user +interface; and (d) make electronic copies of the Software and any Modifications +as required for backup or archival purposes. You acknowledge that your use of +any components provided with the Software that are licensed under an open source +software license ("Open Source Components") are not part of the Software +licensed hereunder and are subject to and governed solely by the terms of the +applicable license(s) for that software, and not by this Agreement. + +RESTRICTIONS. You are responsible for all activities that occur in connection +with the Software. Except as otherwise expressly authorized by MagicBell, you +may not directly or indirectly: (a) sublicense, sell, assign, distribute, +modify, make derivative works of, make any commercial use of, use on a timeshare +or service bureau basis, use for the benefit of a third party or otherwise +commercialize the Software (or any Modifications); (b) allow third parties to +access or use the source code of the Software (or any Modifications); use the +Software (or any Modifications) to create or facilitate the creation of, or +otherwise incorporate any portion of the Software (or any Modifications) in, +any product or service that is competitive with the MagicBell Product; (c) use +the Software (or any Modifications) to perform comparisons or other +"benchmarking" activities; (d) remove any proprietary notices or branding from +the Software; and/or (e) use the Software (or any Modifications) in violation +of any applicable laws or regulations or outside of the scope of the license +granted in Section 1. You shall ensure that there is no direct or indirect use +of, or sharing of, the Software (or any Modifications), or other information +based upon or derived from the Software (or any Modifications) to develop such +competitive products. Without derogating the generality of the foregoing, +development of any competitive product shall include having direct or indirect +access to, supervising, consulting or assisting in the development of, or +product any specifications, documentations, object code or source code for, all +or part of any competitive product. + +AUTHORIZED USERS. Subject to the rights granted to you under this Agreement, +you may permit your employees, contractors and agents to exercise the rights +granted herein in accordance with the Agreement solely on behalf of you to +provide services to you, provided that you are liable for all acts and omissions +thereof to the extent that any such acts and omissions, if performed by you, +would constitute a breach or, or otherwise giver right to liability to you, +under this Agreement. You represent and warrant that you shall not permit any +third party to access or use the Software (or any Modifications) except as +expressly permitted under this Agreement. + +OPEN SOURCE COMPONENTS. You and your authorized users shall not use any Open +Source Components in connection with the Software or any Modifications or in any +way that could subject the Software to an open source license. + +OWNERSHIP. As between MagicBell and you, MagicBell or its licensors shall own +and retain all proprietary rights, including all patent, copyright, trade +secret, trademark and other intellectual property rights, in and to the Software +and any Modifications and you hereby irrevocably transfer, convey and assign to +MagicBell all right, title, and interest in any Modifications regardless of +whether such Modifications are actually delivered to MagicBell. MagicBell shall +have the exclusive right to apply for or register any patents, mask work rights, +copyrights, and such other proprietary protections with respect thereto. You +acknowledge that the license granted under Section 2 of this Agreement does not +provide you with title or ownership to the Software or any such Modifications, +but only a right of limited use under the terms and conditions of this +Agreement. + +You represent and warrant to MagicBell that you have the full right, and have +obtained all consents, approvals, authorizations, permits and licenses required +or necessary, to allow you to grant to MagicBell the assignments and rights +provided for herein and otherwise fully perform this Agreement (and have written +enforceable agreements with all persons necessary to give you the rights to do +the foregoing). + +LIMITATIONS ON MODIFICATIONS TO SOFTWARE. Notwithstanding any provision in this +Agreement, Modifications may only be created and used by you as permitted by +this Agreement. You are solely responsible for all use of Modifications and, +without limiting anything herein, MagicBell will have no liability with respect +to Modifications. You will not assert against MagicBell, its affiliates or +their customers, direct or indirect, agents and contractors, in any way, any +intellectual property rights that you may obtain relating to any Modifications +for the Software. + +SUPPORT AND UPGRADES. If MagicBell provides you with any upgrades, patches, +enhancements or fixes for the Software that it makes generally available free +of charge in connection with the Software, then the items that are provided will +become part of the Software and subject to this Agreement. MagicBell shall have +no obligation, however, under this Agreement or otherwise to provide any +upgrades, patches, enhancements, fixes or any other support to you for the +Software. + +WARRANTY AND DISCLAIMER. USE OF THE SOFTWARE IS ENTIRELY AT YOUR OWN RISK. +MAGICBELL PROVIDES THE SOFTWARE "AS IS" AND "AS AVAILABLE" WITHOUT ANY WARRANTY +OF ANY KIND AND HEREBY DISCLAIMS, FOR ITSELF AND ITS LICENSORS AND SUPPLIERS, +ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, PERFORMANCE, ACCURACY, +RELIABILITY, NON-INFRINGEMENT, AND WARRANTIES ARISING OUT OF COURSE OF +PERFORMANCE, COURSE OF DEALING OR USAGE IN TRADE. MAGICBELL DOES NOT WARRANT +THAT THE SOFTWARE IS ERROR-FREE, WILL FUNCTION WITHOUT INTERRUPTION, WILL MEET +ANY SPECIFIC NEED THAT YOU MAY HAVE, THAT ALL DEFECTS WILL BE CORRECTED OR THAT +IT IS SUFFICIENTLY DOCUMENTED TO BE USEABLE BY YOU. THIS DISCLAIMER OF WARRANTY +CONSTITUTES AN ESSENTIAL PART OF THE AGREEMENT. + +LIMITATION OF LIABILITY. NOTWITHSTANDING ANYTHING ELSE, UNDER NO CIRCUMSTANCES +SHALL MAGICBELL OR ITS LICENSORS OR SUPPLIERS, BE LIABLE TO YOU OR ANY OTHER +PERSON WITH RESPECT TO THE SUBJECT MATTER OF THIS AGREEMENT UNDER ANY CONTRACT, +TORT, NEGLIGENCE, STRICT LIABILITY, WARRANTY OR OTHER LEGAL OR EQUITABLE THEORY, +FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND +INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, +LOSS OF DATA, COSTS OF PROCUREMENT OF SUBSTITUTE GOODS, SERVICES, TECHNOLOGY OR +RIGHTS, INTERRUPTION OF BUSINESS, ACCURACY OF RESULTS, COMPUTER FAILURE OR +MALFUNCTION, OR OTHER DAMAGES IN EXCESS OF ONE HUNDRED DOLLARS (US$100), EVEN IF +AWARE OF THE POSSIBILITY OF SUCH DAMAGES. + +BASIS OF BARGAIN. YOU AND MAGICBELL EACH RECOGNIZE AND AGREE THAT THE WARRANTY +DISCLAIMERS AND LIABILITY AND REMEDY LIMITATIONS IN THIS AGREEMENT ARE MATERIAL, +BARGAINED FOR BASES FOR THIS AGREEMENT AND THAT THEY HAVE BEEN TAKEN INTO +ACCOUNT AND REFLECTED IN DETERMINING THE CONSIDERATION TO BE GIVEN BY EACH PARTY +UNDER THIS AGREEMENT AND IN THE DECISION BY EACH PARTY TO ENTER INTO THIS +AGREEMENT. + +TERM AND TERMINATION. The term of this Agreement will begin when the Software +is downloaded or accessed and shall continue until terminated pursuant to this +section. Either party may terminate this Agreement and the licenses granted +herein at any time. MagicBell may terminate this Agreement and the licenses +granted in this Agreement immediately if you breach any provision of this +Agreement, including but not limited to, if you are or become a competitor of +the MagicBell or make or sell any competitive products, in additional to all +other available remedies. Upon termination, all of your rights and licenses +under this Agreement cease to exist, including, for the avoidance of doubt, any +rights in any Modifications you may have developed; you must cease exercise of +the licensed rights herein; you must destroy or remove from all hard drives, +networks, and storage media, all copies and extracts of the Software and all +Modifications in your possession or control; and this sentence, all remedies for +breach, and Sections 2 through 10 and 12 through 14 shall survive any +termination of this Agreement. Any continued use of the Software by you or +attempt by you to exercise any rights under this Agreement after this Agreement +has been terminated will be considered copyright infringement and you will be +subject to all applicable remedies. + +FEEDBACK. You agree that MagicBell may collect or you may provide to MagicBell +comments, feedback, suggestions or other information related to the Software, or +modifications, corrections, improvements, derivatives and extensions to the +Software (collectively, "Feedback"), and you hereby grant MagicBell the +perpetual and irrevocable right (and the perpetual and irrevocable right to +permit others) to use and fully exercise and exploit the Feedback in any manner +to improve, develop and otherwise exploit applications, services or technology, +and otherwise in connection with its business during and after the term of this +Agreement. + +GOVERNMENT RESTRICTED RIGHTS. All software, technology, and accompanying +documentation are deemed to be "commercial computer software" and "commercial +computer software documentation," respectively, pursuant to DFAR Section +227.7202 and FAR Section 12.212, as applicable. Any use, modification, +reproduction, release, performance, display, transfer or disclosure of the +Software and accompanying documentation by any agency, department or other +entity of any government, shall be governed solely by the terms of this +Agreement and shall be prohibited except to the extent expressly permitted by +the terms herein or in a writing signed by an authorized signatory on behalf of +MagicBell. No other rights are granted. + +MISCELLANEOUS. You may not assign or transfer this Agreement, by operation of +law or otherwise, or any of your rights under this Agreement (including any +license rights granted to you), to any third party without MagicBell’s prior +written consent, which consent will not be unreasonably withheld or delayed. + +MagicBell may assign this Agreement, without consent, including, but not limited +to, affiliates or any successor to all or substantially all of its business or +assets to which this Agreement relates, whether by merger, sale of assets, sale +of stock, reorganization or otherwise. Any attempted assignment or transfer in +violation of the foregoing will be null and void. This Agreement contains the +complete agreement between you and MagicBell regarding the Software and +supersedes all prior agreements and representations between you and MagicBell +regarding the Software. This Agreement may only be amended and any provision +may only be waived by a writing executed by both parties. You agree to promptly +provide MagicBell with all information and documentation that MagicBell requests +to verify your compliance with this Agreement. If any provision of this +Agreement is held to be invalid or unenforceable, it shall be reformed to the +limited extent necessary to make it enforceable. This Agreement shall be +governed by and construed in accordance with the laws of California, without +regard to its conflicts of laws provisions. California will have exclusive +jurisdiction and venue under this Agreement. The United Nations Convention on +Contracts for the International Sale of Goods does not apply to this Agreement. diff --git a/packages/project-client/README.md b/packages/project-client/README.md new file mode 100644 index 000000000..e6d18be97 --- /dev/null +++ b/packages/project-client/README.md @@ -0,0 +1,134 @@ +# Client TypeScript SDK 0.1.0 + +Welcome to the Client SDK documentation. This guide will help you get started with integrating and using the Client SDK in your project. + +## Versions + +- API version: `2.0.0` +- SDK version: `0.1.0` + +## About the API + +OpenAPI 3.1.0 Specification for MagicBell API. + +## Table of Contents + +- [Setup & Configuration](#setup--configuration) + - [Supported Language Versions](#supported-language-versions) + - [Installation](#installation) +- [Authentication](#authentication) + - [Access Token Authentication](#access-token-authentication) +- [Setting a Custom Timeout](#setting-a-custom-timeout) +- [Services](#services) +- [Models](#models) + +# Setup & Configuration + +## Supported Language Versions + +This SDK is compatible with the following versions: `TypeScript >= 4.8.4` + +## Installation + +To get started with the SDK, we recommend installing using `npm`: + +```bash +npm install @magicbell/project-client +``` + +## Authentication + +### Access Token Authentication + +The Client API uses an Access Token for authentication. + +This token must be provided to authenticate your requests to the API. + +#### Setting the Access Token + +When you initialize the SDK, you can set the access token as follows: + +```ts +const sdk = new Client({ token: 'YOUR_TOKEN' }); +``` + +If you need to set or update the access token after initializing the SDK, you can use: + +```ts +const sdk = new Client(); +sdk.token = 'YOUR_TOKEN'; +``` + +## Setting a Custom Timeout + +You can set a custom timeout for the SDK's HTTP requests as follows: + +```ts +const client = new Client({ timeout: 10000 }); +``` + +## Services + +The SDK provides various services to interact with the API. + +
+Below is a list of all available services with links to their detailed documentation: + +| Name | +| :------------------------------------------------------------------- | +| [BroadcastsService](documentation/services/BroadcastsService.md) | +| [IntegrationsService](documentation/services/IntegrationsService.md) | +| [JwtService](documentation/services/JwtService.md) | +| [ChannelsService](documentation/services/ChannelsService.md) | + +
+ +## Models + +The SDK includes several models that represent the data structures used in API requests and responses. These models help in organizing and managing the data efficiently. + +
+Below is a list of all available models with links to their detailed documentation: + +| Name | Description | +| :----------------------------------------------------------------------------------------- | :---------- | +| [BroadcastListResponse](documentation/models/BroadcastListResponse.md) | | +| [Broadcast](documentation/models/Broadcast.md) | | +| [ListIntegrationsResponse](documentation/models/ListIntegrationsResponse.md) | | +| [ApnsConfig](documentation/models/ApnsConfig.md) | | +| [FcmConfig](documentation/models/FcmConfig.md) | | +| [GithubConfig](documentation/models/GithubConfig.md) | | +| [InboxConfig](documentation/models/InboxConfig.md) | | +| [MailgunConfig](documentation/models/MailgunConfig.md) | | +| [PingConfig](documentation/models/PingConfig.md) | | +| [SendgridConfig](documentation/models/SendgridConfig.md) | | +| [SesConfig](documentation/models/SesConfig.md) | | +| [SlackConfig](documentation/models/SlackConfig.md) | | +| [StripeConfig](documentation/models/StripeConfig.md) | | +| [TwilioConfig](documentation/models/TwilioConfig.md) | | +| [WebpushConfig](documentation/models/WebpushConfig.md) | | +| [FetchTokensResponse](documentation/models/FetchTokensResponse.md) | | +| [CreateProjectTokenRequest](documentation/models/CreateProjectTokenRequest.md) | | +| [AccessToken](documentation/models/AccessToken.md) | | +| [DiscardTokenResponse](documentation/models/DiscardTokenResponse.md) | | +| [CreateUserTokenRequest](documentation/models/CreateUserTokenRequest.md) | | +| [ArrayWithMetadataOfInboxToken](documentation/models/ArrayWithMetadataOfInboxToken.md) | | +| [InboxTokenWithMetadata](documentation/models/InboxTokenWithMetadata.md) | | +| [DiscardResult](documentation/models/DiscardResult.md) | | +| [ArrayWithMetadataOfApnsToken](documentation/models/ArrayWithMetadataOfApnsToken.md) | | +| [ApnsTokenWithMetadata](documentation/models/ApnsTokenWithMetadata.md) | | +| [ArrayWithMetadataOfFcmToken](documentation/models/ArrayWithMetadataOfFcmToken.md) | | +| [FcmTokenWithMetadata](documentation/models/FcmTokenWithMetadata.md) | | +| [ArrayWithMetadataOfSlackToken](documentation/models/ArrayWithMetadataOfSlackToken.md) | | +| [SlackTokenWithMetadata](documentation/models/SlackTokenWithMetadata.md) | | +| [ArrayWithMetadataOfTeamsToken](documentation/models/ArrayWithMetadataOfTeamsToken.md) | | +| [TeamsTokenWithMetadata](documentation/models/TeamsTokenWithMetadata.md) | | +| [ArrayWithMetadataOfWebPushToken](documentation/models/ArrayWithMetadataOfWebPushToken.md) | | +| [WebPushTokenWithMetadata](documentation/models/WebPushTokenWithMetadata.md) | | +| [InboxToken](documentation/models/InboxToken.md) | | +| [ApnsToken](documentation/models/ApnsToken.md) | | +| [FcmToken](documentation/models/FcmToken.md) | | +| [SlackToken](documentation/models/SlackToken.md) | | +| [WebPushToken](documentation/models/WebPushToken.md) | | + +
diff --git a/packages/project-client/docs/models/AccessToken.md b/packages/project-client/docs/models/AccessToken.md new file mode 100644 index 000000000..1193f6c2f --- /dev/null +++ b/packages/project-client/docs/models/AccessToken.md @@ -0,0 +1,10 @@ +# AccessToken + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| token | string | ✅ | | +| tokenId | string | ✅ | | +| expiresAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ApnsConfig.md b/packages/project-client/docs/models/ApnsConfig.md new file mode 100644 index 000000000..b6006bf14 --- /dev/null +++ b/packages/project-client/docs/models/ApnsConfig.md @@ -0,0 +1,20 @@ +# ApnsConfig + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| appId | string | ✅ | | +| badge | Badge | ✅ | | +| certificate | string | ✅ | | +| keyId | string | ✅ | | +| teamId | string | ✅ | | + +# Badge + +**Properties** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| UNREAD | string | ✅ | "unread" | +| UNSEEN | string | ✅ | "unseen" | diff --git a/packages/project-client/docs/models/ApnsToken.md b/packages/project-client/docs/models/ApnsToken.md new file mode 100644 index 000000000..c7a7ce850 --- /dev/null +++ b/packages/project-client/docs/models/ApnsToken.md @@ -0,0 +1,17 @@ +# ApnsToken + +**Properties** + +| Name | Type | Required | Description | +| :------------- | :---------------------- | :------- | :---------- | +| deviceToken | string | ✅ | | +| installationId | ApnsTokenInstallationId | ❌ | | + +# ApnsTokenInstallationId + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :------------ | +| DEVELOPMENT | string | ✅ | "development" | +| PRODUCTION | string | ✅ | "production" | diff --git a/packages/project-client/docs/models/ApnsTokenWithMetadata.md b/packages/project-client/docs/models/ApnsTokenWithMetadata.md new file mode 100644 index 000000000..dff58f5e2 --- /dev/null +++ b/packages/project-client/docs/models/ApnsTokenWithMetadata.md @@ -0,0 +1,19 @@ +# ApnsTokenWithMetadata + +**Properties** + +| Name | Type | Required | Description | +| :------- | :---------------------------- | :------- | :---------- | +| data | ApnsToken | ✅ | | +| metadata | ApnsTokenWithMetadataMetadata | ✅ | | + +# ApnsTokenWithMetadataMetadata + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ArrayWithMetadataOfApnsToken.md b/packages/project-client/docs/models/ArrayWithMetadataOfApnsToken.md new file mode 100644 index 000000000..802e12a2a --- /dev/null +++ b/packages/project-client/docs/models/ArrayWithMetadataOfApnsToken.md @@ -0,0 +1,27 @@ +# ArrayWithMetadataOfApnsToken + +**Properties** + +| Name | Type | Required | Description | +| :--- | :--------------------------------- | :------- | :---------- | +| data | ArrayWithMetadataOfApnsTokenData[] | ✅ | | + +# ArrayWithMetadataOfApnsTokenData + +**Properties** + +| Name | Type | Required | Description | +| :------- | :------------ | :------- | :---------- | +| data | ApnsToken | ✅ | | +| metadata | DataMetadata2 | ✅ | | + +# DataMetadata2 + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ArrayWithMetadataOfFcmToken.md b/packages/project-client/docs/models/ArrayWithMetadataOfFcmToken.md new file mode 100644 index 000000000..201103a9a --- /dev/null +++ b/packages/project-client/docs/models/ArrayWithMetadataOfFcmToken.md @@ -0,0 +1,27 @@ +# ArrayWithMetadataOfFcmToken + +**Properties** + +| Name | Type | Required | Description | +| :--- | :-------------------------------- | :------- | :---------- | +| data | ArrayWithMetadataOfFcmTokenData[] | ✅ | | + +# ArrayWithMetadataOfFcmTokenData + +**Properties** + +| Name | Type | Required | Description | +| :------- | :------------ | :------- | :---------- | +| data | FcmToken | ✅ | | +| metadata | DataMetadata3 | ✅ | | + +# DataMetadata3 + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ArrayWithMetadataOfInboxToken.md b/packages/project-client/docs/models/ArrayWithMetadataOfInboxToken.md new file mode 100644 index 000000000..a3bd4dda3 --- /dev/null +++ b/packages/project-client/docs/models/ArrayWithMetadataOfInboxToken.md @@ -0,0 +1,27 @@ +# ArrayWithMetadataOfInboxToken + +**Properties** + +| Name | Type | Required | Description | +| :--- | :---------------------------------- | :------- | :---------- | +| data | ArrayWithMetadataOfInboxTokenData[] | ✅ | | + +# ArrayWithMetadataOfInboxTokenData + +**Properties** + +| Name | Type | Required | Description | +| :------- | :------------ | :------- | :---------- | +| data | InboxToken | ✅ | | +| metadata | DataMetadata1 | ✅ | | + +# DataMetadata1 + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ArrayWithMetadataOfSlackToken.md b/packages/project-client/docs/models/ArrayWithMetadataOfSlackToken.md new file mode 100644 index 000000000..e00cd4f62 --- /dev/null +++ b/packages/project-client/docs/models/ArrayWithMetadataOfSlackToken.md @@ -0,0 +1,27 @@ +# ArrayWithMetadataOfSlackToken + +**Properties** + +| Name | Type | Required | Description | +| :--- | :---------------------------------- | :------- | :---------- | +| data | ArrayWithMetadataOfSlackTokenData[] | ✅ | | + +# ArrayWithMetadataOfSlackTokenData + +**Properties** + +| Name | Type | Required | Description | +| :------- | :------------ | :------- | :---------- | +| data | SlackToken | ✅ | | +| metadata | DataMetadata4 | ✅ | | + +# DataMetadata4 + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ArrayWithMetadataOfTeamsToken.md b/packages/project-client/docs/models/ArrayWithMetadataOfTeamsToken.md new file mode 100644 index 000000000..d3b3c426c --- /dev/null +++ b/packages/project-client/docs/models/ArrayWithMetadataOfTeamsToken.md @@ -0,0 +1,27 @@ +# ArrayWithMetadataOfTeamsToken + +**Properties** + +| Name | Type | Required | Description | +| :--- | :---------------------------------- | :------- | :---------- | +| data | ArrayWithMetadataOfTeamsTokenData[] | ✅ | | + +# ArrayWithMetadataOfTeamsTokenData + +**Properties** + +| Name | Type | Required | Description | +| :------- | :------------ | :------- | :---------- | +| data | any | ✅ | | +| metadata | DataMetadata5 | ✅ | | + +# DataMetadata5 + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ArrayWithMetadataOfWebPushToken.md b/packages/project-client/docs/models/ArrayWithMetadataOfWebPushToken.md new file mode 100644 index 000000000..9568193a1 --- /dev/null +++ b/packages/project-client/docs/models/ArrayWithMetadataOfWebPushToken.md @@ -0,0 +1,27 @@ +# ArrayWithMetadataOfWebPushToken + +**Properties** + +| Name | Type | Required | Description | +| :--- | :------------------------------------ | :------- | :---------- | +| data | ArrayWithMetadataOfWebPushTokenData[] | ✅ | | + +# ArrayWithMetadataOfWebPushTokenData + +**Properties** + +| Name | Type | Required | Description | +| :------- | :------------ | :------- | :---------- | +| data | WebPushToken | ✅ | | +| metadata | DataMetadata6 | ✅ | | + +# DataMetadata6 + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/Broadcast.md b/packages/project-client/docs/models/Broadcast.md new file mode 100644 index 000000000..551cd09c8 --- /dev/null +++ b/packages/project-client/docs/models/Broadcast.md @@ -0,0 +1,110 @@ +# Broadcast + +**Properties** + +| Name | Type | Required | Description | +| :--------------- | :-------- | :------- | :---------- | +| recipients | any[] | ✅ | | +| title | string | ✅ | | +| actionUrl | string | ❌ | | +| category | string | ❌ | | +| content | string | ❌ | | +| customAttributes | any | ❌ | | +| overrides | Overrides | ❌ | | +| topic | string | ❌ | | + +# Overrides + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :-------- | :------- | :---------- | +| channels | Channels | ❌ | | +| providers | Providers | ❌ | | + +# Channels + +**Properties** + +| Name | Type | Required | Description | +| :--------- | :--------- | :------- | :---------- | +| email | Email | ❌ | | +| inApp | InApp | ❌ | | +| mobilePush | MobilePush | ❌ | | +| slack | Slack | ❌ | | +| sms | Sms | ❌ | | +| webPush | WebPush | ❌ | | + +# Email + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| actionUrl | string | ❌ | | +| content | string | ❌ | | +| title | string | ❌ | | + +# InApp + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| actionUrl | string | ❌ | | +| content | string | ❌ | | +| title | string | ❌ | | + +# MobilePush + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| actionUrl | string | ❌ | | +| content | string | ❌ | | +| title | string | ❌ | | + +# Slack + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| actionUrl | string | ❌ | | +| content | string | ❌ | | +| title | string | ❌ | | + +# Sms + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| actionUrl | string | ❌ | | +| content | string | ❌ | | +| title | string | ❌ | | + +# WebPush + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| actionUrl | string | ❌ | | +| content | string | ❌ | | +| title | string | ❌ | | + +# Providers + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :--- | :------- | :---------- | +| amazonSes | any | ❌ | | +| android | any | ❌ | | +| ios | any | ❌ | | +| mailgun | any | ❌ | | +| postmark | any | ❌ | | +| sendgrid | any | ❌ | | +| slack | any | ❌ | | diff --git a/packages/project-client/docs/models/BroadcastListResponse.md b/packages/project-client/docs/models/BroadcastListResponse.md new file mode 100644 index 000000000..39fe994fd --- /dev/null +++ b/packages/project-client/docs/models/BroadcastListResponse.md @@ -0,0 +1,9 @@ +# BroadcastListResponse + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :---------- | :------- | :--------------------------- | +| currentPage | number | ✅ | Number of the page returned. | +| perPage | number | ✅ | Number of entities per page. | +| broadcasts | Broadcast[] | ✅ | | diff --git a/packages/project-client/docs/models/CreateProjectTokenRequest.md b/packages/project-client/docs/models/CreateProjectTokenRequest.md new file mode 100644 index 000000000..c5884cd66 --- /dev/null +++ b/packages/project-client/docs/models/CreateProjectTokenRequest.md @@ -0,0 +1,8 @@ +# CreateProjectTokenRequest + +**Properties** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :----------------------------------------------------- | +| name | string | ✅ | The name of the token. | +| expiry | number | ❌ | The duration for which the token is valid (in seconds) | diff --git a/packages/project-client/docs/models/CreateUserTokenRequest.md b/packages/project-client/docs/models/CreateUserTokenRequest.md new file mode 100644 index 000000000..6d214de46 --- /dev/null +++ b/packages/project-client/docs/models/CreateUserTokenRequest.md @@ -0,0 +1,10 @@ +# CreateUserTokenRequest + +**Properties** + +| Name | Type | Required | Description | +| :--------- | :----- | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| email | string | ❌ | The user's email. | +| expiry | number | ❌ | The duration for which the token is valid (in seconds) | +| externalId | string | ❌ | A unique string that MagicBell can utilize to identify the user uniquely. We recommend setting this attribute to the ID of the user in your database. Provide the external id if the user's email is unavailable. | +| name | string | ❌ | The name of the token. | diff --git a/packages/project-client/docs/models/DiscardResult.md b/packages/project-client/docs/models/DiscardResult.md new file mode 100644 index 000000000..083d20e7d --- /dev/null +++ b/packages/project-client/docs/models/DiscardResult.md @@ -0,0 +1,8 @@ +# DiscardResult + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| discardedAt | string | ❌ | | +| id | string | ❌ | | diff --git a/packages/project-client/docs/models/DiscardTokenResponse.md b/packages/project-client/docs/models/DiscardTokenResponse.md new file mode 100644 index 000000000..fda165f56 --- /dev/null +++ b/packages/project-client/docs/models/DiscardTokenResponse.md @@ -0,0 +1,8 @@ +# DiscardTokenResponse + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| discardedAt | string | ✅ | | +| tokenId | string | ✅ | | diff --git a/packages/project-client/docs/models/FcmConfig.md b/packages/project-client/docs/models/FcmConfig.md new file mode 100644 index 000000000..d5fe72a5e --- /dev/null +++ b/packages/project-client/docs/models/FcmConfig.md @@ -0,0 +1,25 @@ +# FcmConfig + +**Properties** + +| Name | Type | Required | Description | +| :---------------------- | :----- | :------- | :---------- | +| authProviderX509CertUrl | string | ✅ | | +| authUri | string | ✅ | | +| clientEmail | string | ✅ | | +| clientId | string | ✅ | | +| clientX509CertUrl | string | ✅ | | +| privateKey | string | ✅ | | +| privateKeyId | string | ✅ | | +| projectId | string | ✅ | | +| tokenUri | string | ✅ | | +| type | Type\_ | ✅ | | +| universeDomain | string | ✅ | | + +# Type\_ + +**Properties** + +| Name | Type | Required | Description | +| :------------- | :----- | :------- | :---------------- | +| SERVICEACCOUNT | string | ✅ | "service_account" | diff --git a/packages/project-client/docs/models/FcmToken.md b/packages/project-client/docs/models/FcmToken.md new file mode 100644 index 000000000..b4548ec28 --- /dev/null +++ b/packages/project-client/docs/models/FcmToken.md @@ -0,0 +1,17 @@ +# FcmToken + +**Properties** + +| Name | Type | Required | Description | +| :------------- | :--------------------- | :------- | :---------- | +| deviceToken | string | ✅ | | +| installationId | FcmTokenInstallationId | ❌ | | + +# FcmTokenInstallationId + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :------------ | +| DEVELOPMENT | string | ✅ | "development" | +| PRODUCTION | string | ✅ | "production" | diff --git a/packages/project-client/docs/models/FcmTokenWithMetadata.md b/packages/project-client/docs/models/FcmTokenWithMetadata.md new file mode 100644 index 000000000..554e9832e --- /dev/null +++ b/packages/project-client/docs/models/FcmTokenWithMetadata.md @@ -0,0 +1,19 @@ +# FcmTokenWithMetadata + +**Properties** + +| Name | Type | Required | Description | +| :------- | :--------------------------- | :------- | :---------- | +| data | FcmToken | ✅ | | +| metadata | FcmTokenWithMetadataMetadata | ✅ | | + +# FcmTokenWithMetadataMetadata + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/FetchTokensResponse.md b/packages/project-client/docs/models/FetchTokensResponse.md new file mode 100644 index 000000000..0d8b8003f --- /dev/null +++ b/packages/project-client/docs/models/FetchTokensResponse.md @@ -0,0 +1,18 @@ +# FetchTokensResponse + +**Properties** + +| Name | Type | Required | Description | +| :----- | :------- | :------- | :---------- | +| tokens | Tokens[] | ✅ | | + +# Tokens + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| expiresAt | string | ❌ | | +| id | string | ❌ | | +| name | string | ❌ | | diff --git a/packages/project-client/docs/models/GithubConfig.md b/packages/project-client/docs/models/GithubConfig.md new file mode 100644 index 000000000..e884bcf78 --- /dev/null +++ b/packages/project-client/docs/models/GithubConfig.md @@ -0,0 +1,7 @@ +# GithubConfig + +**Properties** + +| Name | Type | Required | Description | +| :------------------- | :----- | :------- | :--------------------------------------------------------- | +| webhookSigningSecret | string | ✅ | The signing secret to verify incoming requests from Stripe | diff --git a/packages/project-client/docs/models/InboxConfig.md b/packages/project-client/docs/models/InboxConfig.md new file mode 100644 index 000000000..6d7cda954 --- /dev/null +++ b/packages/project-client/docs/models/InboxConfig.md @@ -0,0 +1,9 @@ +# InboxConfig + +**Properties** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| images | any | ✅ | | +| locale | string | ✅ | | +| theme | any | ✅ | | diff --git a/packages/project-client/docs/models/InboxToken.md b/packages/project-client/docs/models/InboxToken.md new file mode 100644 index 000000000..b940caf68 --- /dev/null +++ b/packages/project-client/docs/models/InboxToken.md @@ -0,0 +1,7 @@ +# InboxToken + +**Properties** + +| Name | Type | Required | Description | +| :---- | :----- | :------- | :---------- | +| token | string | ✅ | | diff --git a/packages/project-client/docs/models/InboxTokenWithMetadata.md b/packages/project-client/docs/models/InboxTokenWithMetadata.md new file mode 100644 index 000000000..00839c8c0 --- /dev/null +++ b/packages/project-client/docs/models/InboxTokenWithMetadata.md @@ -0,0 +1,19 @@ +# InboxTokenWithMetadata + +**Properties** + +| Name | Type | Required | Description | +| :------- | :----------------------------- | :------- | :---------- | +| data | InboxToken | ✅ | | +| metadata | InboxTokenWithMetadataMetadata | ✅ | | + +# InboxTokenWithMetadataMetadata + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/ListIntegrationsResponse.md b/packages/project-client/docs/models/ListIntegrationsResponse.md new file mode 100644 index 000000000..93b5da48d --- /dev/null +++ b/packages/project-client/docs/models/ListIntegrationsResponse.md @@ -0,0 +1,17 @@ +# ListIntegrationsResponse + +**Properties** + +| Name | Type | Required | Description | +| :----------- | :------------- | :------- | :---------- | +| integrations | Integrations[] | ❌ | | + +# Integrations + +**Properties** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| config | any | ❌ | | +| id | string | ❌ | | +| name | string | ❌ | | diff --git a/packages/project-client/docs/models/MailgunConfig.md b/packages/project-client/docs/models/MailgunConfig.md new file mode 100644 index 000000000..f4c6435b9 --- /dev/null +++ b/packages/project-client/docs/models/MailgunConfig.md @@ -0,0 +1,18 @@ +# MailgunConfig + +**Properties** + +| Name | Type | Required | Description | +| :----- | :------------------ | :------- | :---------- | +| apiKey | string | ✅ | | +| domain | string | ✅ | | +| region | MailgunConfigRegion | ✅ | | + +# MailgunConfigRegion + +**Properties** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| US | string | ✅ | "us" | +| EU | string | ✅ | "eu" | diff --git a/packages/project-client/docs/models/PingConfig.md b/packages/project-client/docs/models/PingConfig.md new file mode 100644 index 000000000..4350c6fe8 --- /dev/null +++ b/packages/project-client/docs/models/PingConfig.md @@ -0,0 +1,7 @@ +# PingConfig + +**Properties** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| url | string | ✅ | URL to ping | diff --git a/packages/project-client/docs/models/SendgridConfig.md b/packages/project-client/docs/models/SendgridConfig.md new file mode 100644 index 000000000..00ed1cc62 --- /dev/null +++ b/packages/project-client/docs/models/SendgridConfig.md @@ -0,0 +1,27 @@ +# SendgridConfig + +**Properties** + +| Name | Type | Required | Description | +| :------ | :----------------- | :------- | :----------------------- | +| apiKey | string | ✅ | The API key for Sendgrid | +| from | SendgridConfigFrom | ❌ | | +| replyTo | ReplyTo | ❌ | | + +# SendgridConfigFrom + +**Properties** + +| Name | Type | Required | Description | +| :---- | :----- | :------- | :----------------------------- | +| email | string | ✅ | The email address to send from | +| name | string | ❌ | The name to send from | + +# ReplyTo + +**Properties** + +| Name | Type | Required | Description | +| :---- | :----- | :------- | :---------------------------- | +| email | string | ✅ | The email address to reply to | +| name | string | ❌ | The name to reply to | diff --git a/packages/project-client/docs/models/SesConfig.md b/packages/project-client/docs/models/SesConfig.md new file mode 100644 index 000000000..6c84da4f6 --- /dev/null +++ b/packages/project-client/docs/models/SesConfig.md @@ -0,0 +1,20 @@ +# SesConfig + +**Properties** + +| Name | Type | Required | Description | +| :-------- | :------------ | :------- | :----------------------------------------------- | +| keyId | string | ✅ | AWS Access Key ID | +| region | string | ✅ | AWS Region | +| secretKey | string | ✅ | AWS Secret Key | +| endpoint | string | ❌ | HTTP endpoint to send requests to (testing only) | +| from | SesConfigFrom | ❌ | | + +# SesConfigFrom + +**Properties** + +| Name | Type | Required | Description | +| :---- | :----- | :------- | :----------------------------- | +| email | string | ✅ | The email address to send from | +| name | string | ❌ | The name to send from | diff --git a/packages/project-client/docs/models/SlackConfig.md b/packages/project-client/docs/models/SlackConfig.md new file mode 100644 index 000000000..0366f21d9 --- /dev/null +++ b/packages/project-client/docs/models/SlackConfig.md @@ -0,0 +1,11 @@ +# SlackConfig + +**Properties** + +| Name | Type | Required | Description | +| :------------ | :----- | :------- | :---------- | +| appId | string | ✅ | | +| clientId | string | ✅ | | +| clientSecret | string | ✅ | | +| signingSecret | string | ✅ | | +| id | string | ❌ | | diff --git a/packages/project-client/docs/models/SlackToken.md b/packages/project-client/docs/models/SlackToken.md new file mode 100644 index 000000000..03697085b --- /dev/null +++ b/packages/project-client/docs/models/SlackToken.md @@ -0,0 +1,26 @@ +# SlackToken + +**Properties** + +| Name | Type | Required | Description | +| :------ | :------ | :------- | :---------- | +| oauth | Oauth | ❌ | | +| webhook | Webhook | ❌ | | + +# Oauth + +**Properties** + +| Name | Type | Required | Description | +| :------------- | :----- | :------- | :---------- | +| channelId | string | ✅ | | +| installationId | string | ✅ | | +| scope | string | ❌ | | + +# Webhook + +**Properties** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| url | string | ✅ | | diff --git a/packages/project-client/docs/models/SlackTokenWithMetadata.md b/packages/project-client/docs/models/SlackTokenWithMetadata.md new file mode 100644 index 000000000..4bb1dd6ef --- /dev/null +++ b/packages/project-client/docs/models/SlackTokenWithMetadata.md @@ -0,0 +1,19 @@ +# SlackTokenWithMetadata + +**Properties** + +| Name | Type | Required | Description | +| :------- | :----------------------------- | :------- | :---------- | +| data | SlackToken | ✅ | | +| metadata | SlackTokenWithMetadataMetadata | ✅ | | + +# SlackTokenWithMetadataMetadata + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/StripeConfig.md b/packages/project-client/docs/models/StripeConfig.md new file mode 100644 index 000000000..6a3a79ea3 --- /dev/null +++ b/packages/project-client/docs/models/StripeConfig.md @@ -0,0 +1,7 @@ +# StripeConfig + +**Properties** + +| Name | Type | Required | Description | +| :------------------- | :----- | :------- | :--------------------------------------------------------- | +| webhookSigningSecret | string | ✅ | The signing secret to verify incoming requests from Stripe | diff --git a/packages/project-client/docs/models/TeamsTokenWithMetadata.md b/packages/project-client/docs/models/TeamsTokenWithMetadata.md new file mode 100644 index 000000000..780c16eca --- /dev/null +++ b/packages/project-client/docs/models/TeamsTokenWithMetadata.md @@ -0,0 +1,19 @@ +# TeamsTokenWithMetadata + +**Properties** + +| Name | Type | Required | Description | +| :------- | :----------------------------- | :------- | :---------- | +| data | any | ✅ | | +| metadata | TeamsTokenWithMetadataMetadata | ✅ | | + +# TeamsTokenWithMetadataMetadata + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/TwilioConfig.md b/packages/project-client/docs/models/TwilioConfig.md new file mode 100644 index 000000000..1a6a63cb8 --- /dev/null +++ b/packages/project-client/docs/models/TwilioConfig.md @@ -0,0 +1,23 @@ +# TwilioConfig + +**Properties** + +| Name | Type | Required | Description | +| :--------- | :----------------- | :------- | :---------------------------------------------- | +| accountSid | string | ✅ | The SID for your Twilio account | +| apiKey | string | ✅ | The API key for Twilio | +| apiSecret | string | ✅ | The API Secret for Twilio | +| from | string | ✅ | The phone number to send from, in E.164 format | +| region | TwilioConfigRegion | ❌ | The region to use for Twilio, defaults to 'us1' | + +# TwilioConfigRegion + +The region to use for Twilio, defaults to 'us1' + +**Properties** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| US1 | string | ✅ | "us1" | +| IE1 | string | ✅ | "ie1" | +| AU1 | string | ✅ | "au1" | diff --git a/packages/project-client/docs/models/WebPushToken.md b/packages/project-client/docs/models/WebPushToken.md new file mode 100644 index 000000000..23e8a46df --- /dev/null +++ b/packages/project-client/docs/models/WebPushToken.md @@ -0,0 +1,17 @@ +# WebPushToken + +**Properties** + +| Name | Type | Required | Description | +| :------- | :----- | :------- | :---------- | +| endpoint | string | ✅ | | +| keys | Keys | ✅ | | + +# Keys + +**Properties** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| auth | string | ✅ | | +| p256dh | string | ✅ | | diff --git a/packages/project-client/docs/models/WebPushTokenWithMetadata.md b/packages/project-client/docs/models/WebPushTokenWithMetadata.md new file mode 100644 index 000000000..21d9e1bea --- /dev/null +++ b/packages/project-client/docs/models/WebPushTokenWithMetadata.md @@ -0,0 +1,19 @@ +# WebPushTokenWithMetadata + +**Properties** + +| Name | Type | Required | Description | +| :------- | :------------------------------- | :------- | :---------- | +| data | WebPushToken | ✅ | | +| metadata | WebPushTokenWithMetadataMetadata | ✅ | | + +# WebPushTokenWithMetadataMetadata + +**Properties** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| createdAt | string | ✅ | | +| id | string | ✅ | | +| discardedAt | string | ❌ | | +| updatedAt | string | ❌ | | diff --git a/packages/project-client/docs/models/WebpushConfig.md b/packages/project-client/docs/models/WebpushConfig.md new file mode 100644 index 000000000..7bb99601b --- /dev/null +++ b/packages/project-client/docs/models/WebpushConfig.md @@ -0,0 +1,8 @@ +# WebpushConfig + +**Properties** + +| Name | Type | Required | Description | +| :--------- | :----- | :------- | :---------- | +| privateKey | string | ✅ | | +| publicKey | string | ✅ | | diff --git a/packages/project-client/docs/services/BroadcastsService.md b/packages/project-client/docs/services/BroadcastsService.md new file mode 100644 index 000000000..6144365d5 --- /dev/null +++ b/packages/project-client/docs/services/BroadcastsService.md @@ -0,0 +1,173 @@ +# BroadcastsService + +A list of all methods in the `BroadcastsService` service. Click on the method name to view detailed information about that method. + +| Methods | Description | +| :------------------------------------ | :--------------------------------------- | +| [list_broadcasts](#list_broadcasts) | Returns a list of broadcasts | +| [create_broadcast](#create_broadcast) | Handles the create notification request. | +| [fetch_broadcast](#fetch_broadcast) | Returns a broadcast | + +## list_broadcasts + +Returns a list of broadcasts + +- HTTP Method: `GET` +- Endpoint: `/broadcasts` + +**Return Type** + +`BroadcastListResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.broadcasts.listBroadcasts(); + + console.log(data); +})(); +``` + +## create_broadcast + +Handles the create notification request. + +- HTTP Method: `POST` +- Endpoint: `/broadcasts` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :---------------------------------- | :------- | :---------------- | +| body | [Broadcast](../models/Broadcast.md) | ❌ | The request body. | + +**Return Type** + +`Broadcast` + +**Example Usage Code Snippet** + +```typescript +import { Broadcast, Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const email: Email = { + actionUrl: 'ipsum esse', + content: 'sit veniam', + title: 'in id ex aliqua', + }; + + const inApp: InApp = { + actionUrl: 'ullamco labore voluptate', + content: 'consequat magna Excepteur dolor mollit', + title: 'irure', + }; + + const mobilePush: MobilePush = { + actionUrl: 'elitdolore adipisicing anim elit deserunt', + content: 'cupidatat elit', + title: 'ut', + }; + + const slack: Slack = { + actionUrl: 'sit commodo consectetur Duis', + content: 'proident sed quis Lorem', + title: 'magna reprehenderit ut deserunt nisi', + }; + + const sms: Sms = { + actionUrl: 'irure Excepteur exercitation', + content: 'et adipisicing in elit', + title: 'sint voluptate ipsum cupidatat', + }; + + const webPush: WebPush = { + actionUrl: 'dolor in elit id', + content: 'est ea elit exercitation dolore', + title: 'aute eiusmod ea', + }; + + const channels: Channels = { + email: email, + inApp: inApp, + mobilePush: mobilePush, + slack: slack, + sms: sms, + webPush: webPush, + }; + + const providers: Providers = { + amazonSes: {}, + android: {}, + ios: {}, + mailgun: {}, + postmark: {}, + sendgrid: {}, + slack: {}, + }; + + const overrides: Overrides = { + channels: channels, + providers: providers, + }; + + const broadcast: Broadcast = { + actionUrl: 'Ut aliquip est laboris', + category: 'sint in eu tempor magna', + content: 'aliqua ad dolor officia', + customAttributes: {}, + overrides: overrides, + recipients: [{}], + title: 'nisi elit amet laboris tempor', + topic: 'nulla consequat do incididunt', + }; + + const { data } = await client.broadcasts.createBroadcast(input); + + console.log(data); +})(); +``` + +## fetch_broadcast + +Returns a broadcast + +- HTTP Method: `GET` +- Endpoint: `/broadcasts/{broadcast_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :---------- | :----- | :------- | :---------- | +| broadcastId | string | ✅ | | + +**Return Type** + +`Broadcast` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.broadcasts.fetchBroadcast('broadcast_id'); + + console.log(data); +})(); +``` diff --git a/packages/project-client/docs/services/ChannelsService.md b/packages/project-client/docs/services/ChannelsService.md new file mode 100644 index 000000000..a3479444f --- /dev/null +++ b/packages/project-client/docs/services/ChannelsService.md @@ -0,0 +1,594 @@ +# ChannelsService + +A list of all methods in the `ChannelsService` service. Click on the method name to view detailed information about that method. + +| Methods | Description | +| :-------------------------------------------------------------------------- | :---------- | +| [get_in_app_user_tokens](#get_in_app_user_tokens) | | +| [get_in_app_user_token](#get_in_app_user_token) | | +| [discard_in_app_user_token](#discard_in_app_user_token) | | +| [get_mobile_push_apns_user_tokens](#get_mobile_push_apns_user_tokens) | | +| [get_mobile_push_apns_user_token](#get_mobile_push_apns_user_token) | | +| [discard_mobile_push_apns_user_token](#discard_mobile_push_apns_user_token) | | +| [get_mobile_push_fcm_user_tokens](#get_mobile_push_fcm_user_tokens) | | +| [get_mobile_push_fcm_user_token](#get_mobile_push_fcm_user_token) | | +| [discard_mobile_push_fcm_user_token](#discard_mobile_push_fcm_user_token) | | +| [get_slack_user_tokens](#get_slack_user_tokens) | | +| [get_slack_user_token](#get_slack_user_token) | | +| [discard_slack_user_token](#discard_slack_user_token) | | +| [get_teams_user_tokens](#get_teams_user_tokens) | | +| [get_teams_user_token](#get_teams_user_token) | | +| [discard_teams_user_token](#discard_teams_user_token) | | +| [get_web_push_user_tokens](#get_web_push_user_tokens) | | +| [get_web_push_user_token](#get_web_push_user_token) | | +| [discard_web_push_user_token](#discard_web_push_user_token) | | + +## get_in_app_user_tokens + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/in_app/tokens` + +**Parameters** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| userId | string | ✅ | | + +**Return Type** + +`ArrayWithMetadataOfInboxToken` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getInAppUserTokens('user_id'); + + console.log(data); +})(); +``` + +## get_in_app_user_token + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/in_app/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`InboxTokenWithMetadata` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getInAppUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## discard_in_app_user_token + +- HTTP Method: `DELETE` +- Endpoint: `/users/{user_id}/channels/in_app/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardResult` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.discardInAppUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## get_mobile_push_apns_user_tokens + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/mobile_push/apns/tokens` + +**Parameters** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| userId | string | ✅ | | + +**Return Type** + +`ArrayWithMetadataOfApnsToken` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getMobilePushApnsUserTokens('user_id'); + + console.log(data); +})(); +``` + +## get_mobile_push_apns_user_token + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/mobile_push/apns/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`ApnsTokenWithMetadata` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getMobilePushApnsUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## discard_mobile_push_apns_user_token + +- HTTP Method: `DELETE` +- Endpoint: `/users/{user_id}/channels/mobile_push/apns/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardResult` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.discardMobilePushApnsUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## get_mobile_push_fcm_user_tokens + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/mobile_push/fcm/tokens` + +**Parameters** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| userId | string | ✅ | | + +**Return Type** + +`ArrayWithMetadataOfFcmToken` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getMobilePushFcmUserTokens('user_id'); + + console.log(data); +})(); +``` + +## get_mobile_push_fcm_user_token + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/mobile_push/fcm/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`FcmTokenWithMetadata` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getMobilePushFcmUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## discard_mobile_push_fcm_user_token + +- HTTP Method: `DELETE` +- Endpoint: `/users/{user_id}/channels/mobile_push/fcm/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardResult` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.discardMobilePushFcmUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## get_slack_user_tokens + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/slack/tokens` + +**Parameters** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| userId | string | ✅ | | + +**Return Type** + +`ArrayWithMetadataOfSlackToken` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getSlackUserTokens('user_id'); + + console.log(data); +})(); +``` + +## get_slack_user_token + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/slack/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`SlackTokenWithMetadata` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getSlackUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## discard_slack_user_token + +- HTTP Method: `DELETE` +- Endpoint: `/users/{user_id}/channels/slack/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardResult` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.discardSlackUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## get_teams_user_tokens + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/teams/tokens` + +**Parameters** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| userId | string | ✅ | | + +**Return Type** + +`ArrayWithMetadataOfTeamsToken` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getTeamsUserTokens('user_id'); + + console.log(data); +})(); +``` + +## get_teams_user_token + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/teams/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`TeamsTokenWithMetadata` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getTeamsUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## discard_teams_user_token + +- HTTP Method: `DELETE` +- Endpoint: `/users/{user_id}/channels/teams/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardResult` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.discardTeamsUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## get_web_push_user_tokens + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/web_push/tokens` + +**Parameters** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| userId | string | ✅ | | + +**Return Type** + +`ArrayWithMetadataOfWebPushToken` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getWebPushUserTokens('user_id'); + + console.log(data); +})(); +``` + +## get_web_push_user_token + +- HTTP Method: `GET` +- Endpoint: `/users/{user_id}/channels/web_push/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`WebPushTokenWithMetadata` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.getWebPushUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` + +## discard_web_push_user_token + +- HTTP Method: `DELETE` +- Endpoint: `/users/{user_id}/channels/web_push/tokens/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| userId | string | ✅ | | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardResult` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.channels.discardWebPushUserToken('user_id', 'token_id'); + + console.log(data); +})(); +``` diff --git a/packages/project-client/docs/services/IntegrationsService.md b/packages/project-client/docs/services/IntegrationsService.md new file mode 100644 index 000000000..628fdfb8a --- /dev/null +++ b/packages/project-client/docs/services/IntegrationsService.md @@ -0,0 +1,1542 @@ +# IntegrationsService + +A list of all methods in the `IntegrationsService` service. Click on the method name to view detailed information about that method. + +| Methods | Description | +| :-------------------------------------------------------------------------- | :---------- | +| [list_integrations](#list_integrations) | | +| [get_apns_integration](#get_apns_integration) | | +| [save_apns_integration](#save_apns_integration) | | +| [delete_apns_integration](#delete_apns_integration) | | +| [delete_apns_integration_by_id](#delete_apns_integration_by_id) | | +| [get_fcm_integration](#get_fcm_integration) | | +| [save_fcm_integration](#save_fcm_integration) | | +| [delete_fcm_integration](#delete_fcm_integration) | | +| [delete_fcm_integration_by_id](#delete_fcm_integration_by_id) | | +| [get_github_integration](#get_github_integration) | | +| [save_github_integration](#save_github_integration) | | +| [delete_github_integration](#delete_github_integration) | | +| [delete_github_integration_by_id](#delete_github_integration_by_id) | | +| [get_inbox_integration](#get_inbox_integration) | | +| [save_inbox_integration](#save_inbox_integration) | | +| [delete_inbox_integration](#delete_inbox_integration) | | +| [delete_inbox_integration_by_id](#delete_inbox_integration_by_id) | | +| [get_mailgun_integration](#get_mailgun_integration) | | +| [save_mailgun_integration](#save_mailgun_integration) | | +| [delete_mailgun_integration](#delete_mailgun_integration) | | +| [delete_mailgun_integration_by_id](#delete_mailgun_integration_by_id) | | +| [get_ping_email_integration](#get_ping_email_integration) | | +| [save_ping_email_integration](#save_ping_email_integration) | | +| [delete_ping_email_integration](#delete_ping_email_integration) | | +| [delete_ping_email_integration_by_id](#delete_ping_email_integration_by_id) | | +| [get_sendgrid_integration](#get_sendgrid_integration) | | +| [save_sendgrid_integration](#save_sendgrid_integration) | | +| [delete_sendgrid_integration](#delete_sendgrid_integration) | | +| [delete_sendgrid_integration_by_id](#delete_sendgrid_integration_by_id) | | +| [get_ses_integration](#get_ses_integration) | | +| [save_ses_integration](#save_ses_integration) | | +| [delete_ses_integration](#delete_ses_integration) | | +| [delete_ses_integration_by_id](#delete_ses_integration_by_id) | | +| [get_slack_integration](#get_slack_integration) | | +| [save_slack_integration](#save_slack_integration) | | +| [delete_slack_integration](#delete_slack_integration) | | +| [delete_slack_integration_by_id](#delete_slack_integration_by_id) | | +| [get_stripe_integration](#get_stripe_integration) | | +| [save_stripe_integration](#save_stripe_integration) | | +| [delete_stripe_integration](#delete_stripe_integration) | | +| [delete_stripe_integration_by_id](#delete_stripe_integration_by_id) | | +| [get_templates_integration](#get_templates_integration) | | +| [save_templates_integration](#save_templates_integration) | | +| [delete_templates_integration](#delete_templates_integration) | | +| [delete_templates_integration_by_id](#delete_templates_integration_by_id) | | +| [get_twilio_integration](#get_twilio_integration) | | +| [save_twilio_integration](#save_twilio_integration) | | +| [delete_twilio_integration](#delete_twilio_integration) | | +| [delete_twilio_integration_by_id](#delete_twilio_integration_by_id) | | +| [get_web_push_integration](#get_web_push_integration) | | +| [save_web_push_integration](#save_web_push_integration) | | +| [delete_web_push_integration](#delete_web_push_integration) | | +| [delete_web_push_integration_by_id](#delete_web_push_integration_by_id) | | + +## list_integrations + +- HTTP Method: `GET` +- Endpoint: `/integrations` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.listIntegrations(); + + console.log(data); +})(); +``` + +## get_apns_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/apns` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getApnsIntegration(); + + console.log(data); +})(); +``` + +## save_apns_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/apns` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :------------------------------------ | :------- | :---------------- | +| body | [ApnsConfig](../models/ApnsConfig.md) | ❌ | The request body. | + +**Return Type** + +`ApnsConfig` + +**Example Usage Code Snippet** + +```typescript +import { ApnsConfig, Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const badge = Badge.UNREAD; + + const apnsConfig: ApnsConfig = { + appId: 'iAYqMy12w9iGu7ff1EsX`Yd7Od!5pFmfIMNCPzvFgZiCEg+ihR0u2bAgXQlSqFd8hh', + badge: badge, + certificate: 'certificate', + keyId: 'nostrud ul', + teamId: 'ut reprehe', + }; + + const { data } = await client.integrations.saveApnsIntegration(input); + + console.log(data); +})(); +``` + +## delete_apns_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/apns` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteApnsIntegration(); + + console.log(data); +})(); +``` + +## delete_apns_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/apns/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteApnsIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_fcm_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/fcm` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getFcmIntegration(); + + console.log(data); +})(); +``` + +## save_fcm_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/fcm` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :---------------------------------- | :------- | :---------------- | +| body | [FcmConfig](../models/FcmConfig.md) | ❌ | The request body. | + +**Return Type** + +`FcmConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, FcmConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const type_ = Type_.SERVICEACCOUNT; + + const fcmConfig: FcmConfig = { + authProviderX509CertUrl: 'auth_provider_x509_cert_url', + authUri: 'auth_uri', + clientEmail: 'client_email', + clientId: 'client_id', + clientX509CertUrl: 'client_x509_cert_url', + privateKey: 'private_key', + privateKeyId: 'private_key_id', + projectId: 'project_id', + tokenUri: 'token_uri', + type: type_, + universeDomain: 'universe_domain', + }; + + const { data } = await client.integrations.saveFcmIntegration(input); + + console.log(data); +})(); +``` + +## delete_fcm_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/fcm` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteFcmIntegration(); + + console.log(data); +})(); +``` + +## delete_fcm_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/fcm/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteFcmIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_github_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/github` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getGithubIntegration(); + + console.log(data); +})(); +``` + +## save_github_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/github` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :---------------------------------------- | :------- | :---------------- | +| body | [GithubConfig](../models/GithubConfig.md) | ❌ | The request body. | + +**Return Type** + +`GithubConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, GithubConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const githubConfig: GithubConfig = { + webhookSigningSecret: 'adipisicing', + }; + + const { data } = await client.integrations.saveGithubIntegration(input); + + console.log(data); +})(); +``` + +## delete_github_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/github` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteGithubIntegration(); + + console.log(data); +})(); +``` + +## delete_github_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/github/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteGithubIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_inbox_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/inbox` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getInboxIntegration(); + + console.log(data); +})(); +``` + +## save_inbox_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/inbox` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :-------------------------------------- | :------- | :---------------- | +| body | [InboxConfig](../models/InboxConfig.md) | ❌ | The request body. | + +**Return Type** + +`InboxConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, InboxConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const inboxConfig: InboxConfig = { + images: {}, + locale: 'dolore moll', + theme: {}, + }; + + const { data } = await client.integrations.saveInboxIntegration(input); + + console.log(data); +})(); +``` + +## delete_inbox_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/inbox` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteInboxIntegration(); + + console.log(data); +})(); +``` + +## delete_inbox_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/inbox/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteInboxIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_mailgun_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/mailgun` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getMailgunIntegration(); + + console.log(data); +})(); +``` + +## save_mailgun_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/mailgun` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :------------------------------------------ | :------- | :---------------- | +| body | [MailgunConfig](../models/MailgunConfig.md) | ❌ | The request body. | + +**Return Type** + +`MailgunConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, MailgunConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const mailgunConfigRegion = MailgunConfigRegion.US; + + const mailgunConfig: MailgunConfig = { + apiKey: 'molli', + domain: 'do ', + region: mailgunConfigRegion, + }; + + const { data } = await client.integrations.saveMailgunIntegration(input); + + console.log(data); +})(); +``` + +## delete_mailgun_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/mailgun` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteMailgunIntegration(); + + console.log(data); +})(); +``` + +## delete_mailgun_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/mailgun/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteMailgunIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_ping_email_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/ping_email` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getPingEmailIntegration(); + + console.log(data); +})(); +``` + +## save_ping_email_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/ping_email` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :------------------------------------ | :------- | :---------------- | +| body | [PingConfig](../models/PingConfig.md) | ❌ | The request body. | + +**Return Type** + +`PingConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, PingConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const pingConfig: PingConfig = { + url: 'laboris Duis', + }; + + const { data } = await client.integrations.savePingEmailIntegration(input); + + console.log(data); +})(); +``` + +## delete_ping_email_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/ping_email` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deletePingEmailIntegration(); + + console.log(data); +})(); +``` + +## delete_ping_email_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/ping_email/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deletePingEmailIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_sendgrid_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/sendgrid` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getSendgridIntegration(); + + console.log(data); +})(); +``` + +## save_sendgrid_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/sendgrid` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :-------------------------------------------- | :------- | :---------------- | +| body | [SendgridConfig](../models/SendgridConfig.md) | ❌ | The request body. | + +**Return Type** + +`SendgridConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, SendgridConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const sendgridConfigFrom: SendgridConfigFrom = { + email: 'email', + name: 'name', + }; + + const replyTo: ReplyTo = { + email: 'email', + name: 'name', + }; + + const sendgridConfig: SendgridConfig = { + apiKey: 'api_key', + from: sendgridConfigFrom, + replyTo: replyTo, + }; + + const { data } = await client.integrations.saveSendgridIntegration(input); + + console.log(data); +})(); +``` + +## delete_sendgrid_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/sendgrid` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteSendgridIntegration(); + + console.log(data); +})(); +``` + +## delete_sendgrid_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/sendgrid/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteSendgridIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_ses_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/ses` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getSesIntegration(); + + console.log(data); +})(); +``` + +## save_ses_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/ses` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :---------------------------------- | :------- | :---------------- | +| body | [SesConfig](../models/SesConfig.md) | ❌ | The request body. | + +**Return Type** + +`SesConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, SesConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const sesConfigFrom: SesConfigFrom = { + email: 'email', + name: 'name', + }; + + const sesConfig: SesConfig = { + endpoint: 'dolor e', + from: sesConfigFrom, + keyId: 'cillum no', + region: 'dolor culpa co', + secretKey: 'pa', + }; + + const { data } = await client.integrations.saveSesIntegration(input); + + console.log(data); +})(); +``` + +## delete_ses_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/ses` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteSesIntegration(); + + console.log(data); +})(); +``` + +## delete_ses_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/ses/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteSesIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_slack_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/slack` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getSlackIntegration(); + + console.log(data); +})(); +``` + +## save_slack_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/slack` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :-------------------------------------- | :------- | :---------------- | +| body | [SlackConfig](../models/SlackConfig.md) | ❌ | The request body. | + +**Return Type** + +`SlackConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, SlackConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const slackConfig: SlackConfig = { + appId: '6SX2ZNPXG8L', + clientId: '430411624.02717865207', + clientSecret: 'labore in ea fugiat magnainsed v', + id: 'CM0mBN', + signingSecret: 'exercitation Excepteur et euanim', + }; + + const { data } = await client.integrations.saveSlackIntegration(input); + + console.log(data); +})(); +``` + +## delete_slack_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/slack` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteSlackIntegration(); + + console.log(data); +})(); +``` + +## delete_slack_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/slack/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteSlackIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_stripe_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/stripe` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getStripeIntegration(); + + console.log(data); +})(); +``` + +## save_stripe_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/stripe` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :---------------------------------------- | :------- | :---------------- | +| body | [StripeConfig](../models/StripeConfig.md) | ❌ | The request body. | + +**Return Type** + +`StripeConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, StripeConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const stripeConfig: StripeConfig = { + webhookSigningSecret: 'et nisi', + }; + + const { data } = await client.integrations.saveStripeIntegration(input); + + console.log(data); +})(); +``` + +## delete_stripe_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/stripe` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteStripeIntegration(); + + console.log(data); +})(); +``` + +## delete_stripe_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/stripe/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteStripeIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_templates_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/templates` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getTemplatesIntegration(); + + console.log(data); +})(); +``` + +## save_templates_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/templates` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :--- | :------- | :---------------- | +| body | any | ❌ | The request body. | + +**Return Type** + +`any` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const input = {}; + + const { data } = await client.integrations.saveTemplatesIntegration(input); + + console.log(data); +})(); +``` + +## delete_templates_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/templates` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteTemplatesIntegration(); + + console.log(data); +})(); +``` + +## delete_templates_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/templates/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteTemplatesIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_twilio_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/twilio` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getTwilioIntegration(); + + console.log(data); +})(); +``` + +## save_twilio_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/twilio` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :---------------------------------------- | :------- | :---------------- | +| body | [TwilioConfig](../models/TwilioConfig.md) | ❌ | The request body. | + +**Return Type** + +`TwilioConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, TwilioConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const twilioConfigRegion = TwilioConfigRegion.US1; + + const twilioConfig: TwilioConfig = { + accountSid: 'sunt', + apiKey: 'laboris non sunt fugiat', + apiSecret: 'aliqua sit laboris labore', + from: '+959', + region: twilioConfigRegion, + }; + + const { data } = await client.integrations.saveTwilioIntegration(input); + + console.log(data); +})(); +``` + +## delete_twilio_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/twilio` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteTwilioIntegration(); + + console.log(data); +})(); +``` + +## delete_twilio_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/twilio/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteTwilioIntegrationById('id'); + + console.log(data); +})(); +``` + +## get_web_push_integration + +- HTTP Method: `GET` +- Endpoint: `/integrations/web_push` + +**Return Type** + +`ListIntegrationsResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.getWebPushIntegration(); + + console.log(data); +})(); +``` + +## save_web_push_integration + +- HTTP Method: `PUT` +- Endpoint: `/integrations/web_push` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :------------------------------------------ | :------- | :---------------- | +| body | [WebpushConfig](../models/WebpushConfig.md) | ❌ | The request body. | + +**Return Type** + +`WebpushConfig` + +**Example Usage Code Snippet** + +```typescript +import { Client, WebpushConfig } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const webpushConfig: WebpushConfig = { + privateKey: 'pariatur occaecat magna', + publicKey: 'exercitati', + }; + + const { data } = await client.integrations.saveWebPushIntegration(input); + + console.log(data); +})(); +``` + +## delete_web_push_integration + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/web_push` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteWebPushIntegration(); + + console.log(data); +})(); +``` + +## delete_web_push_integration_by_id + +- HTTP Method: `DELETE` +- Endpoint: `/integrations/web_push/{id}` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :----- | :------- | :---------- | +| id | string | ✅ | | + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.integrations.deleteWebPushIntegrationById('id'); + + console.log(data); +})(); +``` diff --git a/packages/project-client/docs/services/JwtService.md b/packages/project-client/docs/services/JwtService.md new file mode 100644 index 000000000..adfd65e49 --- /dev/null +++ b/packages/project-client/docs/services/JwtService.md @@ -0,0 +1,204 @@ +# JwtService + +A list of all methods in the `JwtService` service. Click on the method name to view detailed information about that method. + +| Methods | Description | +| :-------------------------------------------- | :---------- | +| [fetch_project_tokens](#fetch_project_tokens) | | +| [create_project_jwt](#create_project_jwt) | | +| [discard_project_jwt](#discard_project_jwt) | | +| [create_user_jwt](#create_user_jwt) | | +| [discard_user_jwt](#discard_user_jwt) | | +| [fetch_user_tokens](#fetch_user_tokens) | | + +## fetch_project_tokens + +- HTTP Method: `GET` +- Endpoint: `/jwt/project` + +**Return Type** + +`FetchTokensResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.jwt.fetchProjectTokens(); + + console.log(data); +})(); +``` + +## create_project_jwt + +- HTTP Method: `POST` +- Endpoint: `/jwt/project` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :------------------------------------------------------------------ | :------- | :---------------- | +| body | [CreateProjectTokenRequest](../models/CreateProjectTokenRequest.md) | ❌ | The request body. | + +**Return Type** + +`AccessToken` + +**Example Usage Code Snippet** + +```typescript +import { Client, CreateProjectTokenRequest } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const createProjectTokenRequest: CreateProjectTokenRequest = { + expiry: 1, + name: 'culpa', + }; + + const { data } = await client.jwt.createProjectJwt(input); + + console.log(data); +})(); +``` + +## discard_project_jwt + +- HTTP Method: `DELETE` +- Endpoint: `/jwt/project/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardTokenResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.jwt.discardProjectJwt('token_id'); + + console.log(data); +})(); +``` + +## create_user_jwt + +- HTTP Method: `POST` +- Endpoint: `/jwt/user` + +**Parameters** + +| Name | Type | Required | Description | +| :--- | :------------------------------------------------------------ | :------- | :---------------- | +| body | [CreateUserTokenRequest](../models/CreateUserTokenRequest.md) | ❌ | The request body. | + +**Return Type** + +`AccessToken` + +**Example Usage Code Snippet** + +```typescript +import { Client, CreateUserTokenRequest } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const createUserTokenRequest: CreateUserTokenRequest = { + email: 'laborum esse do dolore ullamco', + expiry: 6, + externalId: 'ut officia', + name: 'exercitation esse', + }; + + const { data } = await client.jwt.createUserJwt(input); + + console.log(data); +})(); +``` + +## discard_user_jwt + +- HTTP Method: `DELETE` +- Endpoint: `/jwt/user/{token_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :------ | :----- | :------- | :---------- | +| tokenId | string | ✅ | | + +**Return Type** + +`DiscardTokenResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.jwt.discardUserJwt('token_id'); + + console.log(data); +})(); +``` + +## fetch_user_tokens + +- HTTP Method: `GET` +- Endpoint: `/jwt/user/{user_id}` + +**Parameters** + +| Name | Type | Required | Description | +| :----- | :----- | :------- | :---------- | +| userId | string | ✅ | | + +**Return Type** + +`FetchTokensResponse` + +**Example Usage Code Snippet** + +```typescript +import { Client } from '@magicbell/project-client'; + +(async () => { + const client = new Client({ + token: 'YOUR_TOKEN', + }); + + const { data } = await client.jwt.fetchUserTokens('user_id'); + + console.log(data); +})(); +``` diff --git a/packages/project-client/liblab.config.json b/packages/project-client/liblab.config.json new file mode 100644 index 000000000..459fe175b --- /dev/null +++ b/packages/project-client/liblab.config.json @@ -0,0 +1,45 @@ +{ + "sdkName": "client", + "apiVersion": "2.0.0", + "apiName": "magicbell-api", + "specFilePath": "./magicbell-client.swagger.json", + "languages": ["typescript"], + "auth": ["bearer"], + "customizations": { + "includeOptionalSnippetParameters": true, + "authentication": { + "access": { + "prefix": "Bearer" + } + }, + "devContainer": false, + "generateEnv": true, + "inferServiceNames": false, + "injectedModels": [], + "license": { + "type": "CUSTOM", + "url": "https://raw.githubusercontent.com/magicbell/magicbell-js/main/LICENSE" + }, + "responseHeaders": false, + "retry": { + "enabled": true, + "maxAttempts": 3, + "retryDelay": 150 + } + }, + "languageOptions": { + "typescript": { + "bundle": false, + "exportClassDefault": false, + "npmName": "project-client", + "npmOrg": "magicbell", + "githubRepoName": "magicbell-js", + "ignoreFiles": [], + "sdkVersion": "0.1.0", + "liblabVersion": "2" + } + }, + "publishing": { + "githubOrg": "magicbell" + } +} diff --git a/packages/project-client/package.json b/packages/project-client/package.json new file mode 100644 index 000000000..882ee950a --- /dev/null +++ b/packages/project-client/package.json @@ -0,0 +1,48 @@ +{ + "name": "@magicbell/project-client", + "version": "0.1.0", + "description": "OpenAPI 3.1.0 Specification for MagicBell API.", + "keywords": [ + "typescript", + "sdk", + "api", + "client" + ], + "repository": { + "type": "git", + "url": "https://github.com/magicbell/magicbell-js.git", + "directory": "packages/project-client" + }, + "author": "MagicBell", + "exports": { + ".": { + "require": "./dist/index.js", + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "main": "./dist/commonjs/index.js", + "unpkg": "./dist/index.umd.js", + "module": "./dist/esm/index.js", + "source": "./src/index.ts", + "browser": "./dist/index.umd.js", + "types": "./dist/commonjs/index.d.ts", + "files": [ + "dist", + "README.md" + ], + "scripts": { + "build": "run-s build:*", + "build:cjs": "tsc --project tsconfig.build.json --module commonjs --outDir dist/commonjs", + "build:esm": "tsc --project tsconfig.build.json --module esnext --outDir dist/esm", + "codegen": "tsx scripts/build.ts", + "start": "rm -rf dist/ && tsc -w" + }, + "dependencies": { + "axios": "^1.7.4", + "zod": "3.22.0" + }, + "devDependencies": { + "typescript": "^5.5.3" + } +} diff --git a/packages/project-client/scripts/build.ts b/packages/project-client/scripts/build.ts new file mode 100644 index 000000000..8e467701e --- /dev/null +++ b/packages/project-client/scripts/build.ts @@ -0,0 +1,158 @@ +import { execSync } from 'node:child_process'; +import * as fs from 'node:fs/promises'; +import * as path from 'node:path'; +import { parseArgs } from 'node:util'; + +import Debug from 'debug'; +import { rimraf } from 'rimraf'; +import { sortPackageJson } from 'sort-package-json'; + +import rootPkgJson from '../../../package.json'; + +const debug = Debug('build'); + +async function move(oldPath: string, newPath: string) { + await rimraf(newPath); + await fs.mkdir(path.dirname(newPath), { recursive: true }); + await fs.rename(oldPath, newPath); +} + +function deleteUserPaths(schema: any) { + schema.tags = schema.tags.filter((x: any) => x.name !== 'admin' && x.name !== 'user'); + + for (const path of Object.keys(schema.paths)) { + for (const method of Object.keys(schema.paths[path])) { + const operation = schema.paths[path][method]; + if (!('tags' in operation) || !Array.isArray(operation.tags)) continue; + + // delete operation if it's not for admins + if (operation.tags.includes('admin')) { + operation.tags = operation.tags.filter((x: any) => x !== 'admin'); + } else { + delete schema.paths[path][method]; + debug(`delete ${path}/${method}`); + + // delete path if no operations left + if (Object.keys(schema.paths[path]).length > 0) continue; + delete schema.paths[path]; + debug(`delete ${path}`); + } + } + } + + return schema; +} + +function findAllRefs(obj: any, refs = new Set()) { + if (typeof obj !== 'object' || obj === null) return refs; + + if (Array.isArray(obj)) { + obj.forEach((item) => findAllRefs(item, refs)); + } else { + for (const key in obj) { + if (key === '$ref' && typeof obj[key] === 'string') { + refs.add(obj[key]); + } else { + findAllRefs(obj[key], refs); + } + } + } + + return refs; +} + +function deleteUnreferencedComponents(swagger: any) { + let refs = findAllRefs(swagger); + const components = swagger.components && swagger.components.schemas; + let initialCount, currentCount; + + do { + initialCount = Object.keys(components || {}).length; + + if (components) { + for (const schema in components) { + const refString = `#/components/schemas/${schema}`; + if (!refs.has(refString)) { + delete components[schema]; + // console.log(`delete ${refString}`) + } + } + } + + refs = findAllRefs(swagger); // Recalculate references after deletion + currentCount = Object.keys(components || {}).length; + } while (initialCount !== currentCount); +} + +async function readFileOrUrl(path: string): Promise { + if (/^http?s:\/\//.test(path)) { + return fetch(path, { headers: { 'content-type': 'application/json' } }).then((x) => x.text()); + } + + return fs.readFile(path, { encoding: 'utf-8' }); +} + +const { values: args } = parseArgs({ + options: { + spec: { type: 'string', short: 's' }, + }, +}); + +async function build(specfile = 'https://public.magicbell.com/specs/openapi.v2.json') { + const liblabConfig = JSON.parse(await fs.readFile('./liblab.config.json', { encoding: 'utf-8' })); + let swaggerJSON = await readFileOrUrl(specfile); + const spec = JSON.parse(swaggerJSON); + + deleteUserPaths(spec); + deleteUnreferencedComponents(spec); + + swaggerJSON = JSON.stringify(spec, null, 2); + + await fs.writeFile(liblabConfig.specFilePath, swaggerJSON); + execSync(`npx -y liblab@latest build -y`, { stdio: 'inherit' }); + await rimraf(liblabConfig.specFilePath); + + await move('output/typescript/src', './src'); + // tests are currently ignored, as they're not stable between rebuilds, liblab is looking into this + // await move('output/typescript/test', './test'); + await move('output/typescript/package.json', './package.json'); + await move('output/typescript/README.md', './README.md'); + await move('output/typescript/documentation', './docs'); + await rimraf('output'); + + // patch package.json + let pkgJson = JSON.parse(await fs.readFile('./package.json', { encoding: 'utf-8' })); + pkgJson.scripts.codegen = 'tsx scripts/build.ts'; + + pkgJson.scripts = { + build: 'run-s build:*', + 'build:cjs': 'tsc --project tsconfig.build.json --module commonjs --outDir dist/commonjs', + 'build:esm': 'tsc --project tsconfig.build.json --module esnext --outDir dist/esm', + start: 'rm -rf dist/ && tsc -w', + codegen: 'tsx scripts/build.ts', + }; + + for (const key of Object.keys(pkgJson.devDependencies)) { + if (/eslint|prettier/.test(key)) { + delete pkgJson.devDependencies[key]; + } else if (rootPkgJson.dependencies[key]) { + pkgJson.devDependencies[key] = rootPkgJson.dependencies[key]; + } + } + + pkgJson.repository = { + type: 'git', + url: 'https://github.com/magicbell/magicbell-js.git', + directory: 'packages/project-client', + }; + + pkgJson = sortPackageJson(pkgJson); + await fs.writeFile('./package.json', JSON.stringify(pkgJson, null, 2) + '\n'); + + execSync(`yarn --cwd ../.. eslint --fix .`, { stdio: 'inherit' }); + execSync(`yarn --cwd ../.. manypkg fix`, { stdio: 'inherit' }); + execSync(`yarn --cwd ../..`, { stdio: 'inherit' }); + execSync(`yarn build`, { stdio: 'inherit' }); +} + +build(args.spec); diff --git a/packages/project-client/scripts/sync-docs.ts b/packages/project-client/scripts/sync-docs.ts new file mode 100644 index 000000000..4a8aad436 --- /dev/null +++ b/packages/project-client/scripts/sync-docs.ts @@ -0,0 +1,190 @@ +/* eslint-disable no-console */ +import * as fs from 'node:fs/promises'; +import * as path from 'node:path'; + +import { replaceBlock } from '@magicbell/codegen'; +import { Octokit } from '@octokit/rest'; +import { config } from 'dotenv'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +config(); + +const GITHUB_TOKEN = process.env.GITHUB_TOKEN!; +const REPO_OWNER = 'smeijer'; +const REPO_NAME = 'test'; +const FILE_PATH = 'src/docs/the-doc-to-update-2.mdx'; //'src/docs/docs/03-libraries/javascript-project-client.mdx'; +const BRANCH_NAME = 'magicbella/update-sdk-docs'; +const BASE_BRANCH = 'main'; + +if (!GITHUB_TOKEN) { + console.log('GITHUB_TOKEN environment variable is missing'); + process.exit(1); +} + +const octokit = new Octokit({ + auth: GITHUB_TOKEN, +}); + +async function fetchMainBranchSha() { + const response = await octokit.git.getRef({ + owner: REPO_OWNER, + repo: REPO_NAME, + ref: `heads/${BASE_BRANCH}`, + }); + return response.data.object.sha; +} + +async function ensureBranchFromMain() { + const mainBranchSha = await fetchMainBranchSha(); + + try { + await octokit.git.createRef({ + owner: REPO_OWNER, + repo: REPO_NAME, + ref: `refs/heads/${BRANCH_NAME}`, + sha: mainBranchSha, + }); + console.log(`Branch ${BRANCH_NAME} created successfully.`); + } catch (error: any) { + if (error.status === 422 && error.message.includes('Reference already exists')) { + console.log(`Branch ${BRANCH_NAME} already exists. Ensuring it's up to date.`); + await octokit.git.updateRef({ + owner: REPO_OWNER, + repo: REPO_NAME, + ref: `heads/${BRANCH_NAME}`, + sha: mainBranchSha, + force: true, + }); + } else { + throw error; + } + } +} + +async function fetchFileContent() { + try { + const response = await octokit.repos.getContent({ + owner: REPO_OWNER, + repo: REPO_NAME, + path: FILE_PATH, + ref: `heads/${BASE_BRANCH}`, + }); + + const fileContent = Buffer.from(response.data['content'], 'base64').toString('utf-8'); + return { content: fileContent, sha: response.data['sha'], exists: true }; + } catch (error: any) { + if (error.status === 404) { + return { content: '', sha: '', exists: false }; + } else { + throw error; + } + } +} + +async function updateFile(content: string, sha: string) { + const updatedContent = Buffer.from(content).toString('base64'); + + await octokit.repos.createOrUpdateFileContents({ + owner: REPO_OWNER, + repo: REPO_NAME, + path: FILE_PATH, + message: 'docs: update sdk documentation', + content: updatedContent, + branch: BRANCH_NAME, + sha: sha, + }); +} + +async function createOrUpdatePullRequest() { + const { data: pullRequests } = await octokit.pulls.list({ + owner: REPO_OWNER, + repo: REPO_NAME, + state: 'open', + head: `${REPO_OWNER}:${BRANCH_NAME}`, + base: BASE_BRANCH, + }); + + const title = 'docs: update sdk documentation'; + const body = 'Automated update of sdk documentation'; + + if (pullRequests.length > 0) { + const pr = pullRequests[0]; + console.log(`Pull request #${pr.number} already exists. Updating...`); + await octokit.pulls.update({ + owner: REPO_OWNER, + repo: REPO_NAME, + pull_number: pr.number, + title, + body, + }); + } else { + console.log('Creating new pull request.'); + await octokit.pulls.create({ + owner: REPO_OWNER, + repo: REPO_NAME, + head: BRANCH_NAME, + base: BASE_BRANCH, + title, + body, + }); + } +} + +function getMarkdownSection(markdown: string, sectionTitle: string) { + const lines = markdown.split('\n'); + const matcher = sectionTitle.startsWith('#') + ? (line) => line.trim() === sectionTitle.trim() + : (line) => line.trim().endsWith(`# ${sectionTitle}`); + + const startIndex = lines.findIndex(matcher); + + if (startIndex === -1) { + return null; // Section not found + } + + const needle = sectionTitle.split(' ')[0] + ' '; + + const endIndex = lines.findIndex((line, index) => { + if (index <= startIndex) return false; + return line.startsWith(needle); + }); + + const sectionLines = lines.slice(startIndex + 1, endIndex === -1 ? undefined : endIndex); + + return { + title: sectionTitle.replace(needle, '').trim(), + content: sectionLines.join('\n').trim(), + startIndex, + endIndex, + }; +} + +export async function syncDocs() { + try { + const readme = await fs.readFile(path.join(__dirname, '..', 'README.md'), { encoding: 'utf-8' }); + const allMethods = getMarkdownSection(readme, '## All Methods'); + + const { content, sha, exists } = await fetchFileContent(); + const patchedContent = replaceBlock(content, 'ALL_METHODS', allMethods.content); + + if (content === patchedContent) { + console.log('files are already up to date'); + return; + } + + await ensureBranchFromMain(); + await updateFile(patchedContent, exists ? sha : ''); + await createOrUpdatePullRequest(); + console.log('Pull request processed successfully.'); + } catch (error) { + console.error('Error updating documentation:', error); + } +} + +syncDocs().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/packages/project-client/src/http/client.ts b/packages/project-client/src/http/client.ts new file mode 100644 index 000000000..3487ef482 --- /dev/null +++ b/packages/project-client/src/http/client.ts @@ -0,0 +1,35 @@ +import { AuthHandler } from './handlers/auth-handler'; +import { RequestHandlerChain } from './handlers/handler-chain'; +import { HookHandler } from './handlers/hook-handler'; +import { RequestValidationHandler } from './handlers/request-validation-handler'; +import { ResponseValidationHandler } from './handlers/response-validation-handler'; +import { RetryHandler } from './handlers/retry-handler'; +import { TerminatingHandler } from './handlers/terminating-handler'; +import { CustomHook } from './hooks/custom-hook'; +import { Request } from './transport/request'; +import { HttpResponse, SdkConfig } from './types'; + +export class HttpClient { + private readonly requestHandlerChain = new RequestHandlerChain(); + + constructor(private config: SdkConfig, hook = new CustomHook()) { + this.requestHandlerChain.addHandler(new ResponseValidationHandler()); + this.requestHandlerChain.addHandler(new RequestValidationHandler()); + this.requestHandlerChain.addHandler(new AuthHandler()); + this.requestHandlerChain.addHandler(new RetryHandler()); + this.requestHandlerChain.addHandler(new HookHandler(hook)); + this.requestHandlerChain.addHandler(new TerminatingHandler()); + } + + call(request: Request): Promise> { + return this.requestHandlerChain.callChain(request); + } + + setBaseUrl(url: string): void { + this.config.baseUrl = url; + } + + setConfig(config: SdkConfig): void { + this.config = config; + } +} diff --git a/packages/project-client/src/http/environment.ts b/packages/project-client/src/http/environment.ts new file mode 100644 index 000000000..836b28fba --- /dev/null +++ b/packages/project-client/src/http/environment.ts @@ -0,0 +1,3 @@ +export enum Environment { + DEFAULT = 'https://api.magicbell.com/v2', +} diff --git a/packages/project-client/src/http/error.ts b/packages/project-client/src/http/error.ts new file mode 100644 index 000000000..4dc1d6bd5 --- /dev/null +++ b/packages/project-client/src/http/error.ts @@ -0,0 +1,12 @@ +import { HttpMetadata } from './types'; + +export class HttpError extends Error { + public readonly error: string; + public readonly metadata: HttpMetadata; + + constructor(metadata: HttpMetadata, error?: string) { + super(error); + this.error = metadata.statusText; + this.metadata = metadata; + } +} diff --git a/packages/project-client/src/http/handlers/auth-handler.ts b/packages/project-client/src/http/handlers/auth-handler.ts new file mode 100644 index 000000000..9fdc35fcb --- /dev/null +++ b/packages/project-client/src/http/handlers/auth-handler.ts @@ -0,0 +1,34 @@ +import { SerializationStyle } from '../serialization/base-serializer'; +import { Request } from '../transport/request'; +import { HttpResponse, RequestHandler } from '../types'; + +export class AuthHandler implements RequestHandler { + next?: RequestHandler; + + async handle(request: Request): Promise> { + const requestWithAuth = this.addAccessTokenHeader(request); + + if (!this.next) { + throw new Error(`No next handler set in ${AuthHandler.name}`); + } + + return this.next?.handle(requestWithAuth); + } + + private addAccessTokenHeader(request: Request): Request { + const { token } = request.config; + if (!token) { + return request; + } + + request.addHeaderParam('Authorization', { + key: 'Authorization', + value: `Bearer ${token}`, + explode: false, + encode: false, + style: SerializationStyle.SIMPLE, + }); + + return request; + } +} diff --git a/packages/project-client/src/http/handlers/handler-chain.ts b/packages/project-client/src/http/handlers/handler-chain.ts new file mode 100644 index 000000000..9f56b046e --- /dev/null +++ b/packages/project-client/src/http/handlers/handler-chain.ts @@ -0,0 +1,22 @@ +import { Request } from '../transport/request'; +import { HttpResponse, RequestHandler } from '../types'; + +export class RequestHandlerChain { + private readonly handlers: RequestHandler[] = []; + + addHandler(handler: RequestHandler): void { + if (this.handlers.length > 0) { + const previousHandler = this.handlers[this.handlers.length - 1]; + previousHandler.next = handler; + } + this.handlers.push(handler); + } + + async callChain(request: Request): Promise> { + if (!this.handlers.length) { + throw new Error('No handlers added to the chain'); + } + + return this.handlers[0].handle(request); + } +} diff --git a/packages/project-client/src/http/handlers/hook-handler.ts b/packages/project-client/src/http/handlers/hook-handler.ts new file mode 100644 index 000000000..7921baffc --- /dev/null +++ b/packages/project-client/src/http/handlers/hook-handler.ts @@ -0,0 +1,38 @@ +import { HttpError } from '../error'; +import { Hook } from '../hooks/hook'; +import { Request } from '../transport/request'; +import { TransportHookAdapter } from '../transport/transport-hook-adapter'; +import { HttpResponse, RequestHandler } from '../types'; + +export class HookHandler implements RequestHandler { + next?: RequestHandler; + + constructor(private readonly hook: Hook) {} + + async handle(request: Request): Promise> { + if (!this.next) { + throw new Error('No next handler set in hook handler.'); + } + + const hook = new TransportHookAdapter(); + + const hookParams = this.getHookParams(request); + + const nextRequest = await hook.beforeRequest(request, hookParams); + + const response = await this.next.handle(nextRequest); + + if (response.metadata.status < 400) { + return await hook.afterResponse(nextRequest, response, hookParams); + } + + const error = await hook.onError(nextRequest, response, hookParams); + + throw new HttpError(error.metadata, error.error); + } + + private getHookParams(_request: Request): Map { + const hookParams: Map = new Map(); + return hookParams; + } +} diff --git a/packages/project-client/src/http/handlers/request-validation-handler.ts b/packages/project-client/src/http/handlers/request-validation-handler.ts new file mode 100644 index 000000000..5e6e8e868 --- /dev/null +++ b/packages/project-client/src/http/handlers/request-validation-handler.ts @@ -0,0 +1,71 @@ +import { Request } from '../transport/request'; +import { ContentType, HttpResponse, RequestHandler } from '../types'; + +export class RequestValidationHandler implements RequestHandler { + next?: RequestHandler; + + async handle(request: Request): Promise> { + if (!this.next) { + throw new Error('No next handler set in ContentTypeHandler.'); + } + + if (request.requestContentType === ContentType.Json) { + request.body = JSON.stringify(request.requestSchema?.parse(request.body)); + } else if ( + request.requestContentType === ContentType.Xml || + request.requestContentType === ContentType.Binary || + request.requestContentType === ContentType.Text + ) { + request.body = request.body; + } else if (request.requestContentType === ContentType.FormUrlEncoded) { + request.body = this.toFormUrlEncoded(request.body); + } else if (request.requestContentType === ContentType.MultipartFormData) { + request.body = this.toFormData(request.body); + } else { + request.body = JSON.stringify(request.requestSchema?.parse(request.body)); + } + + return await this.next.handle(request); + } + + toFormUrlEncoded(body: BodyInit | undefined): string { + if (body === undefined) { + return ''; + } + + if (typeof body === 'string') { + return body; + } + + if (body instanceof URLSearchParams) { + return body.toString(); + } + + if (body instanceof FormData) { + const params = new URLSearchParams(); + body.forEach((value, key) => { + params.append(key, value.toString()); + }); + return params.toString(); + } + + return ''; + } + + toFormData(body: Record): FormData | undefined { + const formData = new FormData(); + + Object.keys(body).forEach((key: any) => { + const value: any = body[key]; + if (Array.isArray(value)) { + value.forEach((v, i) => formData.append(`${key}[${i}]`, v)); + } else if (value instanceof ArrayBuffer) { + formData.append(key, new Blob([value])); + } else { + formData.append(key, value); + } + }); + + return formData; + } +} diff --git a/packages/project-client/src/http/handlers/response-validation-handler.ts b/packages/project-client/src/http/handlers/response-validation-handler.ts new file mode 100644 index 000000000..a589c09f1 --- /dev/null +++ b/packages/project-client/src/http/handlers/response-validation-handler.ts @@ -0,0 +1,106 @@ +import { ZodUndefined } from 'zod'; + +import { Request } from '../transport/request'; +import { ContentType, HttpResponse, RequestHandler } from '../types'; + +export class ResponseValidationHandler implements RequestHandler { + next?: RequestHandler; + + async handle(request: Request): Promise> { + const response = await this.next!.handle(request); + + if (!this.hasContent(request, response)) { + return response; + } + + if (request.responseContentType === ContentType.Json) { + const decodedBody = new TextDecoder().decode(response.raw); + const json = JSON.parse(decodedBody); + return { + ...response, + data: this.validate(request, json), + }; + } else if ( + request.responseContentType === ContentType.Binary || + request.responseContentType === ContentType.Image + ) { + return { + ...response, + data: this.validate(request, response.raw), + }; + } else if (request.responseContentType === ContentType.Text || request.responseContentType === ContentType.Xml) { + const text = new TextDecoder().decode(response.raw); + return { + ...response, + data: this.validate(request, text), + }; + } else if (request.responseContentType === ContentType.FormUrlEncoded) { + const urlEncoded = this.fromUrlEncoded(new TextDecoder().decode(response.raw)); + return { + ...response, + data: this.validate(request, urlEncoded), + }; + } else if (request.responseContentType === ContentType.MultipartFormData) { + const formData = this.fromFormData(response.raw); + return { + ...response, + data: this.validate(request, formData), + }; + } else { + const decodedBody = new TextDecoder().decode(response.raw); + const json = JSON.parse(decodedBody); + return { + ...response, + data: this.validate(request, json), + }; + } + } + + private validate(request: Request, data: any): T { + if (request.validation?.responseValidation) { + return request.responseSchema.parse(data); + } + return data; + } + + private hasContent(request: Request, response: HttpResponse): boolean { + return ( + !!request.responseSchema && !(request.responseSchema instanceof ZodUndefined) && response.metadata.status !== 204 + ); + } + + private fromUrlEncoded(urlEncodedData: string): object { + const pairs = urlEncodedData.split('&'); + const result: Record = {}; + + pairs.forEach((pair) => { + const [key, value] = pair.split('='); + if (key && value !== undefined) { + result[decodeURIComponent(key)] = decodeURIComponent(value); + } + }); + + return result; + } + + private fromFormData(arrayBuffer: ArrayBuffer): Record { + const decoder = new TextDecoder(); + const text = decoder.decode(arrayBuffer); + + const boundary = text.split('\r\n')[0]; + const parts = text.split(boundary).slice(1, -1); + + const formDataObj: Record = {}; + + parts.forEach((part) => { + const [header, value] = part.split('\r\n\r\n'); + const nameMatch = header.match(/name="([^"]+)"/); + if (nameMatch) { + const name = nameMatch[1].trim(); + formDataObj[name] = value?.trim() || ''; + } + }); + + return formDataObj; + } +} diff --git a/packages/project-client/src/http/handlers/retry-handler.ts b/packages/project-client/src/http/handlers/retry-handler.ts new file mode 100644 index 000000000..d3f191b82 --- /dev/null +++ b/packages/project-client/src/http/handlers/retry-handler.ts @@ -0,0 +1,40 @@ +import { HttpError } from '../error'; +import { Request } from '../transport/request'; +import { HttpResponse, RequestHandler } from '../types'; + +export class RetryHandler implements RequestHandler { + next?: RequestHandler; + + async handle(request: Request): Promise> { + if (!this.next) { + throw new Error('No next handler set in retry handler.'); + } + + for (let attempt = 1; attempt <= request.retry.attempts; attempt++) { + try { + return await this.next.handle(request); + } catch (error: any) { + if (!this.shouldRetry(error) || attempt === request.retry.attempts) { + throw error; + } + await this.delay(request.retry.delayMs); + } + } + + throw new Error('Error retrying request.'); + } + + private shouldRetry(error: Error): boolean { + return error instanceof HttpError && (error.metadata.status >= 500 || error.metadata.status === 408); + } + + private delay(delayMs: number | undefined): Promise { + if (!delayMs) { + return Promise.resolve(); + } + + return new Promise((resolve, reject) => { + setTimeout(() => resolve(), delayMs); + }); + } +} diff --git a/packages/project-client/src/http/handlers/terminating-handler.ts b/packages/project-client/src/http/handlers/terminating-handler.ts new file mode 100644 index 000000000..12f03fc7e --- /dev/null +++ b/packages/project-client/src/http/handlers/terminating-handler.ts @@ -0,0 +1,9 @@ +import { Request } from '../transport/request'; +import { RequestAxiosAdapter } from '../transport/request-axios-adapter'; +import { HttpResponse, RequestHandler } from '../types'; + +export class TerminatingHandler implements RequestHandler { + async handle(request: Request): Promise> { + return new RequestAxiosAdapter(request).send(); + } +} diff --git a/packages/project-client/src/http/hooks/custom-hook.ts b/packages/project-client/src/http/hooks/custom-hook.ts new file mode 100644 index 000000000..8bd856f19 --- /dev/null +++ b/packages/project-client/src/http/hooks/custom-hook.ts @@ -0,0 +1,28 @@ +import { HttpMetadata } from '../types'; +import { Hook, HttpError, HttpRequest, HttpResponse } from './hook'; + +export class CustomHook implements Hook { + public async beforeRequest(request: HttpRequest, params: Map): Promise { + return request; + } + + public async afterResponse( + request: HttpRequest, + response: HttpResponse, + params: Map, + ): Promise> { + return response; + } + + public async onError( + request: HttpRequest, + response: HttpResponse, + params: Map, + ): Promise { + return new CustomHttpError('a custom error message', response.metadata); + } +} + +class CustomHttpError implements HttpError { + constructor(public error: string, public metadata: HttpMetadata) {} +} diff --git a/packages/project-client/src/http/hooks/hook.ts b/packages/project-client/src/http/hooks/hook.ts new file mode 100644 index 000000000..9ca243357 --- /dev/null +++ b/packages/project-client/src/http/hooks/hook.ts @@ -0,0 +1,40 @@ +type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; + +export interface HttpRequest { + baseUrl: string; + method: HttpMethod; + path: string; + headers: Map; + body?: BodyInit; + abortSignal?: AbortSignal; + queryParams: Map; +} + +interface HttpMetadata { + status: number; + statusText: string; + headers: Record; +} + +export interface HttpResponse { + data?: T; + metadata: HttpMetadata; + raw: ArrayBuffer; +} + +export interface HttpError { + error: string; + metadata: HttpMetadata; +} + +export interface Hook { + beforeRequest(request: HttpRequest, params: Map): Promise; + + afterResponse( + request: HttpRequest, + response: HttpResponse, + params: Map, + ): Promise>; + + onError(request: HttpRequest, response: HttpResponse, params: Map): Promise; +} diff --git a/packages/project-client/src/http/index.ts b/packages/project-client/src/http/index.ts new file mode 100644 index 000000000..d8231fa58 --- /dev/null +++ b/packages/project-client/src/http/index.ts @@ -0,0 +1 @@ +export type { RequestConfig, RetryOptions, SdkConfig, ValidationOptions } from './types.ts'; diff --git a/packages/project-client/src/http/serialization/base-serializer.ts b/packages/project-client/src/http/serialization/base-serializer.ts new file mode 100644 index 000000000..7d0c7824e --- /dev/null +++ b/packages/project-client/src/http/serialization/base-serializer.ts @@ -0,0 +1,139 @@ +import { RequestParameter } from '../transport/request'; + +export type SerializationOptions = { + explode: boolean; + style: SerializationStyle; + encode: boolean; +}; + +export enum SerializationStyle { + SIMPLE = 'simple', + LABEL = 'label', + MATRIX = 'matrix', + FORM = 'form', + SPACE_DELIMITED = 'space_delimited', + PIPE_DELIMITED = 'pipe_delimited', + DEEP_OBJECT = 'deep_object', + NONE = 'none', +} + +export class Serializer { + protected serializeValue(param: RequestParameter): string { + if (Array.isArray(param.value)) { + return this.serializeArray(param.value, param); + } + + if (this.isNonNullObject(param.value)) { + return this.serializeObject(param.value, param); + } + + return this.serializePrimitive(param); + } + + private serializePrimitive(param: RequestParameter): string { + if (param.style === SerializationStyle.LABEL) { + return `.${param.value}`; + } else if (param.style === SerializationStyle.MATRIX) { + return `;${param.key}=${param.value}`; + } else if (param.style === SerializationStyle.FORM) { + return `${encodeURIComponent(param.key || '')}=${encodeURIComponent(`${param.value}`)}`; + } + + return `${param.value}`; + } + + private serializeArray(value: unknown[], param: RequestParameter): string { + if (param.explode) { + this.serializeArrayExploded(value, param); + return this.serializeArrayExploded(value, param); + } + + if (param.style === SerializationStyle.SIMPLE) { + return `${value.join(',')}`; + } else if (param.style === SerializationStyle.LABEL) { + return `.${value.join(',')}`; + } else if (param.style === SerializationStyle.MATRIX) { + return `;${param.key}=${value.join(',')}`; + } else if (param.style === SerializationStyle.FORM) { + return `${encodeURIComponent(param.key || '')}=${encodeURIComponent(value.join(','))}`; + } else if (param.style === SerializationStyle.SPACE_DELIMITED) { + return `${param.key}=${value.join(' ')}`; + } else if (param.style === SerializationStyle.PIPE_DELIMITED) { + return `${param.key}=${value.join('|')}`; + } + + return `${value.join(',')}`; + } + + private serializeArrayExploded(value: unknown[], param: RequestParameter): string { + if (param.style === SerializationStyle.SIMPLE) { + return value.map((val) => `${val}`).join(','); + } else if (param.style === SerializationStyle.LABEL) { + return value.map((val) => `.${val}`).join(''); + } else if (param.style === SerializationStyle.MATRIX) { + return value.map((val) => `;${param.key}=${val}`).join(''); + } else if ( + param.style === SerializationStyle.FORM || + param.style === SerializationStyle.SPACE_DELIMITED || + param.style === SerializationStyle.PIPE_DELIMITED + ) { + return value.map((val) => `${encodeURIComponent(param.key || '')}=${encodeURIComponent(`${val}`)}`).join('&'); + } + + return `${value.join(',')}`; + } + + private serializeObject(obj: object, param: RequestParameter): string { + if (param.explode) { + if (param.style === SerializationStyle.SIMPLE) { + return Object.entries(obj) + .map(([key, val]) => `${key}=${val}`) + .join(','); + } else if (param.style === SerializationStyle.LABEL) { + return Object.entries(obj) + .map(([key, val]) => `.${key}=${val}`) + .join(''); + } else if (param.style === SerializationStyle.MATRIX) { + return Object.entries(obj) + .map(([key, val]) => `;${key}=${val}`) + .join(''); + } else if (param.style === SerializationStyle.FORM) { + return Object.entries(obj) + .map(([key, val]) => `${key}=${val}`) + .join('&'); + } + } + + if (param.style === SerializationStyle.SIMPLE) { + return Object.entries(obj) + .map(([key, val]) => `${key},${val}`) + .join(','); + } else if (param.style === SerializationStyle.LABEL) { + return `.${Object.entries(obj) + .map(([key, val]) => `${key},${val}`) + .join(',')}`; + } else if (param.style === SerializationStyle.MATRIX) { + return `;${param.key}=${Object.entries(obj) + .map(([key, val]) => `${key},${val}`) + .join(',')}`; + } else if (param.style === SerializationStyle.FORM) { + return Object.entries(obj) + .map(([key, val]) => `${key}=${val}`) + .join('&'); + } else if (param.style === SerializationStyle.DEEP_OBJECT) { + return Object.entries(obj) + .map(([key, val]) => { + return `${param.key}[${key}]=${val}`; + }) + .join('&'); + } + + return Object.entries(obj) + .map(([key, val]) => `${key}=${val}`) + .join('&'); + } + + private isNonNullObject(value: unknown): value is object { + return typeof value === 'object' && value !== null; + } +} diff --git a/packages/project-client/src/http/serialization/header-serializer.ts b/packages/project-client/src/http/serialization/header-serializer.ts new file mode 100644 index 000000000..98f2fae41 --- /dev/null +++ b/packages/project-client/src/http/serialization/header-serializer.ts @@ -0,0 +1,19 @@ +import { RequestParameter } from '../transport/request'; +import { Serializer } from './base-serializer'; + +export class HeaderSerializer extends Serializer { + public serialize(headerParams: Map | undefined): HeadersInit | undefined { + if (!headerParams || !headerParams.size) { + return undefined; + } + + const headers: HeadersInit = {}; + headerParams.forEach((param) => { + if (!param.key) { + return; + } + headers[param.key] = this.serializeValue(param); + }); + return headers; + } +} diff --git a/packages/project-client/src/http/serialization/path-serializer.ts b/packages/project-client/src/http/serialization/path-serializer.ts new file mode 100644 index 000000000..000fa9d47 --- /dev/null +++ b/packages/project-client/src/http/serialization/path-serializer.ts @@ -0,0 +1,12 @@ +import { RequestParameter } from '../transport/request'; +import { Serializer } from './base-serializer'; + +export class PathSerializer extends Serializer { + public serialize(pathPattern: string, pathArguments: Map): string { + let serializedPath = pathPattern; + pathArguments.forEach((param: RequestParameter) => { + serializedPath = serializedPath.replace(`{${param.key}}`, `${this.serializeValue(param)}`); + }); + return serializedPath; + } +} diff --git a/packages/project-client/src/http/serialization/query-serializer.ts b/packages/project-client/src/http/serialization/query-serializer.ts new file mode 100644 index 000000000..26a193c63 --- /dev/null +++ b/packages/project-client/src/http/serialization/query-serializer.ts @@ -0,0 +1,18 @@ +import { RequestParameter } from '../transport/request'; +import { Serializer } from './base-serializer'; + +export class QuerySerializer extends Serializer { + public serialize(queryParams: Map): string { + if (!queryParams || !queryParams.size) { + return ''; + } + + const query: string[] = []; + + queryParams.forEach((param) => { + return query.push(`${this.serializeValue(param)}`); + }); + + return query.length ? `?${query.join('&')}` : ''; + } +} diff --git a/packages/project-client/src/http/transport/request-axios-adapter.ts b/packages/project-client/src/http/transport/request-axios-adapter.ts new file mode 100644 index 000000000..e7e14ff0b --- /dev/null +++ b/packages/project-client/src/http/transport/request-axios-adapter.ts @@ -0,0 +1,98 @@ +import axios, { AxiosRequestConfig, AxiosResponse, isAxiosError } from 'axios'; + +import { HttpError } from '../error'; +import { HttpMetadata, HttpResponse } from '../types'; +import { Request } from './request'; + +export interface HttpAdapter { + send(): Promise; +} + +export class RequestAxiosAdapter implements HttpAdapter { + private config: AxiosRequestConfig = { + responseType: 'arraybuffer', + }; + + constructor(private request: Request) { + this.setHeaders(); + this.setTimeout(); + } + + public async send(): Promise> { + const method = this.getMethod(); + const { body } = this.request; + let axiosResponse: AxiosResponse; + + try { + if (!!body) { + axiosResponse = await method(this.request.constructFullUrl(), body, this.config); + } else { + axiosResponse = await method(this.request.constructFullUrl(), this.config); + } + } catch (err) { + if (!isAxiosError(err)) { + throw err; + } + axiosResponse = err.response; + } + + const headerRecord: Record = {}; + Object.keys(axiosResponse.headers).forEach((key) => { + headerRecord[key] = axiosResponse.headers[key]; + }); + + const metadata: HttpMetadata = { + status: axiosResponse.status, + statusText: axiosResponse.statusText || '', + headers: headerRecord, + }; + + if (metadata.status >= 400) { + throw new HttpError(metadata); + } + + return { + metadata, + raw: axiosResponse.data.buffer.slice( + axiosResponse.data.byteOffset, + axiosResponse.data.byteOffset + axiosResponse.data.byteLength, + ), + }; + } + + private getMethod(): (url: string, data?: any, config?: AxiosRequestConfig) => Promise { + if (this.request.method === 'POST') { + return axios.post; + } else if (this.request.method === 'GET') { + return axios.get; + } else if (this.request.method === 'PUT') { + return axios.put; + } else if (this.request.method === 'DELETE') { + return axios.delete; + } + throw new Error('invalid method!!!!'); + } + + private setHeaders(): void { + if (!this.request.headers) { + return; + } + + const headersRecord: Record = {}; + new Headers(this.request.getHeaders()).forEach((value, key) => { + headersRecord[key] = value; + }); + + this.config = { + ...this.config, + headers: headersRecord, + }; + } + + private setTimeout(): void { + this.config = { + ...this.config, + timeout: this.request.config.timeout, + }; + } +} diff --git a/packages/project-client/src/http/transport/request-builder.ts b/packages/project-client/src/http/transport/request-builder.ts new file mode 100644 index 000000000..e4744d3ee --- /dev/null +++ b/packages/project-client/src/http/transport/request-builder.ts @@ -0,0 +1,165 @@ +import z, { ZodType } from 'zod'; + +import { Environment } from '../environment'; +import { SerializationStyle } from '../serialization/base-serializer'; +import { ContentType, HttpMethod, RequestConfig, SdkConfig } from '../types'; +import { CreateRequestParameters, Request, RequestParameter } from './request'; + +export class RequestBuilder { + private params: CreateRequestParameters; + + constructor() { + this.params = { + baseUrl: Environment.DEFAULT, + method: 'GET', + path: '', + config: {}, + responseSchema: z.any(), + requestSchema: z.any(), + requestContentType: ContentType.Json, + responseContentType: ContentType.Json, + retry: { + attempts: 3, + delayMs: 150, + }, + validation: { + responseValidation: true, + }, + pathParams: new Map(), + queryParams: new Map(), + headers: new Map(), + }; + } + + setRetryAttempts(sdkConfig?: SdkConfig, requestConfig?: RequestConfig): RequestBuilder { + if (requestConfig?.retry?.attempts !== undefined) { + this.params.retry.attempts = requestConfig.retry.attempts; + } else if (sdkConfig?.retry?.attempts !== undefined) { + this.params.retry.attempts = sdkConfig.retry.attempts; + } + + return this; + } + + setRetryDelayMs(sdkConfig?: SdkConfig, requestConfig?: RequestConfig): RequestBuilder { + if (requestConfig?.retry?.delayMs !== undefined) { + this.params.retry.delayMs = requestConfig.retry.delayMs; + } else if (sdkConfig?.retry?.delayMs !== undefined) { + this.params.retry.delayMs = sdkConfig.retry.delayMs; + } + + return this; + } + + setResponseValidation(sdkConfig: SdkConfig, requestConfig?: RequestConfig): RequestBuilder { + if (requestConfig?.validation?.responseValidation !== undefined) { + this.params.validation.responseValidation = requestConfig.validation.responseValidation; + } else if (sdkConfig?.validation?.responseValidation !== undefined) { + this.params.validation.responseValidation = sdkConfig.validation.responseValidation; + } + + return this; + } + + setBaseUrl(sdkConfig: SdkConfig): RequestBuilder { + if (sdkConfig?.baseUrl !== undefined) { + this.params.baseUrl = sdkConfig.baseUrl; + } + + return this; + } + + setMethod(method: HttpMethod): RequestBuilder { + this.params.method = method; + return this; + } + + setPath(path: string): RequestBuilder { + this.params.path = path; + return this; + } + + setConfig(config: SdkConfig): RequestBuilder { + this.params.config = config; + return this; + } + + setRequestContentType(contentType: ContentType): RequestBuilder { + this.params.requestContentType = contentType; + return this; + } + + setResponseContentType(contentType: ContentType): RequestBuilder { + this.params.responseContentType = contentType; + return this; + } + + setRequestSchema(requestSchema: ZodType): RequestBuilder { + this.params.requestSchema = requestSchema; + return this; + } + + setResponseSchema(responseSchema: ZodType): RequestBuilder { + this.params.responseSchema = responseSchema; + return this; + } + + addBody(body?: any): RequestBuilder { + if (body !== undefined) { + this.params.body = body; + } + return this; + } + + addPathParam(param: Partial): RequestBuilder { + if (param.value === undefined || param.key === undefined) { + return this; + } + + this.params.pathParams.set(param.key, { + key: param.key, + value: param.value, + explode: param.explode ?? true, + style: param.style ?? SerializationStyle.SIMPLE, + encode: param.encode ?? true, + }); + + return this; + } + + addQueryParam(param: Partial): RequestBuilder { + if (param.value === undefined || param.key === undefined) { + return this; + } + + this.params.queryParams.set(param.key, { + key: param.key, + value: param.value, + explode: param.explode ?? true, + style: param.style ?? SerializationStyle.FORM, + encode: param.encode ?? true, + }); + + return this; + } + + addHeaderParam(param: Partial): RequestBuilder { + if (param.value === undefined || param.key === undefined) { + return this; + } + + this.params.headers.set(param.key, { + key: param.key, + value: param.value, + explode: param.explode ?? true, + style: param.style ?? SerializationStyle.SIMPLE, + encode: param.encode ?? false, + }); + + return this; + } + + public build(): Request { + return new Request(this.params); + } +} diff --git a/packages/project-client/src/http/transport/request.ts b/packages/project-client/src/http/transport/request.ts new file mode 100644 index 000000000..82af8178c --- /dev/null +++ b/packages/project-client/src/http/transport/request.ts @@ -0,0 +1,210 @@ +import { ZodType } from 'zod'; + +import { HttpRequest } from '../hooks/hook'; +import { SerializationStyle } from '../serialization/base-serializer'; +import { HeaderSerializer } from '../serialization/header-serializer'; +import { PathSerializer } from '../serialization/path-serializer'; +import { QuerySerializer } from '../serialization/query-serializer'; +import { ContentType, HttpMethod, RetryOptions, SdkConfig, ValidationOptions } from '../types'; + +export interface CreateRequestParameters { + baseUrl: string; + method: HttpMethod; + body?: any; + headers: Map; + queryParams: Map; + pathParams: Map; + path: string; + config: SdkConfig; + responseSchema: ZodType; + requestSchema: ZodType; + requestContentType: ContentType; + responseContentType: ContentType; + validation: ValidationOptions; + retry: RetryOptions; +} + +export interface RequestParameter { + key: string | undefined; + value: unknown; + explode: boolean; + encode: boolean; + style: SerializationStyle; +} + +export class Request { + public baseUrl = ''; + + public headers: Map = new Map(); + + public queryParams: Map = new Map(); + + public pathParams: Map = new Map(); + + public body?: any; + + public method: HttpMethod; + + public path: string; + + public config: SdkConfig; + + public responseSchema: ZodType; + + public requestSchema: ZodType; + + public requestContentType: ContentType; + + public responseContentType: ContentType; + + public validation: ValidationOptions = {} as any; + + public retry: RetryOptions = {} as any; + + private readonly pathPattern: string; + + constructor(params: CreateRequestParameters) { + this.baseUrl = params.baseUrl; + this.method = params.method; + this.pathPattern = params.path; + this.body = params.body; + this.path = this.constructPath(); + this.config = params.config; + this.pathParams = params.pathParams; + this.headers = params.headers; + this.queryParams = params.queryParams; + this.responseSchema = params.responseSchema; + this.requestSchema = params.requestSchema; + this.requestContentType = params.requestContentType; + this.responseContentType = params.responseContentType; + this.retry = params.retry; + this.validation = params.validation; + } + + addHeaderParam(key: string, param: RequestParameter): void { + if (param.value === undefined) { + return; + } + + if (param.explode === undefined) { + param.explode = false; + } + + if (param.style === undefined) { + param.style = SerializationStyle.SIMPLE; + } + + if (param.encode === undefined) { + param.encode = false; + } + + this.headers.set(key, param); + } + + addQueryParam(key: string, param: RequestParameter): void { + if (param.value === undefined) { + return; + } + + if (param.explode === undefined) { + param.explode = true; + } + + if (param.style === undefined) { + param.style = SerializationStyle.FORM; + } + + if (param.encode === undefined) { + param.encode = true; + } + + this.queryParams.set(key, param); + } + + addPathParam(key: string, param: RequestParameter): void { + if (param.value === undefined) { + return; + } + + if (param.explode === undefined) { + param.explode = false; + } + + if (param.style === undefined) { + param.style = SerializationStyle.SIMPLE; + } + + if (param.encode === undefined) { + param.encode = true; + } + + this.pathParams.set(key, param); + } + + addBody(body: any): void { + if (body === undefined) { + return; + } + + this.body = body; + } + + public updateFromHookRequest(hookRequest: HttpRequest): void { + this.baseUrl = hookRequest.baseUrl; + this.method = hookRequest.method; + this.path = hookRequest.path; + this.body = hookRequest.body; + } + + public toHookRequest(): HttpRequest { + return { + baseUrl: this.baseUrl, + method: this.method, + path: this.path, + headers: this.headers, + body: this.body, + queryParams: this.queryParams, + }; + } + + public constructFullUrl(): string { + const queryString = new QuerySerializer().serialize(this.queryParams); + const path = this.constructPath(); + return `${this.baseUrl}${path}${queryString}`; + } + + public copy(overrides?: Partial>) { + const createRequestParams: CreateRequestParameters = { + baseUrl: overrides?.baseUrl ?? this.baseUrl, + method: overrides?.method ?? this.method, + path: overrides?.path ?? this.path, + body: overrides?.body ?? this.body, + config: overrides?.config ?? this.config, + pathParams: overrides?.pathParams ?? this.pathParams, + queryParams: overrides?.queryParams ?? this.queryParams, + headers: overrides?.headers ?? this.headers, + responseSchema: overrides?.responseSchema ?? this.responseSchema, + requestSchema: overrides?.requestSchema ?? this.requestSchema, + requestContentType: overrides?.requestContentType ?? this.requestContentType, + responseContentType: overrides?.responseContentType ?? this.responseContentType, + retry: overrides?.retry ?? this.retry, + validation: overrides?.validation ?? this.validation, + }; + return new Request({ + ...createRequestParams, + ...overrides, + }); + } + + public getHeaders(): HeadersInit | undefined { + if (!this.headers || !this.headers.size) { + return undefined; + } + + return new HeaderSerializer().serialize(this.headers); + } + + private constructPath(): string { + return new PathSerializer().serialize(this.pathPattern, this.pathParams); + } +} diff --git a/packages/project-client/src/http/transport/transport-hook-adapter.ts b/packages/project-client/src/http/transport/transport-hook-adapter.ts new file mode 100644 index 000000000..0ae51d6ce --- /dev/null +++ b/packages/project-client/src/http/transport/transport-hook-adapter.ts @@ -0,0 +1,85 @@ +import { CustomHook } from '../hooks/custom-hook'; +import { HttpError, HttpRequest } from '../hooks/hook'; +import { SerializationStyle } from '../serialization/base-serializer'; +import { HttpResponse } from '../types'; +import { Request, RequestParameter } from './request'; + +export class TransportHookAdapter { + private hook: CustomHook = new CustomHook(); + + public async beforeRequest(request: Request, params: Map): Promise> { + const hookRequest = this.requestToHookRequest(request); + + const newRequest = await this.hook.beforeRequest(hookRequest, params); + + const newTransportRequest = request.copy({ + baseUrl: newRequest.baseUrl, + method: newRequest.method, + path: newRequest.path, + body: newRequest.body, + queryParams: this.hookParamsToTransportParams(newRequest.queryParams, request.queryParams, true), + headers: this.hookParamsToTransportParams(newRequest.headers, request.headers, false), + }); + + return newTransportRequest; + } + + public async afterResponse( + request: Request, + response: HttpResponse, + params: Map, + ): Promise> { + const hookRequest = this.requestToHookRequest(request); + return this.hook.afterResponse(hookRequest, response, params); + } + + public async onError( + request: Request, + response: HttpResponse, + params: Map, + ): Promise { + const hookRequest = this.requestToHookRequest(request); + return this.hook.onError(hookRequest, response, params); + } + + private requestToHookRequest(request: Request): HttpRequest { + const hookHeaders: Map = new Map(); + request.headers.forEach((header, key) => { + hookHeaders.set(key, header.value); + }); + + const hookQueryParams: Map = new Map(); + request.queryParams.forEach((queryParam, key) => { + hookQueryParams.set(key, queryParam.value); + }); + + const hookRequest: HttpRequest = { + baseUrl: request.baseUrl, + method: request.method, + path: request.path, + headers: hookHeaders, + body: request.body, + queryParams: hookQueryParams, + }; + return hookRequest; + } + + private hookParamsToTransportParams( + hookParams: Map, + originalTransportParams: Map, + encode: boolean, + ): Map { + const transportParams: Map = new Map(); + hookParams.forEach((hookParamValue, hookParamKey) => { + const requestParam = originalTransportParams.get(hookParamKey); + transportParams.set(hookParamKey, { + key: hookParamKey, + value: hookParamValue, + encode: requestParam?.encode ?? false, + style: requestParam?.style || SerializationStyle.NONE, + explode: requestParam?.explode ?? false, + }); + }); + return transportParams; + } +} diff --git a/packages/project-client/src/http/types.ts b/packages/project-client/src/http/types.ts new file mode 100644 index 000000000..a3870a4f2 --- /dev/null +++ b/packages/project-client/src/http/types.ts @@ -0,0 +1,70 @@ +import { ZodType } from 'zod'; + +import { Environment } from './environment'; +import { Request } from './transport/request'; + +export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; + +export interface SdkConfig { + baseUrl?: string; + environment?: Environment; + timeout?: number; + token?: string; + retry?: RetryOptions; + validation?: ValidationOptions; +} + +export interface HttpMetadata { + status: number; + statusText: string; + headers: Record; +} + +export interface HttpResponse { + data?: T; + metadata: HttpMetadata; + raw: ArrayBuffer; +} + +export interface RequestHandler { + next?: RequestHandler; + + handle(request: Request): Promise>; +} + +export enum ContentType { + Json = 'json', + Xml = 'xml', + Pdf = 'pdf', + Image = 'image', + File = 'file', + Binary = 'binary', + FormUrlEncoded = 'form', + Text = 'text', + MultipartFormData = 'multipartFormData', +} + +export interface Options { + responseSchema: ZodType; + requestSchema?: ZodType; + body?: any; + requestContentType?: ContentType; + responseContentType?: ContentType; + abortSignal?: AbortSignal; + queryParams?: Record; + retry?: RetryOptions; +} + +export interface RequestConfig { + retry?: RetryOptions; + validation?: ValidationOptions; +} + +export interface RetryOptions { + attempts: number; + delayMs?: number; +} + +export interface ValidationOptions { + responseValidation?: boolean; +} diff --git a/packages/project-client/src/index.ts b/packages/project-client/src/index.ts new file mode 100644 index 000000000..a7bc397a6 --- /dev/null +++ b/packages/project-client/src/index.ts @@ -0,0 +1,67 @@ +import { Environment } from './http/environment'; +import { SdkConfig } from './http/types'; +import { BroadcastsService } from './services/broadcasts'; +import { ChannelsService } from './services/channels'; +import { IntegrationsService } from './services/integrations'; +import { JwtService } from './services/jwt'; + +export type * from './http'; +export * from './services/broadcasts'; +export * from './services/channels'; +export * from './services/integrations'; +export * from './services/jwt'; + +export class Client { + public readonly broadcasts: BroadcastsService; + + public readonly integrations: IntegrationsService; + + public readonly jwt: JwtService; + + public readonly channels: ChannelsService; + + constructor(public config: SdkConfig) { + const baseUrl = config.environment || config.baseUrl || Environment.DEFAULT; + this.config = { + ...config, + baseUrl, + }; + this.broadcasts = new BroadcastsService(this.config); + + this.integrations = new IntegrationsService(this.config); + + this.jwt = new JwtService(this.config); + + this.channels = new ChannelsService(this.config); + } + + set baseUrl(baseUrl: string) { + this.broadcasts.baseUrl = baseUrl; + this.integrations.baseUrl = baseUrl; + this.jwt.baseUrl = baseUrl; + this.channels.baseUrl = baseUrl; + } + + set environment(environment: Environment) { + this.broadcasts.baseUrl = environment; + this.integrations.baseUrl = environment; + this.jwt.baseUrl = environment; + this.channels.baseUrl = environment; + } + + set timeout(timeout: number) { + this.broadcasts.timeout = timeout; + this.integrations.timeout = timeout; + this.jwt.timeout = timeout; + this.channels.timeout = timeout; + } + + set token(token: string) { + this.broadcasts.token = token; + this.integrations.token = token; + this.jwt.token = token; + this.channels.token = token; + } +} + +// c029837e0e474b76bc487506e8799df5e3335891efe4fb02bda7a1441840310c diff --git a/packages/project-client/src/services/base-service.ts b/packages/project-client/src/services/base-service.ts new file mode 100644 index 000000000..311c14644 --- /dev/null +++ b/packages/project-client/src/services/base-service.ts @@ -0,0 +1,27 @@ +import { HttpClient } from '../http/client'; +import { Environment } from '../http/environment'; +import { SdkConfig } from '../http/types'; + +export class BaseService { + public client: HttpClient; + + constructor(public config: SdkConfig) { + this.client = new HttpClient(this.config); + } + + set baseUrl(baseUrl: string) { + this.config.baseUrl = baseUrl; + } + + set environment(environment: Environment) { + this.config.environment = environment; + } + + set timeout(timeout: number) { + this.config.timeout = timeout; + } + + set token(token: string) { + this.config.token = token; + } +} diff --git a/packages/project-client/src/services/broadcasts/broadcasts.ts b/packages/project-client/src/services/broadcasts/broadcasts.ts new file mode 100644 index 000000000..ad711f5da --- /dev/null +++ b/packages/project-client/src/services/broadcasts/broadcasts.ts @@ -0,0 +1,80 @@ +import { z } from 'zod'; + +import { SerializationStyle } from '../../http/serialization/base-serializer'; +import { RequestBuilder } from '../../http/transport/request-builder'; +import { ContentType, HttpResponse, RequestConfig } from '../../http/types'; +import { BaseService } from '../base-service'; +import { Broadcast, broadcastRequest, broadcastResponse } from './models/broadcast'; +import { BroadcastListResponse, broadcastListResponseResponse } from './models/broadcast-list-response'; + +export class BroadcastsService extends BaseService { + /** + * Returns a list of broadcasts + * @returns {Promise>} OK + */ + async listBroadcasts(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/broadcasts') + .setRequestSchema(z.any()) + .setResponseSchema(broadcastListResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * Handles the create notification request. + * @returns {Promise>} Created + */ + async createBroadcast(body: Broadcast, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('POST') + .setPath('/broadcasts') + .setRequestSchema(broadcastRequest) + .setResponseSchema(broadcastResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * Returns a broadcast + * @param {string} broadcastId - + * @returns {Promise>} OK + */ + async fetchBroadcast(broadcastId: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/broadcasts/{broadcast_id}') + .setRequestSchema(z.any()) + .setResponseSchema(broadcastResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'broadcast_id', + value: broadcastId, + }) + .build(); + return this.client.call(request); + } +} diff --git a/packages/project-client/src/services/broadcasts/index.ts b/packages/project-client/src/services/broadcasts/index.ts new file mode 100644 index 000000000..7d928e693 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/index.ts @@ -0,0 +1,2 @@ +export { BroadcastsService } from './broadcasts'; +export * from './models'; diff --git a/packages/project-client/src/services/broadcasts/models/broadcast-list-response.ts b/packages/project-client/src/services/broadcasts/models/broadcast-list-response.ts new file mode 100644 index 000000000..ba2b6c613 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/broadcast-list-response.ts @@ -0,0 +1,59 @@ +import { z } from 'zod'; + +import { broadcast, broadcastRequest, broadcastResponse } from './broadcast'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const broadcastListResponse = z.lazy(() => { + return z.object({ + currentPage: z.number(), + perPage: z.number(), + broadcasts: z.array(broadcast), + }); +}); + +/** + * + * @typedef {BroadcastListResponse} broadcastListResponse + * @property {number} - Number of the page returned. + * @property {number} - Number of entities per page. + * @property {Broadcast[]} + */ +export type BroadcastListResponse = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const broadcastListResponseResponse = z.lazy(() => { + return z + .object({ + current_page: z.number(), + per_page: z.number(), + broadcasts: z.array(broadcastResponse), + }) + .transform((data) => ({ + currentPage: data['current_page'], + perPage: data['per_page'], + broadcasts: data['broadcasts'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const broadcastListResponseRequest = z.lazy(() => { + return z + .object({ + currentPage: z.number().nullish(), + perPage: z.number().nullish(), + broadcasts: z.array(broadcastRequest).nullish(), + }) + .transform((data) => ({ + current_page: data['currentPage'], + per_page: data['perPage'], + broadcasts: data['broadcasts'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/broadcast.ts b/packages/project-client/src/services/broadcasts/models/broadcast.ts new file mode 100644 index 000000000..78bdf715b --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/broadcast.ts @@ -0,0 +1,89 @@ +import { z } from 'zod'; + +import { overrides, overridesRequest, overridesResponse } from './overrides'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const broadcast = z.lazy(() => { + return z.object({ + actionUrl: z.string().max(2048).optional().nullable(), + category: z.string().max(100).optional().nullable(), + content: z.string().max(10485760).optional().nullable(), + customAttributes: z.any().optional().nullable(), + overrides: overrides.optional().nullable(), + recipients: z.array(z.any()).min(1).max(1000), + title: z.string().min(1).max(255), + topic: z.string().max(100).optional().nullable(), + }); +}); + +/** + * + * @typedef {Broadcast} broadcast + * @property {string} + * @property {string} + * @property {string} + * @property {any} + * @property {Overrides} + * @property {any[]} + * @property {string} + * @property {string} + */ +export type Broadcast = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const broadcastResponse = z.lazy(() => { + return z + .object({ + action_url: z.string().max(2048).optional().nullable(), + category: z.string().max(100).optional().nullable(), + content: z.string().max(10485760).optional().nullable(), + custom_attributes: z.any().optional().nullable(), + overrides: overridesResponse.optional().nullable(), + recipients: z.array(z.any()).min(1).max(1000), + title: z.string().min(1).max(255), + topic: z.string().max(100).optional().nullable(), + }) + .transform((data) => ({ + actionUrl: data['action_url'], + category: data['category'], + content: data['content'], + customAttributes: data['custom_attributes'], + overrides: data['overrides'], + recipients: data['recipients'], + title: data['title'], + topic: data['topic'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const broadcastRequest = z.lazy(() => { + return z + .object({ + actionUrl: z.string().nullish(), + category: z.string().nullish(), + content: z.string().nullish(), + customAttributes: z.any().nullish(), + overrides: overridesRequest.nullish(), + recipients: z.array(z.any()).nullish(), + title: z.string().nullish(), + topic: z.string().nullish(), + }) + .transform((data) => ({ + action_url: data['actionUrl'], + category: data['category'], + content: data['content'], + custom_attributes: data['customAttributes'], + overrides: data['overrides'], + recipients: data['recipients'], + title: data['title'], + topic: data['topic'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/channels.ts b/packages/project-client/src/services/broadcasts/models/channels.ts new file mode 100644 index 000000000..3232af227 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/channels.ts @@ -0,0 +1,82 @@ +import { z } from 'zod'; + +import { email, emailRequest, emailResponse } from './email'; +import { inApp, inAppRequest, inAppResponse } from './in-app'; +import { mobilePush, mobilePushRequest, mobilePushResponse } from './mobile-push'; +import { slack, slackRequest, slackResponse } from './slack'; +import { sms, smsRequest, smsResponse } from './sms'; +import { webPush, webPushRequest, webPushResponse } from './web-push'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const channels = z.lazy(() => { + return z.object({ + email: email.optional(), + inApp: inApp.optional(), + mobilePush: mobilePush.optional(), + slack: slack.optional(), + sms: sms.optional(), + webPush: webPush.optional(), + }); +}); + +/** + * + * @typedef {Channels} channels + * @property {Email} + * @property {InApp} + * @property {MobilePush} + * @property {Slack} + * @property {Sms} + * @property {WebPush} + */ +export type Channels = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const channelsResponse = z.lazy(() => { + return z + .object({ + email: emailResponse.optional(), + in_app: inAppResponse.optional(), + mobile_push: mobilePushResponse.optional(), + slack: slackResponse.optional(), + sms: smsResponse.optional(), + web_push: webPushResponse.optional(), + }) + .transform((data) => ({ + email: data['email'], + inApp: data['in_app'], + mobilePush: data['mobile_push'], + slack: data['slack'], + sms: data['sms'], + webPush: data['web_push'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const channelsRequest = z.lazy(() => { + return z + .object({ + email: emailRequest.nullish(), + inApp: inAppRequest.nullish(), + mobilePush: mobilePushRequest.nullish(), + slack: slackRequest.nullish(), + sms: smsRequest.nullish(), + webPush: webPushRequest.nullish(), + }) + .transform((data) => ({ + email: data['email'], + in_app: data['inApp'], + mobile_push: data['mobilePush'], + slack: data['slack'], + sms: data['sms'], + web_push: data['webPush'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/email.ts b/packages/project-client/src/services/broadcasts/models/email.ts new file mode 100644 index 000000000..dee39063d --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/email.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const email = z.lazy(() => { + return z.object({ + actionUrl: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }); +}); + +/** + * + * @typedef {Email} email + * @property {string} + * @property {string} + * @property {string} + */ +export type Email = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const emailResponse = z.lazy(() => { + return z + .object({ + action_url: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }) + .transform((data) => ({ + actionUrl: data['action_url'], + content: data['content'], + title: data['title'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const emailRequest = z.lazy(() => { + return z + .object({ actionUrl: z.string().nullish(), content: z.string().nullish(), title: z.string().nullish() }) + .transform((data) => ({ + action_url: data['actionUrl'], + content: data['content'], + title: data['title'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/in-app.ts b/packages/project-client/src/services/broadcasts/models/in-app.ts new file mode 100644 index 000000000..d0b69023a --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/in-app.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const inApp = z.lazy(() => { + return z.object({ + actionUrl: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }); +}); + +/** + * + * @typedef {InApp} inApp + * @property {string} + * @property {string} + * @property {string} + */ +export type InApp = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const inAppResponse = z.lazy(() => { + return z + .object({ + action_url: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }) + .transform((data) => ({ + actionUrl: data['action_url'], + content: data['content'], + title: data['title'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const inAppRequest = z.lazy(() => { + return z + .object({ actionUrl: z.string().nullish(), content: z.string().nullish(), title: z.string().nullish() }) + .transform((data) => ({ + action_url: data['actionUrl'], + content: data['content'], + title: data['title'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/index.ts b/packages/project-client/src/services/broadcasts/models/index.ts new file mode 100644 index 000000000..32846bda1 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/index.ts @@ -0,0 +1,11 @@ +export type { Broadcast } from './broadcast'; +export type { BroadcastListResponse } from './broadcast-list-response'; +export type { Channels } from './channels'; +export type { Email } from './email'; +export type { InApp } from './in-app'; +export type { MobilePush } from './mobile-push'; +export type { Overrides } from './overrides'; +export type { Providers } from './providers'; +export type { Slack } from './slack'; +export type { Sms } from './sms'; +export type { WebPush } from './web-push'; diff --git a/packages/project-client/src/services/broadcasts/models/mobile-push.ts b/packages/project-client/src/services/broadcasts/models/mobile-push.ts new file mode 100644 index 000000000..237be8b19 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/mobile-push.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const mobilePush = z.lazy(() => { + return z.object({ + actionUrl: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }); +}); + +/** + * + * @typedef {MobilePush} mobilePush + * @property {string} + * @property {string} + * @property {string} + */ +export type MobilePush = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const mobilePushResponse = z.lazy(() => { + return z + .object({ + action_url: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }) + .transform((data) => ({ + actionUrl: data['action_url'], + content: data['content'], + title: data['title'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const mobilePushRequest = z.lazy(() => { + return z + .object({ actionUrl: z.string().nullish(), content: z.string().nullish(), title: z.string().nullish() }) + .transform((data) => ({ + action_url: data['actionUrl'], + content: data['content'], + title: data['title'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/overrides.ts b/packages/project-client/src/services/broadcasts/models/overrides.ts new file mode 100644 index 000000000..ba2a06736 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/overrides.ts @@ -0,0 +1,49 @@ +import { z } from 'zod'; + +import { channels, channelsRequest, channelsResponse } from './channels'; +import { providers, providersRequest, providersResponse } from './providers'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const overrides = z.lazy(() => { + return z.object({ + channels: channels.optional(), + providers: providers.optional(), + }); +}); + +/** + * + * @typedef {Overrides} overrides + * @property {Channels} + * @property {Providers} + */ +export type Overrides = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const overridesResponse = z.lazy(() => { + return z + .object({ + channels: channelsResponse.optional(), + providers: providersResponse.optional(), + }) + .transform((data) => ({ + channels: data['channels'], + providers: data['providers'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const overridesRequest = z.lazy(() => { + return z.object({ channels: channelsRequest.nullish(), providers: providersRequest.nullish() }).transform((data) => ({ + channels: data['channels'], + providers: data['providers'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/providers.ts b/packages/project-client/src/services/broadcasts/models/providers.ts new file mode 100644 index 000000000..6f1783604 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/providers.ts @@ -0,0 +1,81 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const providers = z.lazy(() => { + return z.object({ + amazonSes: z.any().optional(), + android: z.any().optional(), + ios: z.any().optional(), + mailgun: z.any().optional(), + postmark: z.any().optional(), + sendgrid: z.any().optional(), + slack: z.any().optional(), + }); +}); + +/** + * + * @typedef {Providers} providers + * @property {any} + * @property {any} + * @property {any} + * @property {any} + * @property {any} + * @property {any} + * @property {any} + */ +export type Providers = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const providersResponse = z.lazy(() => { + return z + .object({ + amazon_ses: z.any().optional(), + android: z.any().optional(), + ios: z.any().optional(), + mailgun: z.any().optional(), + postmark: z.any().optional(), + sendgrid: z.any().optional(), + slack: z.any().optional(), + }) + .transform((data) => ({ + amazonSes: data['amazon_ses'], + android: data['android'], + ios: data['ios'], + mailgun: data['mailgun'], + postmark: data['postmark'], + sendgrid: data['sendgrid'], + slack: data['slack'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const providersRequest = z.lazy(() => { + return z + .object({ + amazonSes: z.any().nullish(), + android: z.any().nullish(), + ios: z.any().nullish(), + mailgun: z.any().nullish(), + postmark: z.any().nullish(), + sendgrid: z.any().nullish(), + slack: z.any().nullish(), + }) + .transform((data) => ({ + amazon_ses: data['amazonSes'], + android: data['android'], + ios: data['ios'], + mailgun: data['mailgun'], + postmark: data['postmark'], + sendgrid: data['sendgrid'], + slack: data['slack'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/slack.ts b/packages/project-client/src/services/broadcasts/models/slack.ts new file mode 100644 index 000000000..f4e955853 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/slack.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const slack = z.lazy(() => { + return z.object({ + actionUrl: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }); +}); + +/** + * + * @typedef {Slack} slack + * @property {string} + * @property {string} + * @property {string} + */ +export type Slack = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const slackResponse = z.lazy(() => { + return z + .object({ + action_url: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }) + .transform((data) => ({ + actionUrl: data['action_url'], + content: data['content'], + title: data['title'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const slackRequest = z.lazy(() => { + return z + .object({ actionUrl: z.string().nullish(), content: z.string().nullish(), title: z.string().nullish() }) + .transform((data) => ({ + action_url: data['actionUrl'], + content: data['content'], + title: data['title'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/sms.ts b/packages/project-client/src/services/broadcasts/models/sms.ts new file mode 100644 index 000000000..b997b876a --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/sms.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const sms = z.lazy(() => { + return z.object({ + actionUrl: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }); +}); + +/** + * + * @typedef {Sms} sms + * @property {string} + * @property {string} + * @property {string} + */ +export type Sms = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const smsResponse = z.lazy(() => { + return z + .object({ + action_url: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }) + .transform((data) => ({ + actionUrl: data['action_url'], + content: data['content'], + title: data['title'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const smsRequest = z.lazy(() => { + return z + .object({ actionUrl: z.string().nullish(), content: z.string().nullish(), title: z.string().nullish() }) + .transform((data) => ({ + action_url: data['actionUrl'], + content: data['content'], + title: data['title'], + })); +}); diff --git a/packages/project-client/src/services/broadcasts/models/web-push.ts b/packages/project-client/src/services/broadcasts/models/web-push.ts new file mode 100644 index 000000000..7cf79a951 --- /dev/null +++ b/packages/project-client/src/services/broadcasts/models/web-push.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const webPush = z.lazy(() => { + return z.object({ + actionUrl: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }); +}); + +/** + * + * @typedef {WebPush} webPush + * @property {string} + * @property {string} + * @property {string} + */ +export type WebPush = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const webPushResponse = z.lazy(() => { + return z + .object({ + action_url: z.string().max(2048).optional().nullable(), + content: z.string().max(1048576).optional(), + title: z.string().min(1).max(255).optional(), + }) + .transform((data) => ({ + actionUrl: data['action_url'], + content: data['content'], + title: data['title'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const webPushRequest = z.lazy(() => { + return z + .object({ actionUrl: z.string().nullish(), content: z.string().nullish(), title: z.string().nullish() }) + .transform((data) => ({ + action_url: data['actionUrl'], + content: data['content'], + title: data['title'], + })); +}); diff --git a/packages/project-client/src/services/channels/channels.ts b/packages/project-client/src/services/channels/channels.ts new file mode 100644 index 000000000..00572e0d8 --- /dev/null +++ b/packages/project-client/src/services/channels/channels.ts @@ -0,0 +1,633 @@ +import { z } from 'zod'; + +import { SerializationStyle } from '../../http/serialization/base-serializer'; +import { RequestBuilder } from '../../http/transport/request-builder'; +import { ContentType, HttpResponse, RequestConfig } from '../../http/types'; +import { BaseService } from '../base-service'; +import { ApnsTokenWithMetadata, apnsTokenWithMetadataResponse } from './models/apns-token-with-metadata'; +import { + ArrayWithMetadataOfApnsToken, + arrayWithMetadataOfApnsTokenResponse, +} from './models/array-with-metadata-of-apns-token'; +import { + ArrayWithMetadataOfFcmToken, + arrayWithMetadataOfFcmTokenResponse, +} from './models/array-with-metadata-of-fcm-token'; +import { + ArrayWithMetadataOfInboxToken, + arrayWithMetadataOfInboxTokenResponse, +} from './models/array-with-metadata-of-inbox-token'; +import { + ArrayWithMetadataOfSlackToken, + arrayWithMetadataOfSlackTokenResponse, +} from './models/array-with-metadata-of-slack-token'; +import { + ArrayWithMetadataOfTeamsToken, + arrayWithMetadataOfTeamsTokenResponse, +} from './models/array-with-metadata-of-teams-token'; +import { + ArrayWithMetadataOfWebPushToken, + arrayWithMetadataOfWebPushTokenResponse, +} from './models/array-with-metadata-of-web-push-token'; +import { DiscardResult, discardResultResponse } from './models/discard-result'; +import { FcmTokenWithMetadata, fcmTokenWithMetadataResponse } from './models/fcm-token-with-metadata'; +import { InboxTokenWithMetadata, inboxTokenWithMetadataResponse } from './models/inbox-token-with-metadata'; +import { SlackTokenWithMetadata, slackTokenWithMetadataResponse } from './models/slack-token-with-metadata'; +import { TeamsTokenWithMetadata, teamsTokenWithMetadataResponse } from './models/teams-token-with-metadata'; +import { WebPushTokenWithMetadata, webPushTokenWithMetadataResponse } from './models/web-push-token-with-metadata'; + +export class ChannelsService extends BaseService { + /** + * + * @param {string} userId - + * @returns {Promise>} OK + */ + async getInAppUserTokens( + userId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/in_app/tokens') + .setRequestSchema(z.any()) + .setResponseSchema(arrayWithMetadataOfInboxTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async getInAppUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/in_app/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(inboxTokenWithMetadataResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardInAppUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/users/{user_id}/channels/in_app/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardResultResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @returns {Promise>} OK + */ + async getMobilePushApnsUserTokens( + userId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/mobile_push/apns/tokens') + .setRequestSchema(z.any()) + .setResponseSchema(arrayWithMetadataOfApnsTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async getMobilePushApnsUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/mobile_push/apns/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(apnsTokenWithMetadataResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardMobilePushApnsUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/users/{user_id}/channels/mobile_push/apns/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardResultResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @returns {Promise>} OK + */ + async getMobilePushFcmUserTokens( + userId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/mobile_push/fcm/tokens') + .setRequestSchema(z.any()) + .setResponseSchema(arrayWithMetadataOfFcmTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async getMobilePushFcmUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/mobile_push/fcm/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(fcmTokenWithMetadataResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardMobilePushFcmUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/users/{user_id}/channels/mobile_push/fcm/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardResultResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @returns {Promise>} OK + */ + async getSlackUserTokens( + userId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/slack/tokens') + .setRequestSchema(z.any()) + .setResponseSchema(arrayWithMetadataOfSlackTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async getSlackUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/slack/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(slackTokenWithMetadataResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardSlackUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/users/{user_id}/channels/slack/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardResultResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @returns {Promise>} OK + */ + async getTeamsUserTokens( + userId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/teams/tokens') + .setRequestSchema(z.any()) + .setResponseSchema(arrayWithMetadataOfTeamsTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async getTeamsUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/teams/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(teamsTokenWithMetadataResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardTeamsUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/users/{user_id}/channels/teams/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardResultResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @returns {Promise>} OK + */ + async getWebPushUserTokens( + userId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/web_push/tokens') + .setRequestSchema(z.any()) + .setResponseSchema(arrayWithMetadataOfWebPushTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async getWebPushUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/users/{user_id}/channels/web_push/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(webPushTokenWithMetadataResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardWebPushUserToken( + userId: string, + tokenId: string, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/users/{user_id}/channels/web_push/tokens/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardResultResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } +} diff --git a/packages/project-client/src/services/channels/index.ts b/packages/project-client/src/services/channels/index.ts new file mode 100644 index 000000000..c98715cb2 --- /dev/null +++ b/packages/project-client/src/services/channels/index.ts @@ -0,0 +1,2 @@ +export { ChannelsService } from './channels'; +export * from './models'; diff --git a/packages/project-client/src/services/channels/models/apns-token-installation-id.ts b/packages/project-client/src/services/channels/models/apns-token-installation-id.ts new file mode 100644 index 000000000..2e2f4bc08 --- /dev/null +++ b/packages/project-client/src/services/channels/models/apns-token-installation-id.ts @@ -0,0 +1,4 @@ +export enum ApnsTokenInstallationId { + DEVELOPMENT = 'development', + PRODUCTION = 'production', +} diff --git a/packages/project-client/src/services/channels/models/apns-token-with-metadata-metadata.ts b/packages/project-client/src/services/channels/models/apns-token-with-metadata-metadata.ts new file mode 100644 index 000000000..4589d744a --- /dev/null +++ b/packages/project-client/src/services/channels/models/apns-token-with-metadata-metadata.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const apnsTokenWithMetadataMetadata = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {ApnsTokenWithMetadataMetadata} apnsTokenWithMetadataMetadata + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type ApnsTokenWithMetadataMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const apnsTokenWithMetadataMetadataResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const apnsTokenWithMetadataMetadataRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/apns-token-with-metadata.ts b/packages/project-client/src/services/channels/models/apns-token-with-metadata.ts new file mode 100644 index 000000000..321a0e4c9 --- /dev/null +++ b/packages/project-client/src/services/channels/models/apns-token-with-metadata.ts @@ -0,0 +1,55 @@ +import { z } from 'zod'; + +import { apnsToken, apnsTokenRequest, apnsTokenResponse } from './apns-token'; +import { + apnsTokenWithMetadataMetadata, + apnsTokenWithMetadataMetadataRequest, + apnsTokenWithMetadataMetadataResponse, +} from './apns-token-with-metadata-metadata'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const apnsTokenWithMetadata = z.lazy(() => { + return z.object({ + data: apnsToken, + metadata: apnsTokenWithMetadataMetadata, + }); +}); + +/** + * + * @typedef {ApnsTokenWithMetadata} apnsTokenWithMetadata + * @property {ApnsToken} + * @property {ApnsTokenWithMetadataMetadata} + */ +export type ApnsTokenWithMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const apnsTokenWithMetadataResponse = z.lazy(() => { + return z + .object({ + data: apnsTokenResponse, + metadata: apnsTokenWithMetadataMetadataResponse, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const apnsTokenWithMetadataRequest = z.lazy(() => { + return z + .object({ data: apnsTokenRequest.nullish(), metadata: apnsTokenWithMetadataMetadataRequest.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/apns-token.ts b/packages/project-client/src/services/channels/models/apns-token.ts new file mode 100644 index 000000000..ce41d600f --- /dev/null +++ b/packages/project-client/src/services/channels/models/apns-token.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const apnsToken = z.lazy(() => { + return z.object({ + deviceToken: z.string().min(64), + installationId: z.string().optional(), + }); +}); + +/** + * + * @typedef {ApnsToken} apnsToken + * @property {string} + * @property {ApnsTokenInstallationId} + */ +export type ApnsToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const apnsTokenResponse = z.lazy(() => { + return z + .object({ + device_token: z.string().min(64), + installation_id: z.string().optional(), + }) + .transform((data) => ({ + deviceToken: data['device_token'], + installationId: data['installation_id'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const apnsTokenRequest = z.lazy(() => { + return z.object({ deviceToken: z.string().nullish(), installationId: z.string().nullish() }).transform((data) => ({ + device_token: data['deviceToken'], + installation_id: data['installationId'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-apns-token-data.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-apns-token-data.ts new file mode 100644 index 000000000..bdbed0503 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-apns-token-data.ts @@ -0,0 +1,49 @@ +import { z } from 'zod'; + +import { apnsToken, apnsTokenRequest, apnsTokenResponse } from './apns-token'; +import { dataMetadata2, dataMetadata2Request, dataMetadata2Response } from './data-metadata-2'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfApnsTokenData = z.lazy(() => { + return z.object({ + data: apnsToken, + metadata: dataMetadata2, + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfApnsTokenData} arrayWithMetadataOfApnsTokenData + * @property {ApnsToken} + * @property {DataMetadata2} + */ +export type ArrayWithMetadataOfApnsTokenData = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfApnsTokenDataResponse = z.lazy(() => { + return z + .object({ + data: apnsTokenResponse, + metadata: dataMetadata2Response, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfApnsTokenDataRequest = z.lazy(() => { + return z.object({ data: apnsTokenRequest.nullish(), metadata: dataMetadata2Request.nullish() }).transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-apns-token.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-apns-token.ts new file mode 100644 index 000000000..1007933b6 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-apns-token.ts @@ -0,0 +1,47 @@ +import { z } from 'zod'; + +import { + arrayWithMetadataOfApnsTokenData, + arrayWithMetadataOfApnsTokenDataRequest, + arrayWithMetadataOfApnsTokenDataResponse, +} from './array-with-metadata-of-apns-token-data'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfApnsToken = z.lazy(() => { + return z.object({ + data: z.array(arrayWithMetadataOfApnsTokenData), + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfApnsToken} arrayWithMetadataOfApnsToken + * @property {ArrayWithMetadataOfApnsTokenData[]} + */ +export type ArrayWithMetadataOfApnsToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfApnsTokenResponse = z.lazy(() => { + return z + .object({ + data: z.array(arrayWithMetadataOfApnsTokenDataResponse), + }) + .transform((data) => ({ + data: data['data'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfApnsTokenRequest = z.lazy(() => { + return z.object({ data: z.array(arrayWithMetadataOfApnsTokenDataRequest).nullish() }).transform((data) => ({ + data: data['data'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-fcm-token-data.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-fcm-token-data.ts new file mode 100644 index 000000000..0af8d31e5 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-fcm-token-data.ts @@ -0,0 +1,49 @@ +import { z } from 'zod'; + +import { dataMetadata3, dataMetadata3Request, dataMetadata3Response } from './data-metadata-3'; +import { fcmToken, fcmTokenRequest, fcmTokenResponse } from './fcm-token'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfFcmTokenData = z.lazy(() => { + return z.object({ + data: fcmToken, + metadata: dataMetadata3, + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfFcmTokenData} arrayWithMetadataOfFcmTokenData + * @property {FcmToken} + * @property {DataMetadata3} + */ +export type ArrayWithMetadataOfFcmTokenData = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfFcmTokenDataResponse = z.lazy(() => { + return z + .object({ + data: fcmTokenResponse, + metadata: dataMetadata3Response, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfFcmTokenDataRequest = z.lazy(() => { + return z.object({ data: fcmTokenRequest.nullish(), metadata: dataMetadata3Request.nullish() }).transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-fcm-token.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-fcm-token.ts new file mode 100644 index 000000000..a39c8c029 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-fcm-token.ts @@ -0,0 +1,47 @@ +import { z } from 'zod'; + +import { + arrayWithMetadataOfFcmTokenData, + arrayWithMetadataOfFcmTokenDataRequest, + arrayWithMetadataOfFcmTokenDataResponse, +} from './array-with-metadata-of-fcm-token-data'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfFcmToken = z.lazy(() => { + return z.object({ + data: z.array(arrayWithMetadataOfFcmTokenData), + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfFcmToken} arrayWithMetadataOfFcmToken + * @property {ArrayWithMetadataOfFcmTokenData[]} + */ +export type ArrayWithMetadataOfFcmToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfFcmTokenResponse = z.lazy(() => { + return z + .object({ + data: z.array(arrayWithMetadataOfFcmTokenDataResponse), + }) + .transform((data) => ({ + data: data['data'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfFcmTokenRequest = z.lazy(() => { + return z.object({ data: z.array(arrayWithMetadataOfFcmTokenDataRequest).nullish() }).transform((data) => ({ + data: data['data'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-inbox-token-data.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-inbox-token-data.ts new file mode 100644 index 000000000..72cef23ff --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-inbox-token-data.ts @@ -0,0 +1,51 @@ +import { z } from 'zod'; + +import { dataMetadata1, dataMetadata1Request, dataMetadata1Response } from './data-metadata-1'; +import { inboxToken, inboxTokenRequest, inboxTokenResponse } from './inbox-token'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfInboxTokenData = z.lazy(() => { + return z.object({ + data: inboxToken, + metadata: dataMetadata1, + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfInboxTokenData} arrayWithMetadataOfInboxTokenData + * @property {InboxToken} + * @property {DataMetadata1} + */ +export type ArrayWithMetadataOfInboxTokenData = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfInboxTokenDataResponse = z.lazy(() => { + return z + .object({ + data: inboxTokenResponse, + metadata: dataMetadata1Response, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfInboxTokenDataRequest = z.lazy(() => { + return z + .object({ data: inboxTokenRequest.nullish(), metadata: dataMetadata1Request.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-inbox-token.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-inbox-token.ts new file mode 100644 index 000000000..02f34cdb0 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-inbox-token.ts @@ -0,0 +1,47 @@ +import { z } from 'zod'; + +import { + arrayWithMetadataOfInboxTokenData, + arrayWithMetadataOfInboxTokenDataRequest, + arrayWithMetadataOfInboxTokenDataResponse, +} from './array-with-metadata-of-inbox-token-data'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfInboxToken = z.lazy(() => { + return z.object({ + data: z.array(arrayWithMetadataOfInboxTokenData), + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfInboxToken} arrayWithMetadataOfInboxToken + * @property {ArrayWithMetadataOfInboxTokenData[]} + */ +export type ArrayWithMetadataOfInboxToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfInboxTokenResponse = z.lazy(() => { + return z + .object({ + data: z.array(arrayWithMetadataOfInboxTokenDataResponse), + }) + .transform((data) => ({ + data: data['data'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfInboxTokenRequest = z.lazy(() => { + return z.object({ data: z.array(arrayWithMetadataOfInboxTokenDataRequest).nullish() }).transform((data) => ({ + data: data['data'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-slack-token-data.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-slack-token-data.ts new file mode 100644 index 000000000..0ab60fe7a --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-slack-token-data.ts @@ -0,0 +1,51 @@ +import { z } from 'zod'; + +import { dataMetadata4, dataMetadata4Request, dataMetadata4Response } from './data-metadata-4'; +import { slackToken, slackTokenRequest, slackTokenResponse } from './slack-token'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfSlackTokenData = z.lazy(() => { + return z.object({ + data: slackToken, + metadata: dataMetadata4, + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfSlackTokenData} arrayWithMetadataOfSlackTokenData + * @property {SlackToken} + * @property {DataMetadata4} + */ +export type ArrayWithMetadataOfSlackTokenData = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfSlackTokenDataResponse = z.lazy(() => { + return z + .object({ + data: slackTokenResponse, + metadata: dataMetadata4Response, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfSlackTokenDataRequest = z.lazy(() => { + return z + .object({ data: slackTokenRequest.nullish(), metadata: dataMetadata4Request.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-slack-token.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-slack-token.ts new file mode 100644 index 000000000..3fcd51ec0 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-slack-token.ts @@ -0,0 +1,47 @@ +import { z } from 'zod'; + +import { + arrayWithMetadataOfSlackTokenData, + arrayWithMetadataOfSlackTokenDataRequest, + arrayWithMetadataOfSlackTokenDataResponse, +} from './array-with-metadata-of-slack-token-data'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfSlackToken = z.lazy(() => { + return z.object({ + data: z.array(arrayWithMetadataOfSlackTokenData), + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfSlackToken} arrayWithMetadataOfSlackToken + * @property {ArrayWithMetadataOfSlackTokenData[]} + */ +export type ArrayWithMetadataOfSlackToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfSlackTokenResponse = z.lazy(() => { + return z + .object({ + data: z.array(arrayWithMetadataOfSlackTokenDataResponse), + }) + .transform((data) => ({ + data: data['data'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfSlackTokenRequest = z.lazy(() => { + return z.object({ data: z.array(arrayWithMetadataOfSlackTokenDataRequest).nullish() }).transform((data) => ({ + data: data['data'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-teams-token-data.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-teams-token-data.ts new file mode 100644 index 000000000..db76fcf16 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-teams-token-data.ts @@ -0,0 +1,48 @@ +import { z } from 'zod'; + +import { dataMetadata5, dataMetadata5Request, dataMetadata5Response } from './data-metadata-5'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfTeamsTokenData = z.lazy(() => { + return z.object({ + data: z.any(), + metadata: dataMetadata5, + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfTeamsTokenData} arrayWithMetadataOfTeamsTokenData + * @property {any} + * @property {DataMetadata5} + */ +export type ArrayWithMetadataOfTeamsTokenData = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfTeamsTokenDataResponse = z.lazy(() => { + return z + .object({ + data: z.any(), + metadata: dataMetadata5Response, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfTeamsTokenDataRequest = z.lazy(() => { + return z.object({ data: z.any().nullish(), metadata: dataMetadata5Request.nullish() }).transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-teams-token.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-teams-token.ts new file mode 100644 index 000000000..8bb4d30d8 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-teams-token.ts @@ -0,0 +1,47 @@ +import { z } from 'zod'; + +import { + arrayWithMetadataOfTeamsTokenData, + arrayWithMetadataOfTeamsTokenDataRequest, + arrayWithMetadataOfTeamsTokenDataResponse, +} from './array-with-metadata-of-teams-token-data'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfTeamsToken = z.lazy(() => { + return z.object({ + data: z.array(arrayWithMetadataOfTeamsTokenData), + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfTeamsToken} arrayWithMetadataOfTeamsToken + * @property {ArrayWithMetadataOfTeamsTokenData[]} + */ +export type ArrayWithMetadataOfTeamsToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfTeamsTokenResponse = z.lazy(() => { + return z + .object({ + data: z.array(arrayWithMetadataOfTeamsTokenDataResponse), + }) + .transform((data) => ({ + data: data['data'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfTeamsTokenRequest = z.lazy(() => { + return z.object({ data: z.array(arrayWithMetadataOfTeamsTokenDataRequest).nullish() }).transform((data) => ({ + data: data['data'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-web-push-token-data.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-web-push-token-data.ts new file mode 100644 index 000000000..9095a04ac --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-web-push-token-data.ts @@ -0,0 +1,51 @@ +import { z } from 'zod'; + +import { dataMetadata6, dataMetadata6Request, dataMetadata6Response } from './data-metadata-6'; +import { webPushToken, webPushTokenRequest, webPushTokenResponse } from './web-push-token'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfWebPushTokenData = z.lazy(() => { + return z.object({ + data: webPushToken, + metadata: dataMetadata6, + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfWebPushTokenData} arrayWithMetadataOfWebPushTokenData + * @property {WebPushToken} + * @property {DataMetadata6} + */ +export type ArrayWithMetadataOfWebPushTokenData = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfWebPushTokenDataResponse = z.lazy(() => { + return z + .object({ + data: webPushTokenResponse, + metadata: dataMetadata6Response, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfWebPushTokenDataRequest = z.lazy(() => { + return z + .object({ data: webPushTokenRequest.nullish(), metadata: dataMetadata6Request.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/array-with-metadata-of-web-push-token.ts b/packages/project-client/src/services/channels/models/array-with-metadata-of-web-push-token.ts new file mode 100644 index 000000000..d4df1ad02 --- /dev/null +++ b/packages/project-client/src/services/channels/models/array-with-metadata-of-web-push-token.ts @@ -0,0 +1,47 @@ +import { z } from 'zod'; + +import { + arrayWithMetadataOfWebPushTokenData, + arrayWithMetadataOfWebPushTokenDataRequest, + arrayWithMetadataOfWebPushTokenDataResponse, +} from './array-with-metadata-of-web-push-token-data'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const arrayWithMetadataOfWebPushToken = z.lazy(() => { + return z.object({ + data: z.array(arrayWithMetadataOfWebPushTokenData), + }); +}); + +/** + * + * @typedef {ArrayWithMetadataOfWebPushToken} arrayWithMetadataOfWebPushToken + * @property {ArrayWithMetadataOfWebPushTokenData[]} + */ +export type ArrayWithMetadataOfWebPushToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfWebPushTokenResponse = z.lazy(() => { + return z + .object({ + data: z.array(arrayWithMetadataOfWebPushTokenDataResponse), + }) + .transform((data) => ({ + data: data['data'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const arrayWithMetadataOfWebPushTokenRequest = z.lazy(() => { + return z.object({ data: z.array(arrayWithMetadataOfWebPushTokenDataRequest).nullish() }).transform((data) => ({ + data: data['data'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/data-metadata-1.ts b/packages/project-client/src/services/channels/models/data-metadata-1.ts new file mode 100644 index 000000000..732f8247f --- /dev/null +++ b/packages/project-client/src/services/channels/models/data-metadata-1.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const dataMetadata1 = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {DataMetadata1} dataMetadata1 + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type DataMetadata1 = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata1Response = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata1Request = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/data-metadata-2.ts b/packages/project-client/src/services/channels/models/data-metadata-2.ts new file mode 100644 index 000000000..0ff39c53b --- /dev/null +++ b/packages/project-client/src/services/channels/models/data-metadata-2.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const dataMetadata2 = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {DataMetadata2} dataMetadata2 + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type DataMetadata2 = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata2Response = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata2Request = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/data-metadata-3.ts b/packages/project-client/src/services/channels/models/data-metadata-3.ts new file mode 100644 index 000000000..3be1233fd --- /dev/null +++ b/packages/project-client/src/services/channels/models/data-metadata-3.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const dataMetadata3 = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {DataMetadata3} dataMetadata3 + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type DataMetadata3 = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata3Response = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata3Request = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/data-metadata-4.ts b/packages/project-client/src/services/channels/models/data-metadata-4.ts new file mode 100644 index 000000000..369befbeb --- /dev/null +++ b/packages/project-client/src/services/channels/models/data-metadata-4.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const dataMetadata4 = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {DataMetadata4} dataMetadata4 + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type DataMetadata4 = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata4Response = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata4Request = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/data-metadata-5.ts b/packages/project-client/src/services/channels/models/data-metadata-5.ts new file mode 100644 index 000000000..e8761fa95 --- /dev/null +++ b/packages/project-client/src/services/channels/models/data-metadata-5.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const dataMetadata5 = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {DataMetadata5} dataMetadata5 + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type DataMetadata5 = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata5Response = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata5Request = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/data-metadata-6.ts b/packages/project-client/src/services/channels/models/data-metadata-6.ts new file mode 100644 index 000000000..de750a4d5 --- /dev/null +++ b/packages/project-client/src/services/channels/models/data-metadata-6.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const dataMetadata6 = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {DataMetadata6} dataMetadata6 + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type DataMetadata6 = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata6Response = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const dataMetadata6Request = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/discard-result.ts b/packages/project-client/src/services/channels/models/discard-result.ts new file mode 100644 index 000000000..ae59d4a30 --- /dev/null +++ b/packages/project-client/src/services/channels/models/discard-result.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const discardResult = z.lazy(() => { + return z.object({ + discardedAt: z.string().optional(), + id: z.string().optional(), + }); +}); + +/** + * + * @typedef {DiscardResult} discardResult + * @property {string} + * @property {string} + */ +export type DiscardResult = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const discardResultResponse = z.lazy(() => { + return z + .object({ + discarded_at: z.string().optional(), + id: z.string().optional(), + }) + .transform((data) => ({ + discardedAt: data['discarded_at'], + id: data['id'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const discardResultRequest = z.lazy(() => { + return z.object({ discardedAt: z.string().nullish(), id: z.string().nullish() }).transform((data) => ({ + discarded_at: data['discardedAt'], + id: data['id'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/fcm-token-installation-id.ts b/packages/project-client/src/services/channels/models/fcm-token-installation-id.ts new file mode 100644 index 000000000..e1f07e230 --- /dev/null +++ b/packages/project-client/src/services/channels/models/fcm-token-installation-id.ts @@ -0,0 +1,4 @@ +export enum FcmTokenInstallationId { + DEVELOPMENT = 'development', + PRODUCTION = 'production', +} diff --git a/packages/project-client/src/services/channels/models/fcm-token-with-metadata-metadata.ts b/packages/project-client/src/services/channels/models/fcm-token-with-metadata-metadata.ts new file mode 100644 index 000000000..ed8f1b7c6 --- /dev/null +++ b/packages/project-client/src/services/channels/models/fcm-token-with-metadata-metadata.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const fcmTokenWithMetadataMetadata = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {FcmTokenWithMetadataMetadata} fcmTokenWithMetadataMetadata + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type FcmTokenWithMetadataMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const fcmTokenWithMetadataMetadataResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const fcmTokenWithMetadataMetadataRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/fcm-token-with-metadata.ts b/packages/project-client/src/services/channels/models/fcm-token-with-metadata.ts new file mode 100644 index 000000000..23573fb01 --- /dev/null +++ b/packages/project-client/src/services/channels/models/fcm-token-with-metadata.ts @@ -0,0 +1,55 @@ +import { z } from 'zod'; + +import { fcmToken, fcmTokenRequest, fcmTokenResponse } from './fcm-token'; +import { + fcmTokenWithMetadataMetadata, + fcmTokenWithMetadataMetadataRequest, + fcmTokenWithMetadataMetadataResponse, +} from './fcm-token-with-metadata-metadata'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const fcmTokenWithMetadata = z.lazy(() => { + return z.object({ + data: fcmToken, + metadata: fcmTokenWithMetadataMetadata, + }); +}); + +/** + * + * @typedef {FcmTokenWithMetadata} fcmTokenWithMetadata + * @property {FcmToken} + * @property {FcmTokenWithMetadataMetadata} + */ +export type FcmTokenWithMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const fcmTokenWithMetadataResponse = z.lazy(() => { + return z + .object({ + data: fcmTokenResponse, + metadata: fcmTokenWithMetadataMetadataResponse, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const fcmTokenWithMetadataRequest = z.lazy(() => { + return z + .object({ data: fcmTokenRequest.nullish(), metadata: fcmTokenWithMetadataMetadataRequest.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/fcm-token.ts b/packages/project-client/src/services/channels/models/fcm-token.ts new file mode 100644 index 000000000..8b9052d1a --- /dev/null +++ b/packages/project-client/src/services/channels/models/fcm-token.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const fcmToken = z.lazy(() => { + return z.object({ + deviceToken: z.string().min(64), + installationId: z.string().optional(), + }); +}); + +/** + * + * @typedef {FcmToken} fcmToken + * @property {string} + * @property {FcmTokenInstallationId} + */ +export type FcmToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const fcmTokenResponse = z.lazy(() => { + return z + .object({ + device_token: z.string().min(64), + installation_id: z.string().optional(), + }) + .transform((data) => ({ + deviceToken: data['device_token'], + installationId: data['installation_id'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const fcmTokenRequest = z.lazy(() => { + return z.object({ deviceToken: z.string().nullish(), installationId: z.string().nullish() }).transform((data) => ({ + device_token: data['deviceToken'], + installation_id: data['installationId'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/inbox-token-with-metadata-metadata.ts b/packages/project-client/src/services/channels/models/inbox-token-with-metadata-metadata.ts new file mode 100644 index 000000000..47a99e2c3 --- /dev/null +++ b/packages/project-client/src/services/channels/models/inbox-token-with-metadata-metadata.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const inboxTokenWithMetadataMetadata = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {InboxTokenWithMetadataMetadata} inboxTokenWithMetadataMetadata + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type InboxTokenWithMetadataMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const inboxTokenWithMetadataMetadataResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const inboxTokenWithMetadataMetadataRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/inbox-token-with-metadata.ts b/packages/project-client/src/services/channels/models/inbox-token-with-metadata.ts new file mode 100644 index 000000000..14cb0bd2d --- /dev/null +++ b/packages/project-client/src/services/channels/models/inbox-token-with-metadata.ts @@ -0,0 +1,55 @@ +import { z } from 'zod'; + +import { inboxToken, inboxTokenRequest, inboxTokenResponse } from './inbox-token'; +import { + inboxTokenWithMetadataMetadata, + inboxTokenWithMetadataMetadataRequest, + inboxTokenWithMetadataMetadataResponse, +} from './inbox-token-with-metadata-metadata'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const inboxTokenWithMetadata = z.lazy(() => { + return z.object({ + data: inboxToken, + metadata: inboxTokenWithMetadataMetadata, + }); +}); + +/** + * + * @typedef {InboxTokenWithMetadata} inboxTokenWithMetadata + * @property {InboxToken} + * @property {InboxTokenWithMetadataMetadata} + */ +export type InboxTokenWithMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const inboxTokenWithMetadataResponse = z.lazy(() => { + return z + .object({ + data: inboxTokenResponse, + metadata: inboxTokenWithMetadataMetadataResponse, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const inboxTokenWithMetadataRequest = z.lazy(() => { + return z + .object({ data: inboxTokenRequest.nullish(), metadata: inboxTokenWithMetadataMetadataRequest.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/inbox-token.ts b/packages/project-client/src/services/channels/models/inbox-token.ts new file mode 100644 index 000000000..cf8432cdc --- /dev/null +++ b/packages/project-client/src/services/channels/models/inbox-token.ts @@ -0,0 +1,41 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const inboxToken = z.lazy(() => { + return z.object({ + token: z.string(), + }); +}); + +/** + * + * @typedef {InboxToken} inboxToken + * @property {string} + */ +export type InboxToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const inboxTokenResponse = z.lazy(() => { + return z + .object({ + token: z.string(), + }) + .transform((data) => ({ + token: data['token'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const inboxTokenRequest = z.lazy(() => { + return z.object({ token: z.string().nullish() }).transform((data) => ({ + token: data['token'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/index.ts b/packages/project-client/src/services/channels/models/index.ts new file mode 100644 index 000000000..15a326e2e --- /dev/null +++ b/packages/project-client/src/services/channels/models/index.ts @@ -0,0 +1,41 @@ +export type { ApnsToken } from './apns-token'; +export { ApnsTokenInstallationId } from './apns-token-installation-id'; +export type { ApnsTokenWithMetadata } from './apns-token-with-metadata'; +export type { ApnsTokenWithMetadataMetadata } from './apns-token-with-metadata-metadata'; +export type { ArrayWithMetadataOfApnsToken } from './array-with-metadata-of-apns-token'; +export type { ArrayWithMetadataOfApnsTokenData } from './array-with-metadata-of-apns-token-data'; +export type { ArrayWithMetadataOfFcmToken } from './array-with-metadata-of-fcm-token'; +export type { ArrayWithMetadataOfFcmTokenData } from './array-with-metadata-of-fcm-token-data'; +export type { ArrayWithMetadataOfInboxToken } from './array-with-metadata-of-inbox-token'; +export type { ArrayWithMetadataOfInboxTokenData } from './array-with-metadata-of-inbox-token-data'; +export type { ArrayWithMetadataOfSlackToken } from './array-with-metadata-of-slack-token'; +export type { ArrayWithMetadataOfSlackTokenData } from './array-with-metadata-of-slack-token-data'; +export type { ArrayWithMetadataOfTeamsToken } from './array-with-metadata-of-teams-token'; +export type { ArrayWithMetadataOfTeamsTokenData } from './array-with-metadata-of-teams-token-data'; +export type { ArrayWithMetadataOfWebPushToken } from './array-with-metadata-of-web-push-token'; +export type { ArrayWithMetadataOfWebPushTokenData } from './array-with-metadata-of-web-push-token-data'; +export type { DataMetadata1 } from './data-metadata-1'; +export type { DataMetadata2 } from './data-metadata-2'; +export type { DataMetadata3 } from './data-metadata-3'; +export type { DataMetadata4 } from './data-metadata-4'; +export type { DataMetadata5 } from './data-metadata-5'; +export type { DataMetadata6 } from './data-metadata-6'; +export type { DiscardResult } from './discard-result'; +export type { FcmToken } from './fcm-token'; +export { FcmTokenInstallationId } from './fcm-token-installation-id'; +export type { FcmTokenWithMetadata } from './fcm-token-with-metadata'; +export type { FcmTokenWithMetadataMetadata } from './fcm-token-with-metadata-metadata'; +export type { InboxToken } from './inbox-token'; +export type { InboxTokenWithMetadata } from './inbox-token-with-metadata'; +export type { InboxTokenWithMetadataMetadata } from './inbox-token-with-metadata-metadata'; +export type { Keys } from './keys'; +export type { Oauth } from './oauth'; +export type { SlackToken } from './slack-token'; +export type { SlackTokenWithMetadata } from './slack-token-with-metadata'; +export type { SlackTokenWithMetadataMetadata } from './slack-token-with-metadata-metadata'; +export type { TeamsTokenWithMetadata } from './teams-token-with-metadata'; +export type { TeamsTokenWithMetadataMetadata } from './teams-token-with-metadata-metadata'; +export type { WebPushToken } from './web-push-token'; +export type { WebPushTokenWithMetadata } from './web-push-token-with-metadata'; +export type { WebPushTokenWithMetadataMetadata } from './web-push-token-with-metadata-metadata'; +export type { Webhook } from './webhook'; diff --git a/packages/project-client/src/services/channels/models/keys.ts b/packages/project-client/src/services/channels/models/keys.ts new file mode 100644 index 000000000..3c59e4017 --- /dev/null +++ b/packages/project-client/src/services/channels/models/keys.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const keys = z.lazy(() => { + return z.object({ + auth: z.string(), + p256dh: z.string(), + }); +}); + +/** + * + * @typedef {Keys} keys + * @property {string} + * @property {string} + */ +export type Keys = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const keysResponse = z.lazy(() => { + return z + .object({ + auth: z.string(), + p256dh: z.string(), + }) + .transform((data) => ({ + auth: data['auth'], + p256dh: data['p256dh'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const keysRequest = z.lazy(() => { + return z.object({ auth: z.string().nullish(), p256dh: z.string().nullish() }).transform((data) => ({ + auth: data['auth'], + p256dh: data['p256dh'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/oauth.ts b/packages/project-client/src/services/channels/models/oauth.ts new file mode 100644 index 000000000..e5802f93b --- /dev/null +++ b/packages/project-client/src/services/channels/models/oauth.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const oauth = z.lazy(() => { + return z.object({ + channelId: z.string(), + installationId: z.string(), + scope: z.string().optional(), + }); +}); + +/** + * + * @typedef {Oauth} oauth + * @property {string} + * @property {string} + * @property {string} + */ +export type Oauth = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const oauthResponse = z.lazy(() => { + return z + .object({ + channel_id: z.string(), + installation_id: z.string(), + scope: z.string().optional(), + }) + .transform((data) => ({ + channelId: data['channel_id'], + installationId: data['installation_id'], + scope: data['scope'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const oauthRequest = z.lazy(() => { + return z + .object({ channelId: z.string().nullish(), installationId: z.string().nullish(), scope: z.string().nullish() }) + .transform((data) => ({ + channel_id: data['channelId'], + installation_id: data['installationId'], + scope: data['scope'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/slack-token-with-metadata-metadata.ts b/packages/project-client/src/services/channels/models/slack-token-with-metadata-metadata.ts new file mode 100644 index 000000000..3e82d9b20 --- /dev/null +++ b/packages/project-client/src/services/channels/models/slack-token-with-metadata-metadata.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const slackTokenWithMetadataMetadata = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {SlackTokenWithMetadataMetadata} slackTokenWithMetadataMetadata + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type SlackTokenWithMetadataMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const slackTokenWithMetadataMetadataResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const slackTokenWithMetadataMetadataRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/slack-token-with-metadata.ts b/packages/project-client/src/services/channels/models/slack-token-with-metadata.ts new file mode 100644 index 000000000..2afc50fe1 --- /dev/null +++ b/packages/project-client/src/services/channels/models/slack-token-with-metadata.ts @@ -0,0 +1,55 @@ +import { z } from 'zod'; + +import { slackToken, slackTokenRequest, slackTokenResponse } from './slack-token'; +import { + slackTokenWithMetadataMetadata, + slackTokenWithMetadataMetadataRequest, + slackTokenWithMetadataMetadataResponse, +} from './slack-token-with-metadata-metadata'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const slackTokenWithMetadata = z.lazy(() => { + return z.object({ + data: slackToken, + metadata: slackTokenWithMetadataMetadata, + }); +}); + +/** + * + * @typedef {SlackTokenWithMetadata} slackTokenWithMetadata + * @property {SlackToken} + * @property {SlackTokenWithMetadataMetadata} + */ +export type SlackTokenWithMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const slackTokenWithMetadataResponse = z.lazy(() => { + return z + .object({ + data: slackTokenResponse, + metadata: slackTokenWithMetadataMetadataResponse, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const slackTokenWithMetadataRequest = z.lazy(() => { + return z + .object({ data: slackTokenRequest.nullish(), metadata: slackTokenWithMetadataMetadataRequest.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/slack-token.ts b/packages/project-client/src/services/channels/models/slack-token.ts new file mode 100644 index 000000000..c8087f811 --- /dev/null +++ b/packages/project-client/src/services/channels/models/slack-token.ts @@ -0,0 +1,49 @@ +import { z } from 'zod'; + +import { oauth, oauthRequest, oauthResponse } from './oauth'; +import { webhook, webhookRequest, webhookResponse } from './webhook'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const slackToken = z.lazy(() => { + return z.object({ + oauth: oauth.optional(), + webhook: webhook.optional(), + }); +}); + +/** + * + * @typedef {SlackToken} slackToken + * @property {Oauth} + * @property {Webhook} + */ +export type SlackToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const slackTokenResponse = z.lazy(() => { + return z + .object({ + oauth: oauthResponse.optional(), + webhook: webhookResponse.optional(), + }) + .transform((data) => ({ + oauth: data['oauth'], + webhook: data['webhook'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const slackTokenRequest = z.lazy(() => { + return z.object({ oauth: oauthRequest.nullish(), webhook: webhookRequest.nullish() }).transform((data) => ({ + oauth: data['oauth'], + webhook: data['webhook'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/teams-token-with-metadata-metadata.ts b/packages/project-client/src/services/channels/models/teams-token-with-metadata-metadata.ts new file mode 100644 index 000000000..8a5e8a0b2 --- /dev/null +++ b/packages/project-client/src/services/channels/models/teams-token-with-metadata-metadata.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const teamsTokenWithMetadataMetadata = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {TeamsTokenWithMetadataMetadata} teamsTokenWithMetadataMetadata + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type TeamsTokenWithMetadataMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const teamsTokenWithMetadataMetadataResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const teamsTokenWithMetadataMetadataRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/teams-token-with-metadata.ts b/packages/project-client/src/services/channels/models/teams-token-with-metadata.ts new file mode 100644 index 000000000..d64c03b65 --- /dev/null +++ b/packages/project-client/src/services/channels/models/teams-token-with-metadata.ts @@ -0,0 +1,54 @@ +import { z } from 'zod'; + +import { + teamsTokenWithMetadataMetadata, + teamsTokenWithMetadataMetadataRequest, + teamsTokenWithMetadataMetadataResponse, +} from './teams-token-with-metadata-metadata'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const teamsTokenWithMetadata = z.lazy(() => { + return z.object({ + data: z.any(), + metadata: teamsTokenWithMetadataMetadata, + }); +}); + +/** + * + * @typedef {TeamsTokenWithMetadata} teamsTokenWithMetadata + * @property {any} + * @property {TeamsTokenWithMetadataMetadata} + */ +export type TeamsTokenWithMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const teamsTokenWithMetadataResponse = z.lazy(() => { + return z + .object({ + data: z.any(), + metadata: teamsTokenWithMetadataMetadataResponse, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const teamsTokenWithMetadataRequest = z.lazy(() => { + return z + .object({ data: z.any().nullish(), metadata: teamsTokenWithMetadataMetadataRequest.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/web-push-token-with-metadata-metadata.ts b/packages/project-client/src/services/channels/models/web-push-token-with-metadata-metadata.ts new file mode 100644 index 000000000..9d3dd1698 --- /dev/null +++ b/packages/project-client/src/services/channels/models/web-push-token-with-metadata-metadata.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const webPushTokenWithMetadataMetadata = z.lazy(() => { + return z.object({ + createdAt: z.string(), + discardedAt: z.string().optional(), + id: z.string(), + updatedAt: z.string().optional(), + }); +}); + +/** + * + * @typedef {WebPushTokenWithMetadataMetadata} webPushTokenWithMetadataMetadata + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type WebPushTokenWithMetadataMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const webPushTokenWithMetadataMetadataResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + discarded_at: z.string().optional(), + id: z.string(), + updated_at: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + discardedAt: data['discarded_at'], + id: data['id'], + updatedAt: data['updated_at'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const webPushTokenWithMetadataMetadataRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + discardedAt: z.string().nullish(), + id: z.string().nullish(), + updatedAt: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + discarded_at: data['discardedAt'], + id: data['id'], + updated_at: data['updatedAt'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/web-push-token-with-metadata.ts b/packages/project-client/src/services/channels/models/web-push-token-with-metadata.ts new file mode 100644 index 000000000..3a774fb10 --- /dev/null +++ b/packages/project-client/src/services/channels/models/web-push-token-with-metadata.ts @@ -0,0 +1,55 @@ +import { z } from 'zod'; + +import { webPushToken, webPushTokenRequest, webPushTokenResponse } from './web-push-token'; +import { + webPushTokenWithMetadataMetadata, + webPushTokenWithMetadataMetadataRequest, + webPushTokenWithMetadataMetadataResponse, +} from './web-push-token-with-metadata-metadata'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const webPushTokenWithMetadata = z.lazy(() => { + return z.object({ + data: webPushToken, + metadata: webPushTokenWithMetadataMetadata, + }); +}); + +/** + * + * @typedef {WebPushTokenWithMetadata} webPushTokenWithMetadata + * @property {WebPushToken} + * @property {WebPushTokenWithMetadataMetadata} + */ +export type WebPushTokenWithMetadata = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const webPushTokenWithMetadataResponse = z.lazy(() => { + return z + .object({ + data: webPushTokenResponse, + metadata: webPushTokenWithMetadataMetadataResponse, + }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const webPushTokenWithMetadataRequest = z.lazy(() => { + return z + .object({ data: webPushTokenRequest.nullish(), metadata: webPushTokenWithMetadataMetadataRequest.nullish() }) + .transform((data) => ({ + data: data['data'], + metadata: data['metadata'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/web-push-token.ts b/packages/project-client/src/services/channels/models/web-push-token.ts new file mode 100644 index 000000000..03bb666e6 --- /dev/null +++ b/packages/project-client/src/services/channels/models/web-push-token.ts @@ -0,0 +1,48 @@ +import { z } from 'zod'; + +import { keys, keysRequest, keysResponse } from './keys'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const webPushToken = z.lazy(() => { + return z.object({ + endpoint: z.string(), + keys: keys, + }); +}); + +/** + * + * @typedef {WebPushToken} webPushToken + * @property {string} + * @property {Keys} + */ +export type WebPushToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const webPushTokenResponse = z.lazy(() => { + return z + .object({ + endpoint: z.string(), + keys: keysResponse, + }) + .transform((data) => ({ + endpoint: data['endpoint'], + keys: data['keys'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const webPushTokenRequest = z.lazy(() => { + return z.object({ endpoint: z.string().nullish(), keys: keysRequest.nullish() }).transform((data) => ({ + endpoint: data['endpoint'], + keys: data['keys'], + })); +}); diff --git a/packages/project-client/src/services/channels/models/webhook.ts b/packages/project-client/src/services/channels/models/webhook.ts new file mode 100644 index 000000000..80d30b9ff --- /dev/null +++ b/packages/project-client/src/services/channels/models/webhook.ts @@ -0,0 +1,41 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const webhook = z.lazy(() => { + return z.object({ + url: z.string(), + }); +}); + +/** + * + * @typedef {Webhook} webhook + * @property {string} + */ +export type Webhook = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const webhookResponse = z.lazy(() => { + return z + .object({ + url: z.string(), + }) + .transform((data) => ({ + url: data['url'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const webhookRequest = z.lazy(() => { + return z.object({ url: z.string().nullish() }).transform((data) => ({ + url: data['url'], + })); +}); diff --git a/packages/project-client/src/services/integrations/index.ts b/packages/project-client/src/services/integrations/index.ts new file mode 100644 index 000000000..4887df074 --- /dev/null +++ b/packages/project-client/src/services/integrations/index.ts @@ -0,0 +1,2 @@ +export { IntegrationsService } from './integrations'; +export * from './models'; diff --git a/packages/project-client/src/services/integrations/integrations.ts b/packages/project-client/src/services/integrations/integrations.ts new file mode 100644 index 000000000..5a130596e --- /dev/null +++ b/packages/project-client/src/services/integrations/integrations.ts @@ -0,0 +1,1234 @@ +import { z } from 'zod'; + +import { SerializationStyle } from '../../http/serialization/base-serializer'; +import { RequestBuilder } from '../../http/transport/request-builder'; +import { ContentType, HttpResponse, RequestConfig } from '../../http/types'; +import { BaseService } from '../base-service'; +import { ApnsConfig, apnsConfigRequest, apnsConfigResponse } from './models/apns-config'; +import { FcmConfig, fcmConfigRequest, fcmConfigResponse } from './models/fcm-config'; +import { GithubConfig, githubConfigRequest, githubConfigResponse } from './models/github-config'; +import { InboxConfig, inboxConfigRequest, inboxConfigResponse } from './models/inbox-config'; +import { ListIntegrationsResponse, listIntegrationsResponseResponse } from './models/list-integrations-response'; +import { MailgunConfig, mailgunConfigRequest, mailgunConfigResponse } from './models/mailgun-config'; +import { PingConfig, pingConfigRequest, pingConfigResponse } from './models/ping-config'; +import { SendgridConfig, sendgridConfigRequest, sendgridConfigResponse } from './models/sendgrid-config'; +import { SesConfig, sesConfigRequest, sesConfigResponse } from './models/ses-config'; +import { SlackConfig, slackConfigRequest, slackConfigResponse } from './models/slack-config'; +import { StripeConfig, stripeConfigRequest, stripeConfigResponse } from './models/stripe-config'; +import { TwilioConfig, twilioConfigRequest, twilioConfigResponse } from './models/twilio-config'; +import { WebpushConfig, webpushConfigRequest, webpushConfigResponse } from './models/webpush-config'; + +export class IntegrationsService extends BaseService { + /** + * + * @returns {Promise>} OK + */ + async listIntegrations(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getApnsIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/apns') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveApnsIntegration(body: ApnsConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/apns') + .setRequestSchema(apnsConfigRequest) + .setResponseSchema(apnsConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteApnsIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/apns') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteApnsIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/apns/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getFcmIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/fcm') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveFcmIntegration(body: FcmConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/fcm') + .setRequestSchema(fcmConfigRequest) + .setResponseSchema(fcmConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteFcmIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/fcm') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteFcmIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/fcm/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getGithubIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/github') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveGithubIntegration(body: GithubConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/github') + .setRequestSchema(githubConfigRequest) + .setResponseSchema(githubConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteGithubIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/github') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteGithubIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/github/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getInboxIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/inbox') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveInboxIntegration(body: InboxConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/inbox') + .setRequestSchema(inboxConfigRequest) + .setResponseSchema(inboxConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteInboxIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/inbox') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteInboxIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/inbox/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getMailgunIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/mailgun') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveMailgunIntegration( + body: MailgunConfig, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/mailgun') + .setRequestSchema(mailgunConfigRequest) + .setResponseSchema(mailgunConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteMailgunIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/mailgun') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteMailgunIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/mailgun/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getPingEmailIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/ping_email') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async savePingEmailIntegration(body: PingConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/ping_email') + .setRequestSchema(pingConfigRequest) + .setResponseSchema(pingConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deletePingEmailIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/ping_email') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deletePingEmailIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/ping_email/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getSendgridIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/sendgrid') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveSendgridIntegration( + body: SendgridConfig, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/sendgrid') + .setRequestSchema(sendgridConfigRequest) + .setResponseSchema(sendgridConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteSendgridIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/sendgrid') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteSendgridIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/sendgrid/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getSesIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/ses') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveSesIntegration(body: SesConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/ses') + .setRequestSchema(sesConfigRequest) + .setResponseSchema(sesConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteSesIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/ses') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteSesIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/ses/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getSlackIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/slack') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveSlackIntegration(body: SlackConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/slack') + .setRequestSchema(slackConfigRequest) + .setResponseSchema(slackConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteSlackIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/slack') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteSlackIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/slack/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getStripeIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/stripe') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveStripeIntegration(body: StripeConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/stripe') + .setRequestSchema(stripeConfigRequest) + .setResponseSchema(stripeConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteStripeIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/stripe') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteStripeIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/stripe/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getTemplatesIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/templates') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveTemplatesIntegration(body: any, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/templates') + .setRequestSchema(z.any()) + .setResponseSchema(z.any()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteTemplatesIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/templates') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteTemplatesIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/templates/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getTwilioIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/twilio') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveTwilioIntegration(body: TwilioConfig, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/twilio') + .setRequestSchema(twilioConfigRequest) + .setResponseSchema(twilioConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteTwilioIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/twilio') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteTwilioIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/twilio/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async getWebPushIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/integrations/web_push') + .setRequestSchema(z.any()) + .setResponseSchema(listIntegrationsResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} OK + */ + async saveWebPushIntegration( + body: WebpushConfig, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('PUT') + .setPath('/integrations/web_push') + .setRequestSchema(webpushConfigRequest) + .setResponseSchema(webpushConfigResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} No Content + */ + async deleteWebPushIntegration(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/web_push') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} id - + * @returns {Promise>} No Content + */ + async deleteWebPushIntegrationById(id: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/integrations/web_push/{id}') + .setRequestSchema(z.any()) + .setResponseSchema(z.undefined()) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'id', + value: id, + }) + .build(); + return this.client.call(request); + } +} diff --git a/packages/project-client/src/services/integrations/models/apns-config.ts b/packages/project-client/src/services/integrations/models/apns-config.ts new file mode 100644 index 000000000..9d2d04b34 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/apns-config.ts @@ -0,0 +1,69 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const apnsConfig = z.lazy(() => { + return z.object({ + appId: z.string().regex(/^[a-zA-Z0-9]+(.[a-zA-Z0-9]+)*$/), + badge: z.string(), + certificate: z.string(), + keyId: z.string().min(10).max(10), + teamId: z.string().min(10).max(10), + }); +}); + +/** + * + * @typedef {ApnsConfig} apnsConfig + * @property {string} + * @property {Badge} + * @property {string} + * @property {string} + * @property {string} + */ +export type ApnsConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const apnsConfigResponse = z.lazy(() => { + return z + .object({ + app_id: z.string().regex(/^[a-zA-Z0-9]+(.[a-zA-Z0-9]+)*$/), + badge: z.string(), + certificate: z.string(), + key_id: z.string().min(10).max(10), + team_id: z.string().min(10).max(10), + }) + .transform((data) => ({ + appId: data['app_id'], + badge: data['badge'], + certificate: data['certificate'], + keyId: data['key_id'], + teamId: data['team_id'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const apnsConfigRequest = z.lazy(() => { + return z + .object({ + appId: z.string().nullish(), + badge: z.string().nullish(), + certificate: z.string().nullish(), + keyId: z.string().nullish(), + teamId: z.string().nullish(), + }) + .transform((data) => ({ + app_id: data['appId'], + badge: data['badge'], + certificate: data['certificate'], + key_id: data['keyId'], + team_id: data['teamId'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/badge.ts b/packages/project-client/src/services/integrations/models/badge.ts new file mode 100644 index 000000000..643a316f5 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/badge.ts @@ -0,0 +1,4 @@ +export enum Badge { + UNREAD = 'unread', + UNSEEN = 'unseen', +} diff --git a/packages/project-client/src/services/integrations/models/fcm-config.ts b/packages/project-client/src/services/integrations/models/fcm-config.ts new file mode 100644 index 000000000..4e978fd33 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/fcm-config.ts @@ -0,0 +1,105 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const fcmConfig = z.lazy(() => { + return z.object({ + authProviderX509CertUrl: z.string(), + authUri: z.string(), + clientEmail: z.string(), + clientId: z.string(), + clientX509CertUrl: z.string(), + privateKey: z.string(), + privateKeyId: z.string(), + projectId: z.string(), + tokenUri: z.string(), + type: z.string(), + universeDomain: z.string(), + }); +}); + +/** + * + * @typedef {FcmConfig} fcmConfig + * @property {string} + * @property {string} + * @property {string} + * @property {string} + * @property {string} + * @property {string} + * @property {string} + * @property {string} + * @property {string} + * @property {Type_} + * @property {string} + */ +export type FcmConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const fcmConfigResponse = z.lazy(() => { + return z + .object({ + auth_provider_x509_cert_url: z.string(), + auth_uri: z.string(), + client_email: z.string(), + client_id: z.string(), + client_x509_cert_url: z.string(), + private_key: z.string(), + private_key_id: z.string(), + project_id: z.string(), + token_uri: z.string(), + type: z.string(), + universe_domain: z.string(), + }) + .transform((data) => ({ + authProviderX509CertUrl: data['auth_provider_x509_cert_url'], + authUri: data['auth_uri'], + clientEmail: data['client_email'], + clientId: data['client_id'], + clientX509CertUrl: data['client_x509_cert_url'], + privateKey: data['private_key'], + privateKeyId: data['private_key_id'], + projectId: data['project_id'], + tokenUri: data['token_uri'], + type: data['type'], + universeDomain: data['universe_domain'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const fcmConfigRequest = z.lazy(() => { + return z + .object({ + authProviderX509CertUrl: z.string().nullish(), + authUri: z.string().nullish(), + clientEmail: z.string().nullish(), + clientId: z.string().nullish(), + clientX509CertUrl: z.string().nullish(), + privateKey: z.string().nullish(), + privateKeyId: z.string().nullish(), + projectId: z.string().nullish(), + tokenUri: z.string().nullish(), + type: z.string().nullish(), + universeDomain: z.string().nullish(), + }) + .transform((data) => ({ + auth_provider_x509_cert_url: data['authProviderX509CertUrl'], + auth_uri: data['authUri'], + client_email: data['clientEmail'], + client_id: data['clientId'], + client_x509_cert_url: data['clientX509CertUrl'], + private_key: data['privateKey'], + private_key_id: data['privateKeyId'], + project_id: data['projectId'], + token_uri: data['tokenUri'], + type: data['type'], + universe_domain: data['universeDomain'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/github-config.ts b/packages/project-client/src/services/integrations/models/github-config.ts new file mode 100644 index 000000000..945bb249d --- /dev/null +++ b/packages/project-client/src/services/integrations/models/github-config.ts @@ -0,0 +1,41 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const githubConfig = z.lazy(() => { + return z.object({ + webhookSigningSecret: z.string().min(1).max(100), + }); +}); + +/** + * + * @typedef {GithubConfig} githubConfig + * @property {string} - The signing secret to verify incoming requests from Stripe + */ +export type GithubConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const githubConfigResponse = z.lazy(() => { + return z + .object({ + webhook_signing_secret: z.string().min(1).max(100), + }) + .transform((data) => ({ + webhookSigningSecret: data['webhook_signing_secret'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const githubConfigRequest = z.lazy(() => { + return z.object({ webhookSigningSecret: z.string().nullish() }).transform((data) => ({ + webhook_signing_secret: data['webhookSigningSecret'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/inbox-config.ts b/packages/project-client/src/services/integrations/models/inbox-config.ts new file mode 100644 index 000000000..8513a4ef9 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/inbox-config.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const inboxConfig = z.lazy(() => { + return z.object({ + images: z.any().nullable(), + locale: z.string().min(2).nullable(), + theme: z.any().nullable(), + }); +}); + +/** + * + * @typedef {InboxConfig} inboxConfig + * @property {any} + * @property {string} + * @property {any} + */ +export type InboxConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const inboxConfigResponse = z.lazy(() => { + return z + .object({ + images: z.any().nullable(), + locale: z.string().min(2).nullable(), + theme: z.any().nullable(), + }) + .transform((data) => ({ + images: data['images'], + locale: data['locale'], + theme: data['theme'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const inboxConfigRequest = z.lazy(() => { + return z + .object({ images: z.any().nullish(), locale: z.string().nullish(), theme: z.any().nullish() }) + .transform((data) => ({ + images: data['images'], + locale: data['locale'], + theme: data['theme'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/index.ts b/packages/project-client/src/services/integrations/models/index.ts new file mode 100644 index 000000000..36d6482c7 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/index.ts @@ -0,0 +1,21 @@ +export type { ApnsConfig } from './apns-config'; +export { Badge } from './badge'; +export type { FcmConfig } from './fcm-config'; +export type { GithubConfig } from './github-config'; +export type { InboxConfig } from './inbox-config'; +export type { Integrations } from './integrations'; +export type { ListIntegrationsResponse } from './list-integrations-response'; +export type { MailgunConfig } from './mailgun-config'; +export { MailgunConfigRegion } from './mailgun-config-region'; +export type { PingConfig } from './ping-config'; +export type { ReplyTo } from './reply-to'; +export type { SendgridConfig } from './sendgrid-config'; +export type { SendgridConfigFrom } from './sendgrid-config-from'; +export type { SesConfig } from './ses-config'; +export type { SesConfigFrom } from './ses-config-from'; +export type { SlackConfig } from './slack-config'; +export type { StripeConfig } from './stripe-config'; +export type { TwilioConfig } from './twilio-config'; +export { TwilioConfigRegion } from './twilio-config-region'; +export { Type_ } from './type_'; +export type { WebpushConfig } from './webpush-config'; diff --git a/packages/project-client/src/services/integrations/models/integrations.ts b/packages/project-client/src/services/integrations/models/integrations.ts new file mode 100644 index 000000000..ebef95bd8 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/integrations.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const integrations = z.lazy(() => { + return z.object({ + config: z.any().optional(), + id: z.string().optional(), + name: z.string().optional(), + }); +}); + +/** + * + * @typedef {Integrations} integrations + * @property {any} + * @property {string} + * @property {string} + */ +export type Integrations = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const integrationsResponse = z.lazy(() => { + return z + .object({ + config: z.any().optional(), + id: z.string().optional(), + name: z.string().optional(), + }) + .transform((data) => ({ + config: data['config'], + id: data['id'], + name: data['name'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const integrationsRequest = z.lazy(() => { + return z + .object({ config: z.any().nullish(), id: z.string().nullish(), name: z.string().nullish() }) + .transform((data) => ({ + config: data['config'], + id: data['id'], + name: data['name'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/list-integrations-response.ts b/packages/project-client/src/services/integrations/models/list-integrations-response.ts new file mode 100644 index 000000000..1dc2ce227 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/list-integrations-response.ts @@ -0,0 +1,43 @@ +import { z } from 'zod'; + +import { integrations, integrationsRequest, integrationsResponse } from './integrations'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const listIntegrationsResponse = z.lazy(() => { + return z.object({ + integrations: z.array(integrations).optional(), + }); +}); + +/** + * + * @typedef {ListIntegrationsResponse} listIntegrationsResponse + * @property {Integrations[]} + */ +export type ListIntegrationsResponse = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const listIntegrationsResponseResponse = z.lazy(() => { + return z + .object({ + integrations: z.array(integrationsResponse).optional(), + }) + .transform((data) => ({ + integrations: data['integrations'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const listIntegrationsResponseRequest = z.lazy(() => { + return z.object({ integrations: z.array(integrationsRequest).nullish() }).transform((data) => ({ + integrations: data['integrations'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/mailgun-config-region.ts b/packages/project-client/src/services/integrations/models/mailgun-config-region.ts new file mode 100644 index 000000000..f8548acec --- /dev/null +++ b/packages/project-client/src/services/integrations/models/mailgun-config-region.ts @@ -0,0 +1,4 @@ +export enum MailgunConfigRegion { + US = 'us', + EU = 'eu', +} diff --git a/packages/project-client/src/services/integrations/models/mailgun-config.ts b/packages/project-client/src/services/integrations/models/mailgun-config.ts new file mode 100644 index 000000000..dbe4390c4 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/mailgun-config.ts @@ -0,0 +1,53 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const mailgunConfig = z.lazy(() => { + return z.object({ + apiKey: z.string().min(1), + domain: z.string().min(1), + region: z.string(), + }); +}); + +/** + * + * @typedef {MailgunConfig} mailgunConfig + * @property {string} + * @property {string} + * @property {MailgunConfigRegion} + */ +export type MailgunConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const mailgunConfigResponse = z.lazy(() => { + return z + .object({ + api_key: z.string().min(1), + domain: z.string().min(1), + region: z.string(), + }) + .transform((data) => ({ + apiKey: data['api_key'], + domain: data['domain'], + region: data['region'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const mailgunConfigRequest = z.lazy(() => { + return z + .object({ apiKey: z.string().nullish(), domain: z.string().nullish(), region: z.string().nullish() }) + .transform((data) => ({ + api_key: data['apiKey'], + domain: data['domain'], + region: data['region'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/ping-config.ts b/packages/project-client/src/services/integrations/models/ping-config.ts new file mode 100644 index 000000000..3c2b47dd8 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/ping-config.ts @@ -0,0 +1,41 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const pingConfig = z.lazy(() => { + return z.object({ + url: z.string().min(1).max(100), + }); +}); + +/** + * + * @typedef {PingConfig} pingConfig + * @property {string} - URL to ping + */ +export type PingConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const pingConfigResponse = z.lazy(() => { + return z + .object({ + url: z.string().min(1).max(100), + }) + .transform((data) => ({ + url: data['url'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const pingConfigRequest = z.lazy(() => { + return z.object({ url: z.string().nullish() }).transform((data) => ({ + url: data['url'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/reply-to.ts b/packages/project-client/src/services/integrations/models/reply-to.ts new file mode 100644 index 000000000..5aa4b93cd --- /dev/null +++ b/packages/project-client/src/services/integrations/models/reply-to.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const replyTo = z.lazy(() => { + return z.object({ + email: z.string(), + name: z.string().optional(), + }); +}); + +/** + * + * @typedef {ReplyTo} replyTo + * @property {string} - The email address to reply to + * @property {string} - The name to reply to + */ +export type ReplyTo = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const replyToResponse = z.lazy(() => { + return z + .object({ + email: z.string(), + name: z.string().optional(), + }) + .transform((data) => ({ + email: data['email'], + name: data['name'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const replyToRequest = z.lazy(() => { + return z.object({ email: z.string().nullish(), name: z.string().nullish() }).transform((data) => ({ + email: data['email'], + name: data['name'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/sendgrid-config-from.ts b/packages/project-client/src/services/integrations/models/sendgrid-config-from.ts new file mode 100644 index 000000000..eca87fff5 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/sendgrid-config-from.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const sendgridConfigFrom = z.lazy(() => { + return z.object({ + email: z.string(), + name: z.string().optional(), + }); +}); + +/** + * + * @typedef {SendgridConfigFrom} sendgridConfigFrom + * @property {string} - The email address to send from + * @property {string} - The name to send from + */ +export type SendgridConfigFrom = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const sendgridConfigFromResponse = z.lazy(() => { + return z + .object({ + email: z.string(), + name: z.string().optional(), + }) + .transform((data) => ({ + email: data['email'], + name: data['name'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const sendgridConfigFromRequest = z.lazy(() => { + return z.object({ email: z.string().nullish(), name: z.string().nullish() }).transform((data) => ({ + email: data['email'], + name: data['name'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/sendgrid-config.ts b/packages/project-client/src/services/integrations/models/sendgrid-config.ts new file mode 100644 index 000000000..14b965c0a --- /dev/null +++ b/packages/project-client/src/services/integrations/models/sendgrid-config.ts @@ -0,0 +1,60 @@ +import { z } from 'zod'; + +import { replyTo, replyToRequest, replyToResponse } from './reply-to'; +import { sendgridConfigFrom, sendgridConfigFromRequest, sendgridConfigFromResponse } from './sendgrid-config-from'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const sendgridConfig = z.lazy(() => { + return z.object({ + apiKey: z.string(), + from: sendgridConfigFrom.optional(), + replyTo: replyTo.optional(), + }); +}); + +/** + * + * @typedef {SendgridConfig} sendgridConfig + * @property {string} - The API key for Sendgrid + * @property {SendgridConfigFrom} + * @property {ReplyTo} + */ +export type SendgridConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const sendgridConfigResponse = z.lazy(() => { + return z + .object({ + api_key: z.string(), + from: sendgridConfigFromResponse.optional(), + reply_to: replyToResponse.optional(), + }) + .transform((data) => ({ + apiKey: data['api_key'], + from: data['from'], + replyTo: data['reply_to'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const sendgridConfigRequest = z.lazy(() => { + return z + .object({ + apiKey: z.string().nullish(), + from: sendgridConfigFromRequest.nullish(), + replyTo: replyToRequest.nullish(), + }) + .transform((data) => ({ + api_key: data['apiKey'], + from: data['from'], + reply_to: data['replyTo'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/ses-config-from.ts b/packages/project-client/src/services/integrations/models/ses-config-from.ts new file mode 100644 index 000000000..5ee8af515 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/ses-config-from.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const sesConfigFrom = z.lazy(() => { + return z.object({ + email: z.string(), + name: z.string().optional(), + }); +}); + +/** + * + * @typedef {SesConfigFrom} sesConfigFrom + * @property {string} - The email address to send from + * @property {string} - The name to send from + */ +export type SesConfigFrom = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const sesConfigFromResponse = z.lazy(() => { + return z + .object({ + email: z.string(), + name: z.string().optional(), + }) + .transform((data) => ({ + email: data['email'], + name: data['name'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const sesConfigFromRequest = z.lazy(() => { + return z.object({ email: z.string().nullish(), name: z.string().nullish() }).transform((data) => ({ + email: data['email'], + name: data['name'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/ses-config.ts b/packages/project-client/src/services/integrations/models/ses-config.ts new file mode 100644 index 000000000..82c3c01e8 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/ses-config.ts @@ -0,0 +1,71 @@ +import { z } from 'zod'; + +import { sesConfigFrom, sesConfigFromRequest, sesConfigFromResponse } from './ses-config-from'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const sesConfig = z.lazy(() => { + return z.object({ + endpoint: z.string().min(1).optional(), + from: sesConfigFrom.optional(), + keyId: z.string().min(1), + region: z.string().min(1), + secretKey: z.string().min(1), + }); +}); + +/** + * + * @typedef {SesConfig} sesConfig + * @property {string} - HTTP endpoint to send requests to (testing only) + * @property {SesConfigFrom} + * @property {string} - AWS Access Key ID + * @property {string} - AWS Region + * @property {string} - AWS Secret Key + */ +export type SesConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const sesConfigResponse = z.lazy(() => { + return z + .object({ + endpoint: z.string().min(1).optional(), + from: sesConfigFromResponse.optional(), + key_id: z.string().min(1), + region: z.string().min(1), + secret_key: z.string().min(1), + }) + .transform((data) => ({ + endpoint: data['endpoint'], + from: data['from'], + keyId: data['key_id'], + region: data['region'], + secretKey: data['secret_key'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const sesConfigRequest = z.lazy(() => { + return z + .object({ + endpoint: z.string().nullish(), + from: sesConfigFromRequest.nullish(), + keyId: z.string().nullish(), + region: z.string().nullish(), + secretKey: z.string().nullish(), + }) + .transform((data) => ({ + endpoint: data['endpoint'], + from: data['from'], + key_id: data['keyId'], + region: data['region'], + secret_key: data['secretKey'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/slack-config.ts b/packages/project-client/src/services/integrations/models/slack-config.ts new file mode 100644 index 000000000..45eface92 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/slack-config.ts @@ -0,0 +1,77 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const slackConfig = z.lazy(() => { + return z.object({ + appId: z.string().regex(/^[0-9A-Z]+$/), + clientId: z.string().regex(/^[0-9]+\.[0-9]+$/), + clientSecret: z.string().min(32).max(32), + id: z + .string() + .min(1) + .regex(/^[\w]*/) + .optional(), + signingSecret: z.string().min(32).max(32), + }); +}); + +/** + * + * @typedef {SlackConfig} slackConfig + * @property {string} + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type SlackConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const slackConfigResponse = z.lazy(() => { + return z + .object({ + app_id: z.string().regex(/^[0-9A-Z]+$/), + client_id: z.string().regex(/^[0-9]+\.[0-9]+$/), + client_secret: z.string().min(32).max(32), + id: z + .string() + .min(1) + .regex(/^[\w]*/) + .optional(), + signing_secret: z.string().min(32).max(32), + }) + .transform((data) => ({ + appId: data['app_id'], + clientId: data['client_id'], + clientSecret: data['client_secret'], + id: data['id'], + signingSecret: data['signing_secret'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const slackConfigRequest = z.lazy(() => { + return z + .object({ + appId: z.string().nullish(), + clientId: z.string().nullish(), + clientSecret: z.string().nullish(), + id: z.string().nullish(), + signingSecret: z.string().nullish(), + }) + .transform((data) => ({ + app_id: data['appId'], + client_id: data['clientId'], + client_secret: data['clientSecret'], + id: data['id'], + signing_secret: data['signingSecret'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/stripe-config.ts b/packages/project-client/src/services/integrations/models/stripe-config.ts new file mode 100644 index 000000000..1777d4ce0 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/stripe-config.ts @@ -0,0 +1,41 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const stripeConfig = z.lazy(() => { + return z.object({ + webhookSigningSecret: z.string().min(1).max(100), + }); +}); + +/** + * + * @typedef {StripeConfig} stripeConfig + * @property {string} - The signing secret to verify incoming requests from Stripe + */ +export type StripeConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const stripeConfigResponse = z.lazy(() => { + return z + .object({ + webhook_signing_secret: z.string().min(1).max(100), + }) + .transform((data) => ({ + webhookSigningSecret: data['webhook_signing_secret'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const stripeConfigRequest = z.lazy(() => { + return z.object({ webhookSigningSecret: z.string().nullish() }).transform((data) => ({ + webhook_signing_secret: data['webhookSigningSecret'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/twilio-config-region.ts b/packages/project-client/src/services/integrations/models/twilio-config-region.ts new file mode 100644 index 000000000..f78838f53 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/twilio-config-region.ts @@ -0,0 +1,5 @@ +export enum TwilioConfigRegion { + US1 = 'us1', + IE1 = 'ie1', + AU1 = 'au1', +} diff --git a/packages/project-client/src/services/integrations/models/twilio-config.ts b/packages/project-client/src/services/integrations/models/twilio-config.ts new file mode 100644 index 000000000..d619c371c --- /dev/null +++ b/packages/project-client/src/services/integrations/models/twilio-config.ts @@ -0,0 +1,77 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const twilioConfig = z.lazy(() => { + return z.object({ + accountSid: z.string().min(1).max(100), + apiKey: z.string().min(1).max(100), + apiSecret: z.string().min(1).max(100), + from: z + .string() + .min(1) + .max(100) + .regex(/^\+[0-9]{1,14}$/), + region: z.string().optional(), + }); +}); + +/** + * + * @typedef {TwilioConfig} twilioConfig + * @property {string} - The SID for your Twilio account + * @property {string} - The API key for Twilio + * @property {string} - The API Secret for Twilio + * @property {string} - The phone number to send from, in E.164 format + * @property {TwilioConfigRegion} - The region to use for Twilio, defaults to 'us1' + */ +export type TwilioConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const twilioConfigResponse = z.lazy(() => { + return z + .object({ + account_sid: z.string().min(1).max(100), + api_key: z.string().min(1).max(100), + api_secret: z.string().min(1).max(100), + from: z + .string() + .min(1) + .max(100) + .regex(/^\+[0-9]{1,14}$/), + region: z.string().optional(), + }) + .transform((data) => ({ + accountSid: data['account_sid'], + apiKey: data['api_key'], + apiSecret: data['api_secret'], + from: data['from'], + region: data['region'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const twilioConfigRequest = z.lazy(() => { + return z + .object({ + accountSid: z.string().nullish(), + apiKey: z.string().nullish(), + apiSecret: z.string().nullish(), + from: z.string().nullish(), + region: z.string().nullish(), + }) + .transform((data) => ({ + account_sid: data['accountSid'], + api_key: data['apiKey'], + api_secret: data['apiSecret'], + from: data['from'], + region: data['region'], + })); +}); diff --git a/packages/project-client/src/services/integrations/models/type_.ts b/packages/project-client/src/services/integrations/models/type_.ts new file mode 100644 index 000000000..c25e45051 --- /dev/null +++ b/packages/project-client/src/services/integrations/models/type_.ts @@ -0,0 +1,3 @@ +export enum Type_ { + SERVICEACCOUNT = 'service_account', +} diff --git a/packages/project-client/src/services/integrations/models/webpush-config.ts b/packages/project-client/src/services/integrations/models/webpush-config.ts new file mode 100644 index 000000000..8221dcd8e --- /dev/null +++ b/packages/project-client/src/services/integrations/models/webpush-config.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const webpushConfig = z.lazy(() => { + return z.object({ + privateKey: z.string().min(8).max(128), + publicKey: z.string().min(8).max(128), + }); +}); + +/** + * + * @typedef {WebpushConfig} webpushConfig + * @property {string} + * @property {string} + */ +export type WebpushConfig = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const webpushConfigResponse = z.lazy(() => { + return z + .object({ + private_key: z.string().min(8).max(128), + public_key: z.string().min(8).max(128), + }) + .transform((data) => ({ + privateKey: data['private_key'], + publicKey: data['public_key'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const webpushConfigRequest = z.lazy(() => { + return z.object({ privateKey: z.string().nullish(), publicKey: z.string().nullish() }).transform((data) => ({ + private_key: data['privateKey'], + public_key: data['publicKey'], + })); +}); diff --git a/packages/project-client/src/services/jwt/index.ts b/packages/project-client/src/services/jwt/index.ts new file mode 100644 index 000000000..ccbbfa9c6 --- /dev/null +++ b/packages/project-client/src/services/jwt/index.ts @@ -0,0 +1,2 @@ +export { JwtService } from './jwt'; +export * from './models'; diff --git a/packages/project-client/src/services/jwt/jwt.ts b/packages/project-client/src/services/jwt/jwt.ts new file mode 100644 index 000000000..32e001b88 --- /dev/null +++ b/packages/project-client/src/services/jwt/jwt.ts @@ -0,0 +1,160 @@ +import { z } from 'zod'; + +import { RequestBuilder } from '../../http/transport/request-builder'; +import { ContentType, HttpResponse, RequestConfig } from '../../http/types'; +import { BaseService } from '../base-service'; +import { AccessToken, accessTokenResponse } from './models/access-token'; +import { CreateProjectTokenRequest, createProjectTokenRequestRequest } from './models/create-project-token-request'; +import { CreateUserTokenRequest, createUserTokenRequestRequest } from './models/create-user-token-request'; +import { DiscardTokenResponse, discardTokenResponseResponse } from './models/discard-token-response'; +import { FetchTokensResponse, fetchTokensResponseResponse } from './models/fetch-tokens-response'; + +export class JwtService extends BaseService { + /** + * + * @returns {Promise>} OK + */ + async fetchProjectTokens(requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/jwt/project') + .setRequestSchema(z.any()) + .setResponseSchema(fetchTokensResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} Created + */ + async createProjectJwt( + body: CreateProjectTokenRequest, + requestConfig?: RequestConfig, + ): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('POST') + .setPath('/jwt/project') + .setRequestSchema(createProjectTokenRequestRequest) + .setResponseSchema(accessTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardProjectJwt(tokenId: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/jwt/project/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardTokenResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @returns {Promise>} Created + */ + async createUserJwt(body: CreateUserTokenRequest, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('POST') + .setPath('/jwt/user') + .setRequestSchema(createUserTokenRequestRequest) + .setResponseSchema(accessTokenResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addHeaderParam({ key: 'Content-Type', value: 'application/json' }) + .addBody(body) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} tokenId - + * @returns {Promise>} OK + */ + async discardUserJwt(tokenId: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('DELETE') + .setPath('/jwt/user/{token_id}') + .setRequestSchema(z.any()) + .setResponseSchema(discardTokenResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'token_id', + value: tokenId, + }) + .build(); + return this.client.call(request); + } + + /** + * + * @param {string} userId - + * @returns {Promise>} OK + */ + async fetchUserTokens(userId: string, requestConfig?: RequestConfig): Promise> { + const request = new RequestBuilder() + .setConfig(this.config) + .setBaseUrl(this.config) + .setMethod('GET') + .setPath('/jwt/user/{user_id}') + .setRequestSchema(z.any()) + .setResponseSchema(fetchTokensResponseResponse) + .setRequestContentType(ContentType.Json) + .setResponseContentType(ContentType.Json) + .setRetryAttempts(this.config, requestConfig) + .setRetryDelayMs(this.config, requestConfig) + .setResponseValidation(this.config, requestConfig) + .addPathParam({ + key: 'user_id', + value: userId, + }) + .build(); + return this.client.call(request); + } +} diff --git a/packages/project-client/src/services/jwt/models/access-token.ts b/packages/project-client/src/services/jwt/models/access-token.ts new file mode 100644 index 000000000..addfee85b --- /dev/null +++ b/packages/project-client/src/services/jwt/models/access-token.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const accessToken = z.lazy(() => { + return z.object({ + createdAt: z.string(), + expiresAt: z.string().optional(), + token: z.string(), + tokenId: z.string(), + }); +}); + +/** + * + * @typedef {AccessToken} accessToken + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type AccessToken = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const accessTokenResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + expires_at: z.string().optional(), + token: z.string(), + token_id: z.string(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + expiresAt: data['expires_at'], + token: data['token'], + tokenId: data['token_id'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const accessTokenRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + expiresAt: z.string().nullish(), + token: z.string().nullish(), + tokenId: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + expires_at: data['expiresAt'], + token: data['token'], + token_id: data['tokenId'], + })); +}); diff --git a/packages/project-client/src/services/jwt/models/create-project-token-request.ts b/packages/project-client/src/services/jwt/models/create-project-token-request.ts new file mode 100644 index 000000000..9d79b81fa --- /dev/null +++ b/packages/project-client/src/services/jwt/models/create-project-token-request.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const createProjectTokenRequest = z.lazy(() => { + return z.object({ + expiry: z.number().gte(1).optional(), + name: z.string().max(255), + }); +}); + +/** + * + * @typedef {CreateProjectTokenRequest} createProjectTokenRequest + * @property {number} - The duration for which the token is valid (in seconds) + * @property {string} - The name of the token. + */ +export type CreateProjectTokenRequest = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const createProjectTokenRequestResponse = z.lazy(() => { + return z + .object({ + expiry: z.number().gte(1).optional(), + name: z.string().max(255), + }) + .transform((data) => ({ + expiry: data['expiry'], + name: data['name'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const createProjectTokenRequestRequest = z.lazy(() => { + return z.object({ expiry: z.number().nullish(), name: z.string().nullish() }).transform((data) => ({ + expiry: data['expiry'], + name: data['name'], + })); +}); diff --git a/packages/project-client/src/services/jwt/models/create-user-token-request.ts b/packages/project-client/src/services/jwt/models/create-user-token-request.ts new file mode 100644 index 000000000..723e55db7 --- /dev/null +++ b/packages/project-client/src/services/jwt/models/create-user-token-request.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const createUserTokenRequest = z.lazy(() => { + return z.object({ + email: z.string().max(255).optional(), + expiry: z.number().gte(1).optional(), + externalId: z.string().max(255).optional(), + name: z.string().max(255).optional(), + }); +}); + +/** + * + * @typedef {CreateUserTokenRequest} createUserTokenRequest + * @property {string} - The user's email. + * @property {number} - The duration for which the token is valid (in seconds) + * @property {string} - A unique string that MagicBell can utilize to identify the user uniquely. We recommend setting this attribute to the ID of the user in your database. Provide the external id if the user's email is unavailable. + * @property {string} - The name of the token. + */ +export type CreateUserTokenRequest = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const createUserTokenRequestResponse = z.lazy(() => { + return z + .object({ + email: z.string().max(255).optional(), + expiry: z.number().gte(1).optional(), + external_id: z.string().max(255).optional(), + name: z.string().max(255).optional(), + }) + .transform((data) => ({ + email: data['email'], + expiry: data['expiry'], + externalId: data['external_id'], + name: data['name'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const createUserTokenRequestRequest = z.lazy(() => { + return z + .object({ + email: z.string().nullish(), + expiry: z.number().nullish(), + externalId: z.string().nullish(), + name: z.string().nullish(), + }) + .transform((data) => ({ + email: data['email'], + expiry: data['expiry'], + external_id: data['externalId'], + name: data['name'], + })); +}); diff --git a/packages/project-client/src/services/jwt/models/discard-token-response.ts b/packages/project-client/src/services/jwt/models/discard-token-response.ts new file mode 100644 index 000000000..e5b899351 --- /dev/null +++ b/packages/project-client/src/services/jwt/models/discard-token-response.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const discardTokenResponse = z.lazy(() => { + return z.object({ + discardedAt: z.string(), + tokenId: z.string(), + }); +}); + +/** + * + * @typedef {DiscardTokenResponse} discardTokenResponse + * @property {string} + * @property {string} + */ +export type DiscardTokenResponse = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const discardTokenResponseResponse = z.lazy(() => { + return z + .object({ + discarded_at: z.string(), + token_id: z.string(), + }) + .transform((data) => ({ + discardedAt: data['discarded_at'], + tokenId: data['token_id'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const discardTokenResponseRequest = z.lazy(() => { + return z.object({ discardedAt: z.string().nullish(), tokenId: z.string().nullish() }).transform((data) => ({ + discarded_at: data['discardedAt'], + token_id: data['tokenId'], + })); +}); diff --git a/packages/project-client/src/services/jwt/models/fetch-tokens-response.ts b/packages/project-client/src/services/jwt/models/fetch-tokens-response.ts new file mode 100644 index 000000000..bff89076e --- /dev/null +++ b/packages/project-client/src/services/jwt/models/fetch-tokens-response.ts @@ -0,0 +1,43 @@ +import { z } from 'zod'; + +import { tokens, tokensRequest, tokensResponse } from './tokens'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const fetchTokensResponse = z.lazy(() => { + return z.object({ + tokens: z.array(tokens), + }); +}); + +/** + * + * @typedef {FetchTokensResponse} fetchTokensResponse + * @property {Tokens[]} + */ +export type FetchTokensResponse = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const fetchTokensResponseResponse = z.lazy(() => { + return z + .object({ + tokens: z.array(tokensResponse), + }) + .transform((data) => ({ + tokens: data['tokens'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const fetchTokensResponseRequest = z.lazy(() => { + return z.object({ tokens: z.array(tokensRequest).nullish() }).transform((data) => ({ + tokens: data['tokens'], + })); +}); diff --git a/packages/project-client/src/services/jwt/models/index.ts b/packages/project-client/src/services/jwt/models/index.ts new file mode 100644 index 000000000..509e18f30 --- /dev/null +++ b/packages/project-client/src/services/jwt/models/index.ts @@ -0,0 +1,6 @@ +export type { AccessToken } from './access-token'; +export type { CreateProjectTokenRequest } from './create-project-token-request'; +export type { CreateUserTokenRequest } from './create-user-token-request'; +export type { DiscardTokenResponse } from './discard-token-response'; +export type { FetchTokensResponse } from './fetch-tokens-response'; +export type { Tokens } from './tokens'; diff --git a/packages/project-client/src/services/jwt/models/tokens.ts b/packages/project-client/src/services/jwt/models/tokens.ts new file mode 100644 index 000000000..2c29a56eb --- /dev/null +++ b/packages/project-client/src/services/jwt/models/tokens.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; + +/** + * The shape of the model inside the application code - what the users use + */ +export const tokens = z.lazy(() => { + return z.object({ + createdAt: z.string(), + expiresAt: z.string().optional(), + id: z.string().optional(), + name: z.string().optional(), + }); +}); + +/** + * + * @typedef {Tokens} tokens + * @property {string} + * @property {string} + * @property {string} + * @property {string} + */ +export type Tokens = z.infer; + +/** + * The shape of the model mapping from the api schema into the application shape. + * Is equal to application shape if all property names match the api schema + */ +export const tokensResponse = z.lazy(() => { + return z + .object({ + created_at: z.string(), + expires_at: z.string().optional(), + id: z.string().optional(), + name: z.string().optional(), + }) + .transform((data) => ({ + createdAt: data['created_at'], + expiresAt: data['expires_at'], + id: data['id'], + name: data['name'], + })); +}); + +/** + * The shape of the model mapping from the application shape into the api schema. + * Is equal to application shape if all property names match the api schema + */ +export const tokensRequest = z.lazy(() => { + return z + .object({ + createdAt: z.string().nullish(), + expiresAt: z.string().nullish(), + id: z.string().nullish(), + name: z.string().nullish(), + }) + .transform((data) => ({ + created_at: data['createdAt'], + expires_at: data['expiresAt'], + id: data['id'], + name: data['name'], + })); +}); diff --git a/packages/project-client/tsconfig.build.json b/packages/project-client/tsconfig.build.json new file mode 100644 index 000000000..18c1cbdc6 --- /dev/null +++ b/packages/project-client/tsconfig.build.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.build.json", + "include": ["src"], + "exclude": ["src/client/@custom_types"], + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "target": "es2018", + "baseUrl": "./", + "declarationMap": true, + "lib": ["ES2021.String", "dom", "esnext"], + "noEmit": false, + "noUnusedLocals": false, + "noUnusedParameters": false + } +} diff --git a/packages/user-client/package.json b/packages/user-client/package.json index 4d6d1a321..6027fd1f0 100644 --- a/packages/user-client/package.json +++ b/packages/user-client/package.json @@ -38,7 +38,7 @@ "version": "tsc --version" }, "dependencies": { - "axios": "^1.0.0" + "axios": "^1.7.4" }, "devDependencies": { "@types/jest": "^29.5.10", diff --git a/packages/user-client/scripts/build.ts b/packages/user-client/scripts/build.ts index e4e5e6e79..cb693f230 100644 --- a/packages/user-client/scripts/build.ts +++ b/packages/user-client/scripts/build.ts @@ -6,6 +6,8 @@ import { parseArgs } from 'node:util'; import { rimraf } from 'rimraf'; import { sortPackageJson } from 'sort-package-json'; +import rootPkgJson from '../../../package.json'; + async function move(oldPath: string, newPath: string) { await rimraf(newPath); await fs.mkdir(path.dirname(newPath), { recursive: true }); @@ -121,7 +123,9 @@ async function build(specfile = 'https://public.magicbell.com/specs/swagger.json pkgJson.scripts['build'] = 'run-s build:*'; pkgJson.scripts['build:cjs'] = 'tsc --project tsconfig.build.json --module commonjs --outDir dist/commonjs'; pkgJson.scripts['build:esm'] = 'tsc --project tsconfig.build.json --module esnext --outDir dist/esm'; + pkgJson.scripts['start'] = 'rm -rf dist/ && tsc -w'; + delete pkgJson.scripts['watch']; delete pkgJson.scripts['build:umd']; delete pkgJson.scripts['build:all']; delete pkgJson.scripts['prepublishOnly']; @@ -129,6 +133,8 @@ async function build(specfile = 'https://public.magicbell.com/specs/swagger.json for (const key of Object.keys(pkgJson.devDependencies)) { if (/eslint|prettier/.test(key)) { delete pkgJson.devDependencies[key]; + } else if (rootPkgJson.dependencies[key]) { + pkgJson.devDependencies[key] = rootPkgJson.dependencies[key]; } } diff --git a/tsconfig.build.json b/tsconfig.build.json index 3a673645e..5196335fa 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -8,7 +8,7 @@ "declaration": true, "sourceMap": true, "strict": false, - "noUnusedLocals": true, + "noUnusedLocals": false, "noUnusedParameters": false, "noImplicitReturns": false, "noFallthroughCasesInSwitch": true, diff --git a/tsconfig.json b/tsconfig.json index 2a315e9b8..80cfbe8dd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,6 +24,7 @@ "@magicbell/embeddable": ["packages/embeddable/src"], "@magicbell/in-app": ["packages/in-app/src"], "@magicbell/magicbell-react": ["packages/react/src"], + "@magicbell/project-client": ["packages/project-client/src"], "@magicbell/react-headless": ["packages/react-headless/src"], "@magicbell/user-client": ["packages/user-client/src"], "@magicbell/utils": ["packages/utils/src"], diff --git a/yarn.lock b/yarn.lock index 0f2fdabdc..d01550b0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5703,7 +5703,7 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" -axios@^1.0.0: +axios@^1.7.4: version "1.7.4" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== @@ -15617,6 +15617,11 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== +zod@3.22.0: + version "3.22.0" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.0.tgz#2478211a9bf477eb2d7d2ce031b5f8ff0d596407" + integrity sha512-y5KZY/ssf5n7hCGDGGtcJO/EBJEm5Pa+QQvFBeyMOtnFYOSflalxIFFvdaYevPhePcmcKC4aTbFkCcXN7D0O8Q== + zod@3.23.8: version "3.23.8" resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"