Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEVEXP-383: Update documentation to prepare GA #57

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,14 @@ console.log(`The SMS has been sent successfully. Here is the batch id: ${respons

Here is the list of the Sinch products and their level of support by the Node.js SDK:

| API Category | API Name | Status |
|------------------------|-------------------------------------|:------:|
| Messaging | SMS API | ✅ |
| | Conversation API | ✅ |
| | Fax API | 🚧 |
| Voice and Video | Voice API | ✅ |
| Numbers & Connectivity | Numbers API | ✅ |
| Verification | Verification API | ✅ |
| API Category | API Name | Status |
|------------------------|------------------|:------:|
| Messaging | SMS API | ✅ |
| | Conversation API | ✅ |
| | Fax API | |
| Voice and Video | Voice API | ✅ |
| Numbers & Connectivity | Numbers API | ✅ |
| Verification | Verification API | ✅ |

### Packages

Expand Down
47 changes: 44 additions & 3 deletions packages/conversation/src/rest/v1/conversation-service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SinchClientParameters } from '@sinch/sdk-client';
import { ConversationRegion, SinchClientParameters } from '@sinch/sdk-client';
import { ContactApi } from './contact';
import { AppApi } from './app';
import { EventsApi } from './events';
Expand All @@ -10,6 +10,19 @@ import { WebhooksApi } from './webhooks';
import { TemplatesV1Api } from './templates-v1';
import { TemplatesV2Api } from './templates-v2';

/**
* The Conversation Service exposes the following APIs:
* - app
* - contact
* - capability
* - conversation
* - messages
* - events
* - transcoding
* - webhooks
* - templatesV1
* - templatesV2
*/
export class ConversationService {
public readonly contact: ContactApi;
public readonly app: AppApi;
Expand All @@ -22,7 +35,18 @@ export class ConversationService {
public readonly templatesV1: TemplatesV1Api;
public readonly templatesV2: TemplatesV2Api;


/**
* Create a new ConversationService instance with its configuration. It needs the following parameters for authentication:
* - `projectId`
* - `keyId`
* - `keySecret`
*
* Other supported properties:
* - `conversationRegion`
* - `conversationHostname`
* - `conversationTemplatesHostname`
* @param {SinchClientParameters} params - an Object containing the necessary properties to initialize the service
*/
constructor(params: SinchClientParameters) {
this.contact = new ContactApi(params);
this.app = new AppApi(params);
Expand Down Expand Up @@ -52,11 +76,28 @@ export class ConversationService {
}

/**
* Update the default hostname for the Templates API
* Update the default hostname for the Templates APIs
* @param {string} hostname - The new hostname to use for the Templates APIs.
*/
public setTemplatesHostname(hostname: string) {
this.templatesV1.setHostname(hostname);
this.templatesV2.setHostname(hostname);
}

/**
* Update the current region for each API
* @param {ConversationRegion} region - The new region to use in the production URL
*/
public setRegion(region: ConversationRegion) {
this.contact.setRegion(region);
this.app.setRegion(region);
this.events.setRegion(region);
this.messages.setRegion(region);
this.transcoding.setRegion(region);
this.capability.setRegion(region);
this.conversation.setRegion(region);
this.webhooks.setRegion(region);
this.templatesV1.setRegion(region);
this.templatesV2.setRegion(region);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SinchClientParameters } from '@sinch/sdk-client';
import { ConversationRegion, SinchClientParameters } from '@sinch/sdk-client';
import {
AppApi,
CapabilityApi,
Expand All @@ -15,8 +15,10 @@ import {

describe('Conversation Service', () => {
const DEFAULT_HOSTNAME = 'https://us.conversation.api.sinch.com';
const EUROPE_HOSTNAME = 'https://eu.conversation.api.sinch.com';
const CUSTOM_HOSTNAME = 'https://new.host.name';
const DEFAULT_HOSTNAME_TEMPLATES = 'https://us.template.api.sinch.com';
const EUROPE_HOSTNAME_TEMPLATES = 'https://eu.template.api.sinch.com';
const CUSTOM_HOSTNAME_TEMPLATES = 'https://templates.new.host.name';

it('should initialize all the APIs', () => {
Expand Down Expand Up @@ -92,4 +94,29 @@ describe('Conversation Service', () => {
expect(conversationService.templatesV1.getSinchClient().apiClientOptions.hostname).toBe(CUSTOM_HOSTNAME_TEMPLATES);
expect(conversationService.templatesV2.getSinchClient().apiClientOptions.hostname).toBe(CUSTOM_HOSTNAME_TEMPLATES);
});

it('should update the default region for all APIs', () => {
// Given
const params: SinchClientParameters = {
projectId: 'PROJECT_ID',
keyId: 'KEY_ID',
keySecret: 'KEY_SECRET',
};
const conversationService = new ConversationService(params);

// When
conversationService.setRegion(ConversationRegion.EUROPE);

// Then
expect(conversationService.contact.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.app.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.events.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.messages.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.transcoding.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.capability.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.conversation.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.webhooks.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME);
expect(conversationService.templatesV1.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME_TEMPLATES);
expect(conversationService.templatesV2.getSinchClient().apiClientOptions.hostname).toBe(EUROPE_HOSTNAME_TEMPLATES);
});
});
30 changes: 28 additions & 2 deletions packages/fax/src/rest/v3/fax-service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import { SinchClientParameters } from '@sinch/sdk-client';
import { FaxRegion, SinchClientParameters } from '@sinch/sdk-client';
import { EmailsApi } from './emails';
import { FaxesApi } from './faxes';
import { ServicesApi } from './services';

/**
* The Fax Service exposes the following APIs:
* - services
* - faxes
* - emails
*/
export class FaxService {
public readonly emails: EmailsApi;
public readonly faxes: FaxesApi;
public readonly services: ServicesApi;

/**
* Create a new FaxService instance with its configuration. It needs the following parameters for authentication:
* - `projectId`
* - `keyId`
* - `keySecret`
*
* Other supported properties:
* - `faxRegion`
* - `faxHostname`
* @param {SinchClientParameters} params - an Object containing the necessary properties to initialize the service
*/
constructor(params: SinchClientParameters) {
this.emails = new EmailsApi(params);
this.faxes = new FaxesApi(params);
Expand All @@ -16,12 +33,21 @@ export class FaxService {

/**
* Update the default hostname for each API
*
* @param {string} hostname - The new hostname to use for all the APIs.
*/
public setHostname(hostname: string) {
this.emails.setHostname(hostname);
this.faxes.setHostname(hostname);
this.services.setHostname(hostname);
}

/**
* Update the current region for each API
* @param {FaxRegion} region - The new region to use in the production URL
*/
public setRegion(region: FaxRegion) {
this.emails.setRegion(region);
this.faxes.setRegion(region);
this.services.setRegion(region);
}
}
17 changes: 17 additions & 0 deletions packages/numbers/src/rest/v1/numbers-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,29 @@ import { CallbacksApi } from './callbacks';
import { AvailableNumberApi } from './available-number';
import { ActiveNumberApi } from './active-number';

/**
* The Numbers Service exposes the following APIs:
* - availableRegions
* - availableNumber
* - activeNumber
* - callbacks
*/
export class NumbersService {
public readonly availableRegions: AvailableRegionsApi;
public readonly callbacks: CallbacksApi;
public readonly availableNumber: AvailableNumberApi;
public readonly activeNumber: ActiveNumberApi;

/**
* Create a new NumbersService instance with its configuration. It needs the following parameters for authentication:
* - `projectId`
* - `keyId`
* - `keySecret`
*
* Other supported properties:
* - `numbersHostname`
* @param {SinchClientParameters} params - an Object containing the necessary properties to initialize the service
*/
constructor(params: SinchClientParameters) {
this.availableRegions = new AvailableRegionsApi(params);
this.callbacks = new CallbacksApi(params);
Expand Down
16 changes: 11 additions & 5 deletions packages/sdk-client/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
# Sinch Http Client for Node.js

This package contains the HTTP client used by the Sinch SDK client. It uses the `fetch` library to send requests. There are 3 folders in this package:
- api: it defines the interface for an `Api`, an `ApiClient` and for `ApiClientOptions`.
- client: it contains the `fetch` implementation for the `ApiClient`. This implementation handles the refresh of the JWT for the APIs which support this authentication method.
- plugins: calling an API can be seen as a straighforward operation as it's "just" about sending an HTTP request to a server and reading the response. And this is was the `ApiClient` does. However, all APIs don't behave the same and this is why we have introduced the request and response plugins:
This package contains the HTTP client used by the Sinch SDK client. It uses 2 third-party dependencies:
- `node-fetch` to send requests.
- `form-data` to manage "multipart/form-data" streams.

There are 5 folders in this package:
- `api`: it defines the interface for an `Api`, an `ApiClient` and for `ApiClientOptions`.
- `client`: it contains the `fetch` implementation for the `ApiClient`. This implementation handles the refresh of the JWT for the APIs which support this authentication method.
- `domain`: it contains some Sinch-specific interfaces and enums used at domain level for authentication and region definition.
- `plugins`: calling an API can be seen as a straighforward operation as it's "just" about sending an HTTP request to a server and reading the response. And this is was the `ApiClient` does. However, all APIs don't behave the same and this is why we have introduced the request and response plugins:
- request plugins will modify the request: for the moment, they are all about adding some headers (for authentication, for tracking the SDK usage).
- response plugins will modify the response, e.g.: response content is checked and transformed into an exception if the content is empty.
- `utils`: it contains some utility methods that are used by the API SDKs, such as the methods to validate headers are valid in a callback event request, or a method to convert text to hexadecimal for a UDH header

> <span style="color:red; font-weight:bold">Warning:</span>
> **This SDK is currently available to selected developers for preview use only. It is being provided for the purpose of collecting feedback, and should not be used in production environments.**

## Architecture
TODO: schema
![High level architecture](./documentation/High-level-architecture.png)

## Installation

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions packages/sdk-client/src/domain/domain-interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { RequestPlugin } from '../plugins/core/request-plugin';
import { ResponsePlugin } from '../plugins/core/response-plugin';

/**
* Global object that holds the API configuration.
* Be careful to follow the guidelines defined by the API Services about which parameters are required for each API. Not all of them use the same authentication mechanism:
* - OAuth2: Conversation, Fax, Numbers and SMS (US and EU regions only)
* - API Token: SMS on all regions
* - Application Signed: Verification and Voice
*/
export interface SinchClientParameters extends
Partial<UnifiedCredentials>,
Partial<ServicePlanIdCredentials>,
Expand Down Expand Up @@ -46,19 +53,30 @@ export interface ApplicationCredentials {
}

export interface ApiHostname {
/** Override the hostname for the OAuth2 authentication API */
authHostname?: string;
/** Override the hostname for the Conversation API (not Conversation Templates) - Note the regions become ineffective */
conversationHostname?: string;
/** Override the hostname for the Conversation Templates API - Note the regions become ineffective */
conversationTemplatesHostname?: string;
/** Override the hostname for the Fax API - Note the regions become ineffective */
faxHostname?: string;
/** Override the hostname for the Numbers API */
numbersHostname?: string;
/** Override the hostname for the SMS API - Note the regions become ineffective */
smsHostname?: string;
/** Override the hostname for the Verification API */
verificationHostname?: string;
/** Override the hostname for the Voice API (not Voice Application Management) - Note the regions become ineffective */
voiceHostname?: string;
/** Override the hostname for the Voice Application Management API */
voiceApplicationManagementHostname?: string;
}

export interface ApiPlugins {
/** Add more plugins to action on the request before it is sent */
requestPlugins?: RequestPlugin[];
/** Add more plugins to action on the server response before it is returned in the Promise */
responsePlugins?: ResponsePlugin<any>[];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ export interface AdditionalHeaders {
headers: Promise<{ [key: string]: string }>;
}

/**
* Builds a Promise containing the new header in the form of an object {key : value}
* @param {string} key - the header key
* @param {string} value - the header value
*/
export const buildHeader = async (key: string, value: string): Promise<{[key: string]: string}> => (
{ [key] : value }
);

export class AdditionalHeadersRequest implements RequestPlugin {
private readonly additionalHeaders: AdditionalHeaders;

Expand Down
1 change: 1 addition & 0 deletions packages/sdk-client/src/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './core';
export * from './additional-headers';
export * from './api-token';
export * from './basicAuthentication';
export * from './exception';
Expand Down
Loading
Loading