diff --git a/ask-sdk-model/index.ts b/ask-sdk-model/index.ts index ff7f33a..91feca8 100644 --- a/ask-sdk-model/index.ts +++ b/ask-sdk-model/index.ts @@ -1,428 +1,428 @@ -export namespace services { - /** - * Represents the interface between ApiClient and a Service Client. - * @export - * @interface ApiClientMessage - */ - export interface ApiClientMessage { - headers : Array<{key : string, value : string}>; - body? : string; - } - - /** - * Represents a request sent from Service Clients to an ApiClient implementation. - * @export - * @interface ApiClientRequest - * @extends {ApiClientMessage} - */ - export interface ApiClientRequest extends ApiClientMessage { - url : string; - method : string; - } - - /** - * Represents a response returned by ApiClient implementation to a Service Client. - * @export - * @interface ApiClientResponse - * @extends {ApiClientMessage} - */ - export interface ApiClientResponse extends ApiClientMessage { - /** - * Result code of the attempt to satisfy the request. Normally this - * corresponds to the HTTP status code returned by the server. - */ - statusCode : number; - } - - /** - * Represents a response with parsed body. - * @export - * @interface ApiResponse - */ - export interface ApiResponse { - headers : Array<{key : string, value : string}>; - body? : any; - statusCode : number; - } - - /** - * Represents a basic contract for API request execution - * @export - * @interface ApiClient - */ - export interface ApiClient { - /** - * Dispatches a request to an API endpoint described in the request. - * An ApiClient is expected to resolve the Promise in the case an API returns a non-200 HTTP - * status code. The responsibility of translating a particular response code to an error lies with the - * caller to invoke. - * @param {ApiClientRequest} request request to dispatch to the ApiClient - * @returns {Promise} Response from the ApiClient - * @memberof ApiClient - */ - invoke(request : ApiClientRequest) : Promise; - } - - /** - * Represents an interface that provides API configuration options needed by service clients. - * @interface ApiConfiguration - */ - export interface ApiConfiguration { - /** - * Configured ApiClient implementation - */ - apiClient : ApiClient; - /** - * Authorization value to be used on any calls of the service client instance - */ - authorizationValue : string; - /** - * Endpoint to hit by the service client instance - */ - apiEndpoint : string; - } - - /** - * Class to be used as the base class for the generated service clients. - */ - export abstract class BaseServiceClient { - private static isCodeSuccessful( responseCode : number ) : boolean { - return responseCode >= 200 && responseCode < 300; - } - - private static buildUrl( - endpoint : string, - path : string, - queryParameters : Array<{ key : string, value : string }>, - pathParameters : Map, - ) : string { - const processedEndpoint : string = endpoint.endsWith('/') ? endpoint.substr(0, endpoint.length - 1) : endpoint; - const pathWithParams : string = this.interpolateParams(path, pathParameters); - const isConstantQueryPresent : boolean = pathWithParams.includes('?'); - const queryString : string = this.buildQueryString(queryParameters, isConstantQueryPresent); - - return processedEndpoint + pathWithParams + queryString; - } - - private static interpolateParams(path : string, params : Map) : string { - if (!params) { - return path; - } - - let result : string = path; - - params.forEach((paramValue : string, paramName : string) => { - result = result.replace('{' + paramName + '}', encodeURIComponent(paramValue)); - }); - - return result; - } - - private static buildQueryString(params : Array<{ key : string, value : string }>, isQueryStart : boolean) : string { - if (!params) { - return ''; - } - - const sb : string[] = []; - - if (isQueryStart) { - sb.push('&'); - } else { - sb.push('?'); - } - - params.forEach((obj) => { - sb.push(encodeURIComponent(obj.key)); - sb.push('='); - sb.push(encodeURIComponent(obj.value)); - sb.push('&'); - }); - sb.pop(); - - return sb.join(''); - } - - /** - * ApiConfiguration instance to provide dependencies for this service client - */ - protected apiConfiguration : ApiConfiguration; - - private requestInterceptors : Array<(request : ApiClientRequest) => void | Promise> = []; - private responseInterceptors : Array<(response : ApiClientResponse) => void | Promise> = []; - - /** - * Creates new instance of the BaseServiceClient - * @param {ApiConfiguration} apiConfiguration configuration parameter to provide dependencies to service client instance - */ - protected constructor(apiConfiguration : ApiConfiguration) { - this.apiConfiguration = apiConfiguration; - } - - /** - * Sets array of functions that is going to be executed before the request is send - * @param {Function} requestInterceptor request interceptor function - * @returns {BaseServiceClient} - */ - public withRequestInterceptors(...requestInterceptors : Array<(request : ApiClientRequest) => void | Promise>) : BaseServiceClient { - for ( const interceptor of requestInterceptors ) { - this.requestInterceptors.push(interceptor); - } - - return this; - } - - /** - * Sets array of functions that is going to be executed after the request is send - * @param {Function} responseInterceptor response interceptor function - * @returns {BaseServiceClient} - */ - public withResponseInterceptors(...responseInterceptors : Array<(response : ApiClientResponse) => void | Promise>) : BaseServiceClient { - for ( const interceptor of responseInterceptors ) { - this.responseInterceptors.push(interceptor); - } - - return this; - } - - /** - * Invocation wrapper to implement service operations in generated classes - * @param method HTTP method, such as 'POST', 'GET', 'DELETE', etc. - * @param endpoint base API url - * @param path the path pattern with possible placeholders for path parameters in form {paramName} - * @param pathParams path parameters collection - * @param queryParams query parameters collection - * @param headerParams headers collection - * @param bodyParam if body parameter is present it is provided here, otherwise null or undefined - * @param errors maps recognized status codes to messages - * @param nonJsonBody if the body is in JSON format - */ - protected async invoke( - method : string, - endpoint : string, - path : string, - pathParams : Map, - queryParams : Array<{ key : string, value : string }>, - headerParams : Array<{ key : string, value : string }>, - bodyParam : any, - errors : Map, - nonJsonBody? : boolean, - ) : Promise { - const request : ApiClientRequest = { - url : BaseServiceClient.buildUrl(endpoint, path, queryParams, pathParams), - method, - headers : headerParams, - }; - if (bodyParam != null) { - request.body = nonJsonBody ? bodyParam : JSON.stringify(bodyParam); - } - - const apiClient = this.apiConfiguration.apiClient; - let response : ApiClientResponse; - try { - for (const requestInterceptor of this.requestInterceptors) { - await requestInterceptor(request); - } - response = await apiClient.invoke(request); - for (const responseInterceptor of this.responseInterceptors) { - await responseInterceptor(response); - } - } catch (err) { - err.message = `Call to service failed: ${err.message}`; - - throw err; - } - - let body; - - try { - const contentType = response.headers.find((h) => h.key === 'content-type'); - // json if no content type or content type is application/json - const isJson = !contentType || contentType.value.includes('application/json'); - body = response.body && isJson ? JSON.parse(response.body) : response.body; - // converting to undefined if empty string - body = body || undefined; - } catch (err) { - throw new SyntaxError(`Failed trying to parse the response body: ${response.body}`); - } - - if (BaseServiceClient.isCodeSuccessful(response.statusCode)) { - const apiResponse : ApiResponse = { - headers : response.headers, - body, - statusCode : response.statusCode, - }; - - return apiResponse; - } - - const err = new Error('Unknown error'); - err.name = 'ServiceError'; - err['statusCode'] = response.statusCode; // tslint:disable-line:no-string-literal - err['response'] = body; // tslint:disable-line:no-string-literal - if (errors && errors.has(response.statusCode)) { - err.message = errors.get(response.statusCode); - } - - throw err; - } - } - - /** - * Represents a Login With Amazon(LWA) access token - */ - export interface AccessToken { - token : string; - expiry : Number; - } - - /** - * Represents a request for retrieving a Login With Amazon(LWA) access token - */ - export interface AccessTokenRequest { - clientId : string; - clientSecret : string; - scope? : string; - refreshToken? : string; - } - - /** - * Represents a response returned by LWA containing a Login With Amazon(LWA) access token - */ - export interface AccessTokenResponse { - access_token : string; - expires_in : number; - scope : string; - token_type : string; - } - - /** - * Represents the authentication configuration for a client ID and client secret - */ - export interface AuthenticationConfiguration { - clientId : string; - clientSecret : string; - refreshToken? : string; - authEndpoint? : string; - } - - /** - * Class to be used to call Amazon LWA to retrieve access tokens. - */ - export class LwaServiceClient extends BaseServiceClient { - protected static EXPIRY_OFFSET_MILLIS : number = 60000; - protected static REFRESH_ACCESS_TOKEN : string = 'refresh_access_token'; - protected static CLIENT_CREDENTIALS_GRANT_TYPE : string = 'client_credentials'; - protected static LWA_CREDENTIALS_GRANT_TYPE : string = 'refresh_token'; - protected static AUTH_ENDPOINT : string = 'https://api.amazon.com'; - - protected authenticationConfiguration : AuthenticationConfiguration; - protected tokenStore : {[cacheKey : string] : AccessToken}; - protected grantType : string; - - constructor(options : { - apiConfiguration : ApiConfiguration, - authenticationConfiguration : AuthenticationConfiguration, - grantType? : string, - }) { - super(options.apiConfiguration); - if (options.authenticationConfiguration == null) { - throw new Error('AuthenticationConfiguration cannot be null or undefined.'); - } - this.grantType = options.grantType ? options.grantType : LwaServiceClient.CLIENT_CREDENTIALS_GRANT_TYPE; - this.authenticationConfiguration = options.authenticationConfiguration; - this.tokenStore = {}; - } - - public async getAccessTokenForScope(scope : string) : Promise { - if (scope == null) { - throw new Error('Scope cannot be null or undefined.'); - } - - return this.getAccessToken(scope); - } - - public async getAccessToken(scope? : string) : Promise { - const cacheKey : string = scope ? scope : LwaServiceClient.REFRESH_ACCESS_TOKEN; - const accessToken = this.tokenStore[cacheKey]; - - if (accessToken && accessToken.expiry > Date.now() + LwaServiceClient.EXPIRY_OFFSET_MILLIS) { - return accessToken.token; - } - - const accessTokenRequest : AccessTokenRequest = { - clientId : this.authenticationConfiguration.clientId, - clientSecret : this.authenticationConfiguration.clientSecret, - }; - if (scope && this.authenticationConfiguration.refreshToken) { - throw new Error('Cannot support both refreshToken and scope.'); - } else if (scope == null && this.authenticationConfiguration.refreshToken == null) { - throw new Error('Either refreshToken or scope must be specified.'); - } else if (scope == null) { - accessTokenRequest.refreshToken = this.authenticationConfiguration.refreshToken; - } else { - accessTokenRequest.scope = scope; - } - - const accessTokenResponse : AccessTokenResponse = await this.generateAccessToken(accessTokenRequest); - - this.tokenStore[cacheKey] = { - token : accessTokenResponse.access_token, - expiry : Date.now() + accessTokenResponse.expires_in * 1000, - }; - - return accessTokenResponse.access_token; - } - - protected async generateAccessToken(accessTokenRequest : AccessTokenRequest) : Promise { - const authEndpoint = this.authenticationConfiguration.authEndpoint || LwaServiceClient.AUTH_ENDPOINT; - - if (accessTokenRequest == null) { - throw new Error(`Required parameter accessTokenRequest was null or undefined when calling generateAccessToken.`); - } - - const queryParams : Array<{ key : string, value : string }> = []; - - const headerParams : Array<{key : string, value : string}> = []; - headerParams.push({key : 'Content-type', value : 'application/x-www-form-urlencoded'}); - - const pathParams : Map = new Map(); - - const paramInfo = this.grantType === LwaServiceClient.LWA_CREDENTIALS_GRANT_TYPE ? `&refresh_token=${accessTokenRequest.refreshToken}` : `&scope=${accessTokenRequest.scope}`; - const bodyParams : string = `grant_type=${this.grantType}&client_secret=${accessTokenRequest.clientSecret}&client_id=${accessTokenRequest.clientId}` + paramInfo; - - const errorDefinitions : Map = new Map(); - errorDefinitions.set(200, 'Token request sent.'); - errorDefinitions.set(400, 'Bad Request'); - errorDefinitions.set(401, 'Authentication Failed'); - errorDefinitions.set(500, 'Internal Server Error'); - - const apiResponse : ApiResponse = await this.invoke( - 'POST', - authEndpoint, - '/auth/O2/token', - pathParams, - queryParams, - headerParams, - bodyParams, - errorDefinitions, - true, - ); - - return apiResponse.body as AccessTokenResponse; - } - } -} - -/** - * function creating an AskSdk user agent. - * @param packageVersion - * @param customUserAgent - */ -export function createUserAgent(packageVersion : string, customUserAgent : string) : string { - const customUserAgentString = customUserAgent ? (' ' + customUserAgent) : ''; - - return `ask-node-model/${packageVersion} Node/${process.version}` + customUserAgentString; -} +export namespace services { + /** + * Represents the interface between ApiClient and a Service Client. + * @export + * @interface ApiClientMessage + */ + export interface ApiClientMessage { + headers : Array<{key : string, value : string}>; + body? : string; + } + + /** + * Represents a request sent from Service Clients to an ApiClient implementation. + * @export + * @interface ApiClientRequest + * @extends {ApiClientMessage} + */ + export interface ApiClientRequest extends ApiClientMessage { + url : string; + method : string; + } + + /** + * Represents a response returned by ApiClient implementation to a Service Client. + * @export + * @interface ApiClientResponse + * @extends {ApiClientMessage} + */ + export interface ApiClientResponse extends ApiClientMessage { + /** + * Result code of the attempt to satisfy the request. Normally this + * corresponds to the HTTP status code returned by the server. + */ + statusCode : number; + } + + /** + * Represents a response with parsed body. + * @export + * @interface ApiResponse + */ + export interface ApiResponse { + headers : Array<{key : string, value : string}>; + body? : any; + statusCode : number; + } + + /** + * Represents a basic contract for API request execution + * @export + * @interface ApiClient + */ + export interface ApiClient { + /** + * Dispatches a request to an API endpoint described in the request. + * An ApiClient is expected to resolve the Promise in the case an API returns a non-200 HTTP + * status code. The responsibility of translating a particular response code to an error lies with the + * caller to invoke. + * @param {ApiClientRequest} request request to dispatch to the ApiClient + * @returns {Promise} Response from the ApiClient + * @memberof ApiClient + */ + invoke(request : ApiClientRequest) : Promise; + } + + /** + * Represents an interface that provides API configuration options needed by service clients. + * @interface ApiConfiguration + */ + export interface ApiConfiguration { + /** + * Configured ApiClient implementation + */ + apiClient : ApiClient; + /** + * Authorization value to be used on any calls of the service client instance + */ + authorizationValue : string; + /** + * Endpoint to hit by the service client instance + */ + apiEndpoint : string; + } + + /** + * Class to be used as the base class for the generated service clients. + */ + export abstract class BaseServiceClient { + private static isCodeSuccessful( responseCode : number ) : boolean { + return responseCode >= 200 && responseCode < 300; + } + + private static buildUrl( + endpoint : string, + path : string, + queryParameters : Array<{ key : string, value : string }>, + pathParameters : Map, + ) : string { + const processedEndpoint : string = endpoint.endsWith('/') ? endpoint.substr(0, endpoint.length - 1) : endpoint; + const pathWithParams : string = this.interpolateParams(path, pathParameters); + const isConstantQueryPresent : boolean = pathWithParams.includes('?'); + const queryString : string = this.buildQueryString(queryParameters, isConstantQueryPresent); + + return processedEndpoint + pathWithParams + queryString; + } + + private static interpolateParams(path : string, params : Map) : string { + if (!params) { + return path; + } + + let result : string = path; + + params.forEach((paramValue : string, paramName : string) => { + result = result.replace('{' + paramName + '}', encodeURIComponent(paramValue)); + }); + + return result; + } + + private static buildQueryString(params : Array<{ key : string, value : string }>, isQueryStart : boolean) : string { + if (!params) { + return ''; + } + + const sb : string[] = []; + + if (isQueryStart) { + sb.push('&'); + } else { + sb.push('?'); + } + + params.forEach((obj) => { + sb.push(encodeURIComponent(obj.key)); + sb.push('='); + sb.push(encodeURIComponent(obj.value)); + sb.push('&'); + }); + sb.pop(); + + return sb.join(''); + } + + /** + * ApiConfiguration instance to provide dependencies for this service client + */ + protected apiConfiguration : ApiConfiguration; + + private requestInterceptors : Array<(request : ApiClientRequest) => void | Promise> = []; + private responseInterceptors : Array<(response : ApiClientResponse) => void | Promise> = []; + + /** + * Creates new instance of the BaseServiceClient + * @param {ApiConfiguration} apiConfiguration configuration parameter to provide dependencies to service client instance + */ + protected constructor(apiConfiguration : ApiConfiguration) { + this.apiConfiguration = apiConfiguration; + } + + /** + * Sets array of functions that is going to be executed before the request is send + * @param {Function} requestInterceptor request interceptor function + * @returns {BaseServiceClient} + */ + public withRequestInterceptors(...requestInterceptors : Array<(request : ApiClientRequest) => void | Promise>) : BaseServiceClient { + for ( const interceptor of requestInterceptors ) { + this.requestInterceptors.push(interceptor); + } + + return this; + } + + /** + * Sets array of functions that is going to be executed after the request is send + * @param {Function} responseInterceptor response interceptor function + * @returns {BaseServiceClient} + */ + public withResponseInterceptors(...responseInterceptors : Array<(response : ApiClientResponse) => void | Promise>) : BaseServiceClient { + for ( const interceptor of responseInterceptors ) { + this.responseInterceptors.push(interceptor); + } + + return this; + } + + /** + * Invocation wrapper to implement service operations in generated classes + * @param method HTTP method, such as 'POST', 'GET', 'DELETE', etc. + * @param endpoint base API url + * @param path the path pattern with possible placeholders for path parameters in form {paramName} + * @param pathParams path parameters collection + * @param queryParams query parameters collection + * @param headerParams headers collection + * @param bodyParam if body parameter is present it is provided here, otherwise null or undefined + * @param errors maps recognized status codes to messages + * @param nonJsonBody if the body is in JSON format + */ + protected async invoke( + method : string, + endpoint : string, + path : string, + pathParams : Map, + queryParams : Array<{ key : string, value : string }>, + headerParams : Array<{ key : string, value : string }>, + bodyParam : any, + errors : Map, + nonJsonBody? : boolean, + ) : Promise { + const request : ApiClientRequest = { + url : BaseServiceClient.buildUrl(endpoint, path, queryParams, pathParams), + method, + headers : headerParams, + }; + if (bodyParam != null) { + request.body = nonJsonBody ? bodyParam : JSON.stringify(bodyParam); + } + + const apiClient = this.apiConfiguration.apiClient; + let response : ApiClientResponse; + try { + for (const requestInterceptor of this.requestInterceptors) { + await requestInterceptor(request); + } + response = await apiClient.invoke(request); + for (const responseInterceptor of this.responseInterceptors) { + await responseInterceptor(response); + } + } catch (err) { + err.message = `Call to service failed: ${err.message}`; + + throw err; + } + + let body; + + try { + const contentType = response.headers.find((h) => h.key === 'content-type'); + // json if no content type or content type is application/json + const isJson = !contentType || contentType.value.includes('application/json'); + body = response.body && isJson ? JSON.parse(response.body) : response.body; + // converting to undefined if empty string + body = body || undefined; + } catch (err) { + throw new SyntaxError(`Failed trying to parse the response body: ${response.body}`); + } + + if (BaseServiceClient.isCodeSuccessful(response.statusCode)) { + const apiResponse : ApiResponse = { + headers : response.headers, + body, + statusCode : response.statusCode, + }; + + return apiResponse; + } + + const err = new Error('Unknown error'); + err.name = 'ServiceError'; + err['statusCode'] = response.statusCode; // tslint:disable-line:no-string-literal + err['response'] = body; // tslint:disable-line:no-string-literal + if (errors && errors.has(response.statusCode)) { + err.message = errors.get(response.statusCode); + } + + throw err; + } + } + + /** + * Represents a Login With Amazon(LWA) access token + */ + export interface AccessToken { + token : string; + expiry : Number; + } + + /** + * Represents a request for retrieving a Login With Amazon(LWA) access token + */ + export interface AccessTokenRequest { + clientId : string; + clientSecret : string; + scope? : string; + refreshToken? : string; + } + + /** + * Represents a response returned by LWA containing a Login With Amazon(LWA) access token + */ + export interface AccessTokenResponse { + access_token : string; + expires_in : number; + scope : string; + token_type : string; + } + + /** + * Represents the authentication configuration for a client ID and client secret + */ + export interface AuthenticationConfiguration { + clientId : string; + clientSecret : string; + refreshToken? : string; + authEndpoint? : string; + } + + /** + * Class to be used to call Amazon LWA to retrieve access tokens. + */ + export class LwaServiceClient extends BaseServiceClient { + protected static EXPIRY_OFFSET_MILLIS : number = 60000; + protected static REFRESH_ACCESS_TOKEN : string = 'refresh_access_token'; + protected static CLIENT_CREDENTIALS_GRANT_TYPE : string = 'client_credentials'; + protected static LWA_CREDENTIALS_GRANT_TYPE : string = 'refresh_token'; + protected static AUTH_ENDPOINT : string = 'https://api.amazon.com'; + + protected authenticationConfiguration : AuthenticationConfiguration; + protected tokenStore : {[cacheKey : string] : AccessToken}; + protected grantType : string; + + constructor(options : { + apiConfiguration : ApiConfiguration, + authenticationConfiguration : AuthenticationConfiguration, + grantType? : string, + }) { + super(options.apiConfiguration); + if (options.authenticationConfiguration == null) { + throw new Error('AuthenticationConfiguration cannot be null or undefined.'); + } + this.grantType = options.grantType ? options.grantType : LwaServiceClient.CLIENT_CREDENTIALS_GRANT_TYPE; + this.authenticationConfiguration = options.authenticationConfiguration; + this.tokenStore = {}; + } + + public async getAccessTokenForScope(scope : string) : Promise { + if (scope == null) { + throw new Error('Scope cannot be null or undefined.'); + } + + return this.getAccessToken(scope); + } + + public async getAccessToken(scope? : string) : Promise { + const cacheKey : string = scope ? scope : LwaServiceClient.REFRESH_ACCESS_TOKEN; + const accessToken = this.tokenStore[cacheKey]; + + if (accessToken && accessToken.expiry > Date.now() + LwaServiceClient.EXPIRY_OFFSET_MILLIS) { + return accessToken.token; + } + + const accessTokenRequest : AccessTokenRequest = { + clientId : this.authenticationConfiguration.clientId, + clientSecret : this.authenticationConfiguration.clientSecret, + }; + if (scope && this.authenticationConfiguration.refreshToken) { + throw new Error('Cannot support both refreshToken and scope.'); + } else if (scope == null && this.authenticationConfiguration.refreshToken == null) { + throw new Error('Either refreshToken or scope must be specified.'); + } else if (scope == null) { + accessTokenRequest.refreshToken = this.authenticationConfiguration.refreshToken; + } else { + accessTokenRequest.scope = scope; + } + + const accessTokenResponse : AccessTokenResponse = await this.generateAccessToken(accessTokenRequest); + + this.tokenStore[cacheKey] = { + token : accessTokenResponse.access_token, + expiry : Date.now() + accessTokenResponse.expires_in * 1000, + }; + + return accessTokenResponse.access_token; + } + + protected async generateAccessToken(accessTokenRequest : AccessTokenRequest) : Promise { + const authEndpoint = this.authenticationConfiguration.authEndpoint || LwaServiceClient.AUTH_ENDPOINT; + + if (accessTokenRequest == null) { + throw new Error(`Required parameter accessTokenRequest was null or undefined when calling generateAccessToken.`); + } + + const queryParams : Array<{ key : string, value : string }> = []; + + const headerParams : Array<{key : string, value : string}> = []; + headerParams.push({key : 'Content-type', value : 'application/x-www-form-urlencoded'}); + + const pathParams : Map = new Map(); + + const paramInfo = this.grantType === LwaServiceClient.LWA_CREDENTIALS_GRANT_TYPE ? `&refresh_token=${accessTokenRequest.refreshToken}` : `&scope=${accessTokenRequest.scope}`; + const bodyParams : string = `grant_type=${this.grantType}&client_secret=${accessTokenRequest.clientSecret}&client_id=${accessTokenRequest.clientId}` + paramInfo; + + const errorDefinitions : Map = new Map(); + errorDefinitions.set(200, 'Token request sent.'); + errorDefinitions.set(400, 'Bad Request'); + errorDefinitions.set(401, 'Authentication Failed'); + errorDefinitions.set(500, 'Internal Server Error'); + + const apiResponse : ApiResponse = await this.invoke( + 'POST', + authEndpoint, + '/auth/O2/token', + pathParams, + queryParams, + headerParams, + bodyParams, + errorDefinitions, + true, + ); + + return apiResponse.body as AccessTokenResponse; + } + } +} + +/** + * function creating an AskSdk user agent. + * @param packageVersion + * @param customUserAgent + */ +export function createUserAgent(packageVersion : string, customUserAgent : string) : string { + const customUserAgentString = customUserAgent ? (' ' + customUserAgent) : ''; + + return `ask-node-model/${packageVersion} Node/${process.version}` + customUserAgentString; +} /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -2140,11 +2140,23 @@ export namespace interfaces.system { 'user': User; 'device'?: Device; 'person'?: Person; + 'unit'?: interfaces.systemUnit.Unit; 'apiEndpoint': string; 'apiAccessToken'?: string; } } +export namespace interfaces.systemUnit { + /** + * An object that represents a logical entity for organizing actors and resources that interact with Alexa systems. + * @interface + */ + export interface Unit { + 'unitId'?: string; + 'persistentUnitId'?: string; + } +} + export namespace interfaces.videoapp { /** * @@ -8133,5 +8145,4 @@ export namespace services { } } } -} - +} \ No newline at end of file diff --git a/ask-sdk-model/package.json b/ask-sdk-model/package.json index cf6a319..d29c63d 100644 --- a/ask-sdk-model/package.json +++ b/ask-sdk-model/package.json @@ -28,7 +28,7 @@ "@types/node": "^9.6.1", "del": "^3.0.0", "gulp": "^4.0.0", - "typescript": "^2.8.1" + "typescript": "^3.5.3" }, "repository": "github:alexa/alexa-apis-for-nodejs", "bugs": "https://github.com/alexa/alexa-skill-sdk-for-nodejs/issues",