@vonage/server-client
Advanced tools
Comparing version 1.9.0 to 1.10.0
@@ -0,33 +1,135 @@ | ||
import { Response } from 'node-fetch'; | ||
import { AuthInterface, AuthParams } from '@vonage/auth'; | ||
import { VetchResponse, VetchOptions, HTTPMethods } from '@vonage/vetch'; | ||
import { AuthenticationType } from './enums/AuthenticationType'; | ||
import { AuthenticationType } from './enums'; | ||
import * as transfomers from './transformers'; | ||
import { ConfigParams } from './types/index'; | ||
export declare abstract class Client { | ||
import { ConfigParams } from './types'; | ||
export declare class Client { | ||
/** | ||
* Static property containing utility transformers. | ||
*/ | ||
static transformers: typeof transfomers; | ||
/** | ||
* The type of authentication used for the client's requests. | ||
*/ | ||
protected authType?: AuthenticationType; | ||
/** | ||
* The authentication instance responsible for generating authentication headers and query parameters. | ||
*/ | ||
protected auth: AuthInterface; | ||
/** | ||
* Configuration settings for the client, including default hosts for various services and other request settings. | ||
*/ | ||
protected config: ConfigParams; | ||
/** | ||
* Creates a new instance of the Client. | ||
* | ||
* @param {AuthInterface | AuthParams} credentials - The authentication credentials or an authentication instance. | ||
* @param {ConfigParams} [options] - Optional configuration settings for the client. | ||
*/ | ||
constructor(credentials: AuthInterface | AuthParams, options?: ConfigParams); | ||
/** | ||
* Adds the appropriate authentication headers or parameters to the request based on the authentication type. | ||
* | ||
* @param {VetchOptions} request - The request options to which authentication needs to be added. | ||
* @return {Promise<VetchOptions>} - The request options with the added authentication. | ||
*/ | ||
addAuthenticationToRequest(request: VetchOptions): Promise<VetchOptions>; | ||
/** | ||
* Sends a DELETE request to the specified URL. | ||
* | ||
* @param {string} url - The URL endpoint for the DELETE request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the DELETE request. | ||
*/ | ||
sendDeleteRequest<T>(url: string): Promise<VetchResponse<T>>; | ||
sendFormSubmitRequest<T>(url: string, payload?: { | ||
[key: string]: any; | ||
}): Promise<VetchResponse<T>>; | ||
/** | ||
* Sends a POST request with form data to the specified URL. | ||
* | ||
* @param {string} url - The URL endpoint for the POST request. | ||
* @param {Record<string, string>} [payload] - Optional payload containing form data to send with the POST request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the POST request. | ||
*/ | ||
sendFormSubmitRequest<T>(url: string, payload?: Record<string, string>): Promise<VetchResponse<T>>; | ||
/** | ||
* Sends a GET request to the specified URL with optional query parameters. | ||
* | ||
* @param {string} url - The URL endpoint for the GET request. | ||
* @param {Record<string, unknown>} [queryParams] - Optional query parameters to append to the URL. These should be compatible with Node's URLSearchParams. | ||
* @return {Promise<VetchResponse<T>>} - The response from the GET request. | ||
*/ | ||
sendGetRequest<T>(url: string, queryParams?: { | ||
[key: string]: any; | ||
[key: string]: unknown; | ||
}): Promise<VetchResponse<T>>; | ||
/** | ||
* Sends a PATCH request to the specified URL with an optional payload. | ||
* | ||
* @param {string} url - The URL endpoint for the PATCH request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the PATCH request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the PATCH request. | ||
*/ | ||
sendPatchRequest<T>(url: string, payload?: { | ||
[key: string]: any; | ||
[key: string]: unknown; | ||
}): Promise<VetchResponse<T>>; | ||
/** | ||
* Sends a POST request to the specified URL with an optional payload. | ||
* | ||
* @param {string} url - The URL endpoint for the POST request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the POST request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the POST request. | ||
*/ | ||
sendPostRequest<T>(url: string, payload?: { | ||
[key: string]: any; | ||
[key: string]: unknown; | ||
}): Promise<VetchResponse<T>>; | ||
/** | ||
* Sends a PUT request to the specified URL with an optional payload. | ||
* | ||
* @param {string} url - The URL endpoint for the PUT request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the PUT request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the PUT request. | ||
*/ | ||
sendPutRequest<T>(url: string, payload?: { | ||
[key: string]: any; | ||
[key: string]: unknown; | ||
}): Promise<VetchResponse<T>>; | ||
sendRequestWithData<T>(method: HTTPMethods, url: string, payload?: { | ||
[key: string]: any; | ||
/** | ||
* Sends a request with JSON-encoded data to the specified URL using the provided HTTP method. | ||
* | ||
* @param {HTTPMethods.POST | HTTPMethods.PATCH | HTTPMethods.PUT} method - The HTTP method to be used for the request (only POST, PATCH, or PUT are acceptable). | ||
* @param {string} url - The URL endpoint for the request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the request, JSON-encoded. | ||
* @return {Promise<VetchResponse<T>>} - The response from the request. | ||
*/ | ||
sendRequestWithData<T>(method: HTTPMethods.POST | HTTPMethods.PATCH | HTTPMethods.PUT, url: string, payload?: { | ||
[key: string]: unknown; | ||
}): Promise<VetchResponse<T>>; | ||
/** | ||
* Sends a request adding necessary headers, handling authentication, and parsing the response. | ||
* | ||
* @param {VetchOptions} request - The options defining the request, including URL, method, headers, and data. | ||
* @return {Promise<VetchResponse<T>>} - The parsed response from the request. | ||
*/ | ||
sendRequest<T>(request: VetchOptions): Promise<VetchResponse<T>>; | ||
/** | ||
* Prepares the request with necessary headers, authentication, and query parameters. | ||
* | ||
* @param {VetchOptions} request - The initial request options. | ||
* @return {Promise<VetchOptions>} - The modified request options. | ||
*/ | ||
protected prepareRequest(request: VetchOptions): Promise<VetchOptions>; | ||
/** | ||
* Prepares the body for the request based on the content type. | ||
* | ||
* @param {VetchOptions} request - The request options. | ||
* @return {string | undefined} - The prepared request body as a string or undefined. | ||
*/ | ||
protected prepareBody(request: VetchOptions): string | undefined; | ||
/** | ||
* Parses the response based on its content type. | ||
* | ||
* @template T - The expected type of the parsed response data. | ||
* | ||
* @param {VetchOptions} request - The request options. | ||
* @param {Response} response - The raw response from the request. | ||
* @return {Promise<VetchResponse<T>>} - The parsed response. | ||
*/ | ||
protected parseResponse<T>(request: VetchOptions, response: Response): Promise<VetchResponse<T>>; | ||
} |
@@ -30,5 +30,7 @@ "use strict"; | ||
exports.Client = void 0; | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const node_fetch_2 = __importDefault(require("node-fetch")); | ||
const auth_1 = require("@vonage/auth"); | ||
const vetch_1 = require("@vonage/vetch"); | ||
const AuthenticationType_1 = require("./enums/AuthenticationType"); | ||
const enums_1 = require("./enums"); | ||
const transfomers = __importStar(require("./transformers")); | ||
@@ -38,8 +40,13 @@ const debug_1 = __importDefault(require("debug")); | ||
class Client { | ||
static transformers = transfomers; | ||
authType; | ||
auth; | ||
config; | ||
/** | ||
* Creates a new instance of the Client. | ||
* | ||
* @param {AuthInterface | AuthParams} credentials - The authentication credentials or an authentication instance. | ||
* @param {ConfigParams} [options] - Optional configuration settings for the client. | ||
*/ | ||
constructor(credentials, options) { | ||
// eslint-disable-next-line max-len | ||
/** | ||
* The type of authentication used for the client's requests. | ||
*/ | ||
this.authType = enums_1.AuthenticationType.QUERY_KEY_SECRET; | ||
this.auth = !Object.prototype.hasOwnProperty.call(credentials, 'getQueryParams') | ||
@@ -58,7 +65,15 @@ ? new auth_1.Auth(credentials) | ||
} | ||
/** | ||
* Adds the appropriate authentication headers or parameters to the request based on the authentication type. | ||
* | ||
* @param {VetchOptions} request - The request options to which authentication needs to be added. | ||
* @return {Promise<VetchOptions>} - The request options with the added authentication. | ||
*/ | ||
async addAuthenticationToRequest(request) { | ||
let requestPath = 'data'; | ||
log(`adding ${this.authType || 'api key/secret'} to request`); | ||
if (!Object.values(enums_1.AuthenticationType).includes(this.authType)) { | ||
throw new Error('No authentication type set'); | ||
} | ||
switch (this.authType) { | ||
case AuthenticationType_1.AuthenticationType.BASIC: | ||
case enums_1.AuthenticationType.BASIC: | ||
request.headers = Object.assign({}, request.headers, { | ||
@@ -68,3 +83,3 @@ Authorization: await this.auth.createBasicHeader(), | ||
return request; | ||
case AuthenticationType_1.AuthenticationType.JWT: | ||
case enums_1.AuthenticationType.JWT: | ||
request.headers = Object.assign({}, request.headers, { | ||
@@ -74,28 +89,30 @@ Authorization: await this.auth.createBearerHeader(), | ||
return request; | ||
case AuthenticationType_1.AuthenticationType.QUERY_KEY_SECRET: | ||
requestPath = 'params'; | ||
// falls through | ||
case AuthenticationType_1.AuthenticationType.KEY_SECRET: | ||
default: | ||
} | ||
if (['GET', 'DELETE'].includes(request.method)) { | ||
requestPath = 'params'; | ||
if (this.authType === enums_1.AuthenticationType.QUERY_KEY_SECRET) { | ||
log(`adding parameters to query string`); | ||
request.params = { | ||
...(request.params ? request.params : {}), | ||
...(await this.auth.getQueryParams({})), | ||
}; | ||
return request; | ||
} | ||
if (typeof request.data === 'string') { | ||
throw new Error('Cannot append auth parameters to body'); | ||
} | ||
const authParams = await this.auth.getQueryParams({}); | ||
let params = { | ||
...request[requestPath], | ||
request.data = request.data ?? {}; | ||
// JSON as default | ||
log(`Adding parameters to body`); | ||
request.data = { | ||
...request.data, | ||
...authParams, | ||
}; | ||
// This is most likely web-form | ||
if (!request[requestPath] | ||
&& this.authType !== AuthenticationType_1.AuthenticationType.QUERY_KEY_SECRET) { | ||
requestPath = 'body'; | ||
params = new URLSearchParams({ | ||
...Object.fromEntries(request.body.entries()), | ||
...authParams, | ||
}); | ||
} | ||
request[requestPath] = params; | ||
return request; | ||
} | ||
/** | ||
* Sends a DELETE request to the specified URL. | ||
* | ||
* @param {string} url - The URL endpoint for the DELETE request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the DELETE request. | ||
*/ | ||
async sendDeleteRequest(url) { | ||
@@ -108,2 +125,9 @@ const request = { | ||
} | ||
/** | ||
* Sends a POST request with form data to the specified URL. | ||
* | ||
* @param {string} url - The URL endpoint for the POST request. | ||
* @param {Record<string, string>} [payload] - Optional payload containing form data to send with the POST request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the POST request. | ||
*/ | ||
async sendFormSubmitRequest(url, payload) { | ||
@@ -113,9 +137,14 @@ const request = { | ||
method: vetch_1.HTTPMethods.POST, | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
...(payload ? { body: new URLSearchParams(payload) } : {}), | ||
type: vetch_1.ContentType.FORM_URLENCODED, | ||
...(payload ? { data: payload } : {}), | ||
}; | ||
return await this.sendRequest(request); | ||
} | ||
/** | ||
* Sends a GET request to the specified URL with optional query parameters. | ||
* | ||
* @param {string} url - The URL endpoint for the GET request. | ||
* @param {Record<string, unknown>} [queryParams] - Optional query parameters to append to the URL. These should be compatible with Node's URLSearchParams. | ||
* @return {Promise<VetchResponse<T>>} - The response from the GET request. | ||
*/ | ||
async sendGetRequest(url, queryParams) { | ||
@@ -129,11 +158,40 @@ const request = { | ||
} | ||
/** | ||
* Sends a PATCH request to the specified URL with an optional payload. | ||
* | ||
* @param {string} url - The URL endpoint for the PATCH request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the PATCH request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the PATCH request. | ||
*/ | ||
async sendPatchRequest(url, payload) { | ||
return this.sendRequestWithData(vetch_1.HTTPMethods.PATCH, url, payload); | ||
} | ||
/** | ||
* Sends a POST request to the specified URL with an optional payload. | ||
* | ||
* @param {string} url - The URL endpoint for the POST request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the POST request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the POST request. | ||
*/ | ||
async sendPostRequest(url, payload) { | ||
return this.sendRequestWithData(vetch_1.HTTPMethods.POST, url, payload); | ||
} | ||
/** | ||
* Sends a PUT request to the specified URL with an optional payload. | ||
* | ||
* @param {string} url - The URL endpoint for the PUT request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the PUT request. | ||
* @return {Promise<VetchResponse<T>>} - The response from the PUT request. | ||
*/ | ||
sendPutRequest(url, payload) { | ||
return this.sendRequestWithData(vetch_1.HTTPMethods.PUT, url, payload); | ||
} | ||
/** | ||
* Sends a request with JSON-encoded data to the specified URL using the provided HTTP method. | ||
* | ||
* @param {HTTPMethods.POST | HTTPMethods.PATCH | HTTPMethods.PUT} method - The HTTP method to be used for the request (only POST, PATCH, or PUT are acceptable). | ||
* @param {string} url - The URL endpoint for the request. | ||
* @param {Record<string, unknown>} [payload] - Optional payload to be sent as the body of the request, JSON-encoded. | ||
* @return {Promise<VetchResponse<T>>} - The response from the request. | ||
*/ | ||
async sendRequestWithData(method, url, payload) { | ||
@@ -143,5 +201,3 @@ const request = { | ||
method: method, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
type: vetch_1.ContentType.JSON, | ||
...(payload ? { data: payload } : {}), | ||
@@ -151,11 +207,138 @@ }; | ||
} | ||
/** | ||
* Sends a request adding necessary headers, handling authentication, and parsing the response. | ||
* | ||
* @param {VetchOptions} request - The options defining the request, including URL, method, headers, and data. | ||
* @return {Promise<VetchResponse<T>>} - The parsed response from the request. | ||
*/ | ||
async sendRequest(request) { | ||
request.timeout = this.config.timeout; | ||
const timeout = request.timeout || this.config.timeout; | ||
const controller = new AbortController(); | ||
const timeoutId = setTimeout(() => { | ||
controller.abort(); | ||
}, timeout); | ||
try { | ||
log('Preparing request', request); | ||
request = await this.prepareRequest(request); | ||
const fetcRequest = { | ||
url: request.url, | ||
method: request.method, | ||
headers: request.headers, | ||
body: this.prepareBody(request), | ||
...(timeout ? { signal: controller.signal } : {}), | ||
}; | ||
log('Sending request', fetcRequest); | ||
return await this.parseResponse(request, await (0, node_fetch_1.default)(request.url, fetcRequest)); | ||
} | ||
catch (error) { | ||
if (error instanceof node_fetch_2.default) { | ||
log(`Request timed out after ${timeout}`); | ||
} | ||
throw error; | ||
} | ||
finally { | ||
clearTimeout(timeoutId); | ||
} | ||
} | ||
/** | ||
* Prepares the request with necessary headers, authentication, and query parameters. | ||
* | ||
* @param {VetchOptions} request - The initial request options. | ||
* @return {Promise<VetchOptions>} - The modified request options. | ||
*/ | ||
async prepareRequest(request) { | ||
request.headers = { | ||
...request.headers, | ||
'user-agent': [ | ||
`@vonage/server-sdk/3.0.0`, | ||
` node/${process.version.replace('v', '')}`, | ||
this.config.appendUserAgent ? ` ${this.config.appendUserAgent}` : '', | ||
].join(), | ||
}; | ||
switch (request.type) { | ||
case vetch_1.ContentType.FORM_URLENCODED: | ||
request.headers['content-type'] = vetch_1.ContentType.FORM_URLENCODED; | ||
break; | ||
case vetch_1.ContentType.JSON: | ||
request.headers['content-type'] = vetch_1.ContentType.JSON; | ||
break; | ||
} | ||
request = await this.addAuthenticationToRequest(request); | ||
const vetch = new vetch_1.Vetch(this.config); | ||
const result = await vetch.request(request); | ||
return result; | ||
const url = new URL(request.url); | ||
const params = new URLSearchParams(request.params); | ||
// copy params into the URL | ||
for (const [param, value] of params.entries()) { | ||
url.searchParams.append(param, value); | ||
} | ||
request.url = url.toString(); | ||
return request; | ||
} | ||
/** | ||
* Prepares the body for the request based on the content type. | ||
* | ||
* @param {VetchOptions} request - The request options. | ||
* @return {string | undefined} - The prepared request body as a string or undefined. | ||
*/ | ||
prepareBody(request) { | ||
request.headers = { | ||
...request?.headers, | ||
}; | ||
if (!request.data) { | ||
return; | ||
} | ||
if (request.type === vetch_1.ContentType.JSON) { | ||
return JSON.stringify(request.data); | ||
} | ||
if (request.type === vetch_1.ContentType.FORM_URLENCODED) { | ||
const requestParams = new URLSearchParams(request.data); | ||
requestParams.sort(); | ||
return requestParams.toString(); | ||
} | ||
return undefined; | ||
} | ||
/** | ||
* Parses the response based on its content type. | ||
* | ||
* @template T - The expected type of the parsed response data. | ||
* | ||
* @param {VetchOptions} request - The request options. | ||
* @param {Response} response - The raw response from the request. | ||
* @return {Promise<VetchResponse<T>>} - The parsed response. | ||
*/ | ||
async parseResponse(request, response) { | ||
let decoded = null; | ||
if (!response.ok) { | ||
log('Request failed', response); | ||
throw new vetch_1.VetchError(`Request failed with status code ${response.status}`, request, response); | ||
} | ||
switch (response.headers.get('content-type')) { | ||
case vetch_1.ContentType.FORM_URLENCODED: | ||
decoded = response.body | ||
? new URLSearchParams(await response.text()) | ||
: ''; | ||
break; | ||
case vetch_1.ContentType.JSON: | ||
decoded = await response.json(); | ||
break; | ||
default: | ||
decoded = await response.text(); | ||
} | ||
const responseHeaders = {}; | ||
for (const [header, value] of response.headers.entries()) { | ||
Object.assign(response, header, value); | ||
} | ||
return { | ||
data: decoded, | ||
config: request, | ||
status: response.status, | ||
statusText: response.statusText, | ||
headers: responseHeaders, | ||
request: request, | ||
}; | ||
} | ||
} | ||
exports.Client = Client; | ||
//# sourceMappingURL=client.js.map | ||
/** | ||
* Static property containing utility transformers. | ||
*/ | ||
Client.transformers = transfomers; |
@@ -0,7 +1,27 @@ | ||
/** | ||
* Enum representing the different types of authentication methods | ||
* supported by the Vonage APIs. | ||
*/ | ||
export declare enum AuthenticationType { | ||
/** | ||
* @description Basic authentication using a base64-encoded string. | ||
*/ | ||
BASIC = "basic", | ||
/** | ||
* @description JSON Web Token (JWT) authentication. | ||
*/ | ||
JWT = "jwt", | ||
/** | ||
* @description Authentication using both API key and secret in the request body. | ||
* @deprecated This method is deprecated. | ||
*/ | ||
KEY_SECRET = "key_secret", | ||
/** | ||
* @description Authentication using API key and secret in the query parameters. | ||
*/ | ||
QUERY_KEY_SECRET = "query_key_secret", | ||
/** | ||
* @description HMAC signature-based authentication. | ||
*/ | ||
SIGNATURE = "signature" | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AuthenticationType = void 0; | ||
/** | ||
* Enum representing the different types of authentication methods | ||
* supported by the Vonage APIs. | ||
*/ | ||
var AuthenticationType; | ||
(function (AuthenticationType) { | ||
/** | ||
* @description Basic authentication using a base64-encoded string. | ||
*/ | ||
AuthenticationType["BASIC"] = "basic"; | ||
/** | ||
* @description JSON Web Token (JWT) authentication. | ||
*/ | ||
AuthenticationType["JWT"] = "jwt"; | ||
/** | ||
* @description Authentication using both API key and secret in the request body. | ||
* @deprecated This method is deprecated. | ||
*/ | ||
AuthenticationType["KEY_SECRET"] = "key_secret"; | ||
/** | ||
* @description Authentication using API key and secret in the query parameters. | ||
*/ | ||
AuthenticationType["QUERY_KEY_SECRET"] = "query_key_secret"; | ||
/** | ||
* @description HMAC signature-based authentication. | ||
*/ | ||
AuthenticationType["SIGNATURE"] = "signature"; | ||
})(AuthenticationType || (exports.AuthenticationType = AuthenticationType = {})); | ||
//# sourceMappingURL=AuthenticationType.js.map |
@@ -0,21 +1,118 @@ | ||
/** | ||
* Enum representing the different types of generic error codes | ||
* that might be returned by the Vonage APIs. | ||
*/ | ||
export declare enum GenericErrors { | ||
/** | ||
* The account has insufficient funds. This request could not be performed | ||
* due to your account balance being low. Top up your account in the Vonage | ||
* Dashboard. | ||
*/ | ||
LOW_BALANCE = "low-balance", | ||
/** | ||
* The provided credentials are incorrect or missing. You did not provide | ||
* correct credentials. Check your authentication credentials; they can be | ||
* found in the Vonage Dashboard. | ||
*/ | ||
UNAUTHORIZED = "unauthorized", | ||
/** | ||
* The authenticated user does not have access to the requested resource. Your | ||
* account does not have permission to perform this action. Check that you're | ||
* using the correct credentials and that your account has this feature enabled. | ||
*/ | ||
FORBIDDEN = "forbidden", | ||
/** | ||
* The requested resource could not be found. The requested resource does not | ||
* exist, or you do not have access to it. Check both the URI that you're | ||
* requesting and your authentication credentials. | ||
*/ | ||
NOT_FOUND = "not-found", | ||
/** | ||
* The account is not provisioned for the requested service. The credentials | ||
* provided do not have access to the requested product. Check that your API | ||
* key is correct and has been whitelisted. | ||
*/ | ||
UNPROVISIONED = "unprovisioned", | ||
/** | ||
* The account has been suspended. This account has been suspended. Contact | ||
* support@api.vonage.com for more information. | ||
*/ | ||
ACCOUNT_SUSPENDED = "account-suspended", | ||
/** | ||
* The provided JWT has expired. The JWT provided has expired. Generate a | ||
* new JWT with an expiration date in the future. | ||
*/ | ||
JWT_EXPIRED = "jwt-expired", | ||
/** | ||
* The provided JWT has been revoked. The JWT provided has been revoked. | ||
* Generate a new JWT using your private key. | ||
*/ | ||
JWT_REVOKED = "jwt-revoked", | ||
/** | ||
* The provided API key is invalid. The API key provided does not exist in | ||
* our system, or you do not have access. Modify your request to provide a | ||
* valid API key. | ||
*/ | ||
INVALID_API_KEY = "invalid-api-key", | ||
/** | ||
* The provided signature is invalid. The signature provided did not | ||
* validate. Check your signature secret and ensure you're following the | ||
* correct signing process. | ||
*/ | ||
INVALID_SIGNATURE = "invalid-signature", | ||
/** | ||
* The request originates from an unauthorized IP address. The source IP | ||
* address of the request is not in our allow list. Make a request from an | ||
* allowed IP address, or add your current IP to the list of authorized | ||
* addresses. | ||
*/ | ||
INVALID_IP = "invalid-ip", | ||
/** | ||
* Multiple authentication methods were provided in the request. | ||
* Provide exactly one authentication method. | ||
*/ | ||
MULTIPLE_AUTH_METHODS = "multiple-auth-methods", | ||
/** | ||
* The provided ID in the request is invalid. The ID provided does not exist | ||
* in our system. Modify your request to provide a valid ID. | ||
*/ | ||
INVALID_ID = "invalid-id", | ||
/** | ||
* The provided JSON in the request body is invalid. The request body did | ||
* not contain valid JSON. Send a JSON request body, including a | ||
* Content-Type header of application/json. | ||
*/ | ||
INVALID_JSON = "invalid-json", | ||
/** | ||
* The HTTP verb used in the request is not allowed. This endpoint does not | ||
* support the HTTP verb that you requested. Read the API documentation to | ||
* see which verbs your desired endpoint supports. | ||
*/ | ||
WRONG_VERB = "wrong-verb", | ||
/** | ||
* The provided Accept header in the request is invalid. Invalid Accept | ||
* header provided. Most Vonage APIs only send back application/json. Check | ||
* the API documentation for the specific API you're working with for a | ||
* complete list of supported data types. | ||
*/ | ||
ACCEPT_HEADER = "accept-header", | ||
/** | ||
* The provided Content-Type header in the request is invalid. Invalid | ||
* Content-Type header provided. Most Vonage APIs only accept application/ | ||
* json. Check the API documentation for the specific API you're working | ||
* with for a complete list of supported data types. | ||
*/ | ||
CONTENT_TYPE_HEADER = "content-type-header", | ||
/** | ||
* The requested service is unavailable due to legal reasons. Vonage APIs | ||
* are unavailable in the following areas due to international sanctions: | ||
* Sudan, Syria, Crimea, North Korea, Iran, and Cuba. | ||
*/ | ||
UNAVAILABLE_LEGAL = "unavailable-legal", | ||
/** | ||
* The application associated with the request has been suspended. This | ||
* application has been suspended. Re-enable the application or create a new | ||
* application to use. | ||
*/ | ||
APPLICATION_SUSPENDED = "application-suspended" | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GenericErrors = void 0; | ||
/** | ||
* Enum representing the different types of generic error codes | ||
* that might be returned by the Vonage APIs. | ||
*/ | ||
var GenericErrors; | ||
(function (GenericErrors) { | ||
/** | ||
* The account has insufficient funds. This request could not be performed | ||
* due to your account balance being low. Top up your account in the Vonage | ||
* Dashboard. | ||
*/ | ||
GenericErrors["LOW_BALANCE"] = "low-balance"; | ||
/** | ||
* The provided credentials are incorrect or missing. You did not provide | ||
* correct credentials. Check your authentication credentials; they can be | ||
* found in the Vonage Dashboard. | ||
*/ | ||
GenericErrors["UNAUTHORIZED"] = "unauthorized"; | ||
/** | ||
* The authenticated user does not have access to the requested resource. Your | ||
* account does not have permission to perform this action. Check that you're | ||
* using the correct credentials and that your account has this feature enabled. | ||
*/ | ||
GenericErrors["FORBIDDEN"] = "forbidden"; | ||
/** | ||
* The requested resource could not be found. The requested resource does not | ||
* exist, or you do not have access to it. Check both the URI that you're | ||
* requesting and your authentication credentials. | ||
*/ | ||
GenericErrors["NOT_FOUND"] = "not-found"; | ||
/** | ||
* The account is not provisioned for the requested service. The credentials | ||
* provided do not have access to the requested product. Check that your API | ||
* key is correct and has been whitelisted. | ||
*/ | ||
GenericErrors["UNPROVISIONED"] = "unprovisioned"; | ||
/** | ||
* The account has been suspended. This account has been suspended. Contact | ||
* support@api.vonage.com for more information. | ||
*/ | ||
GenericErrors["ACCOUNT_SUSPENDED"] = "account-suspended"; | ||
/** | ||
* The provided JWT has expired. The JWT provided has expired. Generate a | ||
* new JWT with an expiration date in the future. | ||
*/ | ||
GenericErrors["JWT_EXPIRED"] = "jwt-expired"; | ||
/** | ||
* The provided JWT has been revoked. The JWT provided has been revoked. | ||
* Generate a new JWT using your private key. | ||
*/ | ||
GenericErrors["JWT_REVOKED"] = "jwt-revoked"; | ||
/** | ||
* The provided API key is invalid. The API key provided does not exist in | ||
* our system, or you do not have access. Modify your request to provide a | ||
* valid API key. | ||
*/ | ||
GenericErrors["INVALID_API_KEY"] = "invalid-api-key"; | ||
/** | ||
* The provided signature is invalid. The signature provided did not | ||
* validate. Check your signature secret and ensure you're following the | ||
* correct signing process. | ||
*/ | ||
GenericErrors["INVALID_SIGNATURE"] = "invalid-signature"; | ||
/** | ||
* The request originates from an unauthorized IP address. The source IP | ||
* address of the request is not in our allow list. Make a request from an | ||
* allowed IP address, or add your current IP to the list of authorized | ||
* addresses. | ||
*/ | ||
GenericErrors["INVALID_IP"] = "invalid-ip"; | ||
/** | ||
* Multiple authentication methods were provided in the request. | ||
* Provide exactly one authentication method. | ||
*/ | ||
GenericErrors["MULTIPLE_AUTH_METHODS"] = "multiple-auth-methods"; | ||
/** | ||
* The provided ID in the request is invalid. The ID provided does not exist | ||
* in our system. Modify your request to provide a valid ID. | ||
*/ | ||
GenericErrors["INVALID_ID"] = "invalid-id"; | ||
/** | ||
* The provided JSON in the request body is invalid. The request body did | ||
* not contain valid JSON. Send a JSON request body, including a | ||
* Content-Type header of application/json. | ||
*/ | ||
GenericErrors["INVALID_JSON"] = "invalid-json"; | ||
/** | ||
* The HTTP verb used in the request is not allowed. This endpoint does not | ||
* support the HTTP verb that you requested. Read the API documentation to | ||
* see which verbs your desired endpoint supports. | ||
*/ | ||
GenericErrors["WRONG_VERB"] = "wrong-verb"; | ||
/** | ||
* The provided Accept header in the request is invalid. Invalid Accept | ||
* header provided. Most Vonage APIs only send back application/json. Check | ||
* the API documentation for the specific API you're working with for a | ||
* complete list of supported data types. | ||
*/ | ||
GenericErrors["ACCEPT_HEADER"] = "accept-header"; | ||
/** | ||
* The provided Content-Type header in the request is invalid. Invalid | ||
* Content-Type header provided. Most Vonage APIs only accept application/ | ||
* json. Check the API documentation for the specific API you're working | ||
* with for a complete list of supported data types. | ||
*/ | ||
GenericErrors["CONTENT_TYPE_HEADER"] = "content-type-header"; | ||
/** | ||
* The requested service is unavailable due to legal reasons. Vonage APIs | ||
* are unavailable in the following areas due to international sanctions: | ||
* Sudan, Syria, Crimea, North Korea, Iran, and Cuba. | ||
*/ | ||
GenericErrors["UNAVAILABLE_LEGAL"] = "unavailable-legal"; | ||
/** | ||
* The application associated with the request has been suspended. This | ||
* application has been suspended. Re-enable the application or create a new | ||
* application to use. | ||
*/ | ||
GenericErrors["APPLICATION_SUSPENDED"] = "application-suspended"; | ||
})(GenericErrors || (exports.GenericErrors = GenericErrors = {})); | ||
//# sourceMappingURL=GenericErrorCodes.js.map |
@@ -19,2 +19,1 @@ "use strict"; | ||
__exportStar(require("./GenericErrorCodes"), exports); | ||
//# sourceMappingURL=index.js.map |
import { Client } from './client'; | ||
import { AuthenticationType } from './enums/AuthenticationType'; | ||
import { AuthenticationType } from './enums'; | ||
/** | ||
* A client for downloading files from Vonage. | ||
* | ||
* @extends Client | ||
*/ | ||
export declare class FileClient extends Client { | ||
protected authType: AuthenticationType; | ||
protected saveFilePath: string; | ||
/** | ||
* Downloads a file from Vonage and saves it to a specified path. | ||
* | ||
* @param {string} file - The URL or ID of the file to be downloaded. | ||
* @param {string} path - The path where the downloaded file should be saved. | ||
* | ||
* @throws {Error} Throws an error if the file could not be downloaded or saved. | ||
* | ||
* @return {Promise<void>} Resolves when the file is successfully downloaded and saved. | ||
*/ | ||
downloadFile(file: string, path: string): Promise<void>; | ||
} |
@@ -8,8 +8,30 @@ "use strict"; | ||
const client_1 = require("./client"); | ||
const AuthenticationType_1 = require("./enums/AuthenticationType"); | ||
const enums_1 = require("./enums"); | ||
const debug_1 = __importDefault(require("debug")); | ||
const vetch_1 = require("@vonage/vetch"); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const fs_1 = require("fs"); | ||
const debug_1 = __importDefault(require("debug")); | ||
const log = (0, debug_1.default)('vonage:server-client'); | ||
const promises_1 = require("stream/promises"); | ||
const log = (0, debug_1.default)('vonage:file-client'); | ||
/** | ||
* A client for downloading files from Vonage. | ||
* | ||
* @extends Client | ||
*/ | ||
class FileClient extends client_1.Client { | ||
authType = AuthenticationType_1.AuthenticationType.JWT; | ||
constructor() { | ||
super(...arguments); | ||
this.authType = enums_1.AuthenticationType.JWT; | ||
this.saveFilePath = ''; | ||
} | ||
/** | ||
* Downloads a file from Vonage and saves it to a specified path. | ||
* | ||
* @param {string} file - The URL or ID of the file to be downloaded. | ||
* @param {string} path - The path where the downloaded file should be saved. | ||
* | ||
* @throws {Error} Throws an error if the file could not be downloaded or saved. | ||
* | ||
* @return {Promise<void>} Resolves when the file is successfully downloaded and saved. | ||
*/ | ||
async downloadFile(file, path) { | ||
@@ -20,3 +42,3 @@ log(`Downloading file: ${file}`); | ||
const fileURL = new URL(file); | ||
fileId = fileURL.pathname.split('/').pop(); | ||
fileId = fileURL.pathname.split('/').pop() || ''; | ||
} | ||
@@ -27,5 +49,17 @@ catch (_) { | ||
log(`File Id ${fileId}`); | ||
const resp = await this.sendGetRequest(`${this.config.apiHost}/v1/files/${fileId}`); | ||
const request = await this.addAuthenticationToRequest({ | ||
url: `${this.config.apiHost}/v1/files/${fileId}`, | ||
method: vetch_1.HTTPMethods.GET, | ||
}); | ||
log('File download request', request); | ||
const response = await (0, node_fetch_1.default)(request.url, { | ||
method: request.method, | ||
headers: request.headers, | ||
}); | ||
log('File download response', response); | ||
if (!response.ok) { | ||
throw new vetch_1.VetchError(`Unexpected response when downloading file: ${response.statusText}`, request); | ||
} | ||
log(`Saving to ${path}`); | ||
(0, fs_1.writeFileSync)(path, resp.data); | ||
await (0, promises_1.pipeline)(response.body, (0, fs_1.createWriteStream)(path)); | ||
log('File saved'); | ||
@@ -35,2 +69,1 @@ } | ||
exports.FileClient = FileClient; | ||
//# sourceMappingURL=fileClient.js.map |
@@ -24,2 +24,1 @@ "use strict"; | ||
__exportStar(require("./fileClient"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -1,4 +0,39 @@ | ||
export declare const transformObjectKeys: (transformFn: (key: string | number) => string, objectToTransform: Record<string | number, unknown>, deep?: boolean, preserve?: boolean) => Record<string | number, unknown>; | ||
export declare const camelCaseObjectKeys: any; | ||
export declare const snakeCaseObjectKeys: any; | ||
export declare const kebabCaseObjectKeys: any; | ||
export type TransformFunction = (key: string) => string; | ||
/** | ||
* Transforms the keys of an object based on a provided transformation function. | ||
* | ||
* @param {TransformFunction} transformFn - The function to transform the object's keys. | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* | ||
* @return {Record<string | number, unknown>} A new object with transformed keys. | ||
*/ | ||
export declare const transformObjectKeys: (transformFn: TransformFunction, objectToTransform: Record<string | number, unknown>, deep?: boolean, preserve?: boolean) => Record<string | number, unknown>; | ||
/** | ||
* Transforms the keys of an object to camelCase. | ||
* | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* @return {Record<string | number, unknown>} A new object with camelCased keys. | ||
*/ | ||
export declare const camelCaseObjectKeys: (objectToTransform: Record<string | number, unknown>, deep?: boolean | undefined, preserve?: boolean | undefined) => Record<string | number, unknown>; | ||
/** | ||
* Transforms the keys of an object to snake_case. | ||
* | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* @return {Record<string | number, unknown>} A new object with snake_cased keys. | ||
*/ | ||
export declare const snakeCaseObjectKeys: (objectToTransform: Record<string | number, unknown>, deep?: boolean | undefined, preserve?: boolean | undefined) => Record<string | number, unknown>; | ||
/** | ||
* Transforms the keys of an object to kebab-case. | ||
* | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* @return {Record<string | number, unknown>} A new object with kebab-cased keys. | ||
*/ | ||
export declare const kebabCaseObjectKeys: (objectToTransform: Record<string | number, unknown>, deep?: boolean | undefined, preserve?: boolean | undefined) => Record<string | number, unknown>; |
@@ -12,2 +12,12 @@ "use strict"; | ||
const lodash_isobject_1 = __importDefault(require("lodash.isobject")); | ||
/** | ||
* Transforms the keys of an object based on a provided transformation function. | ||
* | ||
* @param {TransformFunction} transformFn - The function to transform the object's keys. | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* | ||
* @return {Record<string | number, unknown>} A new object with transformed keys. | ||
*/ | ||
const transformObjectKeys = (transformFn, objectToTransform, deep = false, preserve = false) => { | ||
@@ -38,5 +48,28 @@ const transformedObject = { | ||
exports.transformObjectKeys = transformObjectKeys; | ||
/** | ||
* Transforms the keys of an object to camelCase. | ||
* | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* @return {Record<string | number, unknown>} A new object with camelCased keys. | ||
*/ | ||
exports.camelCaseObjectKeys = (0, lodash_partial_1.default)(exports.transformObjectKeys, lodash_camelcase_1.default); | ||
/** | ||
* Transforms the keys of an object to snake_case. | ||
* | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* @return {Record<string | number, unknown>} A new object with snake_cased keys. | ||
*/ | ||
exports.snakeCaseObjectKeys = (0, lodash_partial_1.default)(exports.transformObjectKeys, lodash_snakecase_1.default); | ||
/** | ||
* Transforms the keys of an object to kebab-case. | ||
* | ||
* @param {Record<string | number, unknown>} objectToTransform - The object whose keys are to be transformed. | ||
* @param {boolean} [deep=false] - Whether to deeply transform nested object keys. | ||
* @param {boolean} [preserve=false] - Whether to preserve the original object's keys. | ||
* @return {Record<string | number, unknown>} A new object with kebab-cased keys. | ||
*/ | ||
exports.kebabCaseObjectKeys = (0, lodash_partial_1.default)(exports.transformObjectKeys, lodash_kebabcase_1.default); | ||
//# sourceMappingURL=transformers.js.map |
@@ -18,2 +18,1 @@ "use strict"; | ||
__exportStar(require("./types/index"), exports); | ||
//# sourceMappingURL=types.js.map |
@@ -0,3 +1,12 @@ | ||
/** | ||
* Represents a link object in the HAL format. | ||
* | ||
* @see {@link https://tools.ietf.org/html/rfc5988} for more details on Web Linking. | ||
* | ||
*/ | ||
export type APILink = { | ||
/** | ||
* The URL of the link. | ||
*/ | ||
href: string; | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=APILink.js.map |
import { APILink } from './APILink'; | ||
/** | ||
* Represents a set of links in the HAL format. | ||
* | ||
* @see {@link https://tools.ietf.org/html/draft-kelly-json-hal-08} for more details on HAL format. | ||
* | ||
*/ | ||
export type APILinks = { | ||
_links: { | ||
/** | ||
* The set of links. | ||
*/ | ||
_links?: { | ||
/** | ||
* The link for the current resource. | ||
*/ | ||
self: APILink; | ||
/** | ||
* The link for the next page of resources. | ||
*/ | ||
next?: APILink; | ||
/** | ||
* The link for the first page of resources. | ||
*/ | ||
first?: APILink; | ||
/** | ||
* The link for the last page of resources. | ||
*/ | ||
last?: APILink; | ||
/** | ||
* The link for the previous page of resources. | ||
*/ | ||
prev?: APILink; | ||
}; | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=APILinks.js.map |
import { ResponseTypes } from '@vonage/vetch'; | ||
/** | ||
* Type defining configuration parameters for API requests. | ||
* | ||
* @see {@link https://github.com/vonage/vetch} for more information on ResponseTypes. | ||
*/ | ||
export type ConfigParams = { | ||
/** | ||
* The host for REST API requests. | ||
*/ | ||
restHost?: string; | ||
/** | ||
* The host for general API requests. | ||
*/ | ||
apiHost?: string; | ||
/** | ||
* The host for video-related API requests. | ||
*/ | ||
videoHost?: string; | ||
/** | ||
* The desired response type for API requests. | ||
* @deprecated The client will now use the `content-type` header to decode the | ||
* response properly | ||
*/ | ||
responseType?: ResponseTypes; | ||
/** | ||
* The maximum time, in milliseconds, to wait for API responses. | ||
*/ | ||
timeout?: number; | ||
/** | ||
* The host for proactive API requests. | ||
*/ | ||
proactiveHost?: string; | ||
/** | ||
* The host for meetings-related API requests. | ||
*/ | ||
meetingsHost?: string; | ||
/** | ||
* A string to append to the User-Agent header in API requests. | ||
*/ | ||
appendUserAgent?: string; | ||
}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
//# sourceMappingURL=ConfigParams.js.map |
@@ -20,2 +20,1 @@ "use strict"; | ||
__exportStar(require("./ConfigParams"), exports); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"$schema": "https://json.schemastore.org/package.json", | ||
"name": "@vonage/server-client", | ||
"version": "1.9.0", | ||
"description": "Core services related to talking to the Vonage APIs", | ||
"version": "1.10.0", | ||
"description": "The Vonage Server Client provides core functionalities for interacting with Vonage APIs, ensuring a standardized response regardless of the underlying HTTP adapter.", | ||
"homepage": "https://developer.vonage.com", | ||
@@ -14,3 +15,12 @@ "bugs": { | ||
"license": "Apache-2.0", | ||
"author": "Chris Tankersley <chris@ctankersley.com>", | ||
"contributors": [ | ||
{ | ||
"name": "Chris Tankersley", | ||
"url": "https://github.com/dragonmantank" | ||
}, | ||
{ | ||
"name": "Chuck \"MANCHUCK\" Reeves", | ||
"url": "https://github.com/manchuck" | ||
} | ||
], | ||
"main": "dist/index.js", | ||
@@ -31,4 +41,4 @@ "types": "dist/index.d.ts", | ||
"dependencies": { | ||
"@vonage/auth": "^1.7.0", | ||
"@vonage/vetch": "^1.6.0", | ||
"@vonage/auth": "^1.8.0", | ||
"@vonage/vetch": "^1.7.0", | ||
"debug": "^4.3.4", | ||
@@ -39,5 +49,12 @@ "lodash.camelcase": "^4.3.0", | ||
"lodash.partial": "^4.2.1", | ||
"lodash.snakecase": "^4.1.1" | ||
"lodash.snakecase": "^4.1.1", | ||
"node-fetch": "^2" | ||
}, | ||
"devDependencies": { | ||
"@types/lodash.camelcase": "4.3.7", | ||
"@types/lodash.isobject": "3.0.7", | ||
"@types/lodash.kebabcase": "4.1.7", | ||
"@types/lodash.partial": "4.2.7", | ||
"@types/lodash.snakecase": "4.1.7", | ||
"@types/node-fetch": "2.6.6", | ||
"nock": "^13.3.4" | ||
@@ -44,0 +61,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54221
1148
9
7
26
1
+ Addednode-fetch@^2
Updated@vonage/auth@^1.8.0
Updated@vonage/vetch@^1.7.0