@sap-cloud-sdk/connectivity
Version:
SAP Cloud SDK for JavaScript connectivity
131 lines • 6.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useOrFetchDestination = useOrFetchDestination;
exports.resolveDestination = resolveDestination;
exports.getDestination = getDestination;
exports.getAllDestinationsFromDestinationService = getAllDestinationsFromDestinationService;
const util_1 = require("@sap-cloud-sdk/util");
const identity_service_1 = require("../identity-service");
const environment_accessor_1 = require("../environment-accessor");
const jwt_1 = require("../jwt");
const token_accessor_1 = require("../token-accessor");
const destination_1 = require("./destination");
const destination_from_env_1 = require("./destination-from-env");
const destination_from_vcap_1 = require("./destination-from-vcap");
const destination_from_service_1 = require("./destination-from-service");
const destination_accessor_types_1 = require("./destination-accessor-types");
const destination_from_registration_1 = require("./destination-from-registration");
const get_subscriber_token_1 = require("./get-subscriber-token");
const get_provider_token_1 = require("./get-provider-token");
const destination_service_1 = require("./destination-service");
const logger = (0, util_1.createLogger)({
package: 'connectivity',
messageContext: 'destination-accessor'
});
/**
* Returns the parameter if it is a destination, calls {@link getDestination} otherwise (which will try to fetch the destination
* from the Cloud Foundry destination service).
*
* Fetching a destination requires:
* - A binding to exactly one XSUAA service instance with service plan "application".
* - A binding to a destination service instance.
*
* If either of the prerequisites is not met or one of the services returns an error, this function will either throw an error or return a promise that rejects.
* @param destination - A destination or the necessary parameters to fetch one.
* @returns A promise resolving to the requested destination on success.
*/
async function useOrFetchDestination(destination) {
return (0, destination_accessor_types_1.isDestinationFetchOptions)(destination)
? getDestination(destination)
: (0, destination_1.sanitizeDestination)(destination);
}
/**
* Resolve a destination by the following steps:
* 1. Call [[useOrFetchDestination]]
* 2. Throw an error, when the resulting destination from the previous step is falsy
* 3. Return the checked destination.
* @param destination - A destination or the necessary parameters to fetch one.
* @returns A promise resolving to the requested destination on success.
* @internal
*/
async function resolveDestination(destination) {
const resolvedDestination = await useOrFetchDestination(destination).catch(error => {
throw new util_1.ErrorWithCause('Failed to load destination.', error);
});
if (!resolvedDestination) {
throw Error(`Failed to resolve the destination '${(0, destination_1.toDestinationNameUrl)(destination)}'.`);
}
return resolvedDestination;
}
/**
* Builds a destination from one of three sources (in the given order):
* - from the environment variable "destinations".
* - from service bindings.
* - from the destination service.
*
* If you want to get a destination only from a specific source, use the corresponding function directly
* (`getDestinationFromEnvByName`, `getDestinationFromServiceBinding`, `getDestinationFromDestinationService`).
* @param options - The options to retrieve the destination.
* @returns A promise returning the requested destination on success.
*/
async function getDestination(options) {
const destination = (0, destination_from_env_1.searchEnvVariablesForDestination)(options) ||
(await (0, destination_from_registration_1.searchRegisteredDestination)(options)) ||
(await (0, destination_from_vcap_1.searchServiceBindingForDestination)(options)) ||
(await (0, destination_from_service_1.getDestinationFromDestinationService)(options));
return destination;
}
/**
* Creates comprehensive log messages from a destinations array and their origin.
* @param origin - Origin of the destination.
* @param destinations - Array of destinations.
* @returns Logs of the retrieval of destinations.
*/
function createDestinationFetchLogs(origin, destinations) {
return destinations.reduce((prevLogMessages, currentDestination) => prevLogMessages +
`Retrieving ${origin} destination: ${currentDestination.name}.\n`, '');
}
/**
* Fetches all destinations from the destination service which match the token.
* With a subscriber token it fetches all subscriber destinations, otherwise all provider destinations.
* @param options - The {@link AllDestinationOptions | options} to fetch all destinations.
* @returns A promise of an array of all destinations without authTokens from the destination service, on success.
*/
async function getAllDestinationsFromDestinationService(options = {}) {
options = {
...options,
// Enable caching by default
useCache: options.useCache ?? true
};
logger.debug('Attempting to retrieve all destinations from destination service.');
if ((0, identity_service_1.shouldExchangeToken)(options) && options.jwt) {
// Exchange the IAS token to a XSUAA token using the destination service credentials
options.jwt = await (0, token_accessor_1.jwtBearerToken)(options.jwt, 'destination');
}
const token = (await (0, get_subscriber_token_1.getSubscriberToken)(options))?.serviceJwt ||
(await (0, get_provider_token_1.getProviderServiceToken)(options));
const destinationServiceUri = (0, environment_accessor_1.getDestinationServiceCredentials)().uri;
const subdomain = (0, jwt_1.getSubdomain)(token.decoded);
logger.debug(`Retrieving all destinations for account: "${subdomain}" from destination service.`);
const [instance, subaccount] = await Promise.all([
(0, destination_service_1.fetchDestinations)(destinationServiceUri, token.encoded, 'instance', options),
(0, destination_service_1.fetchDestinations)(destinationServiceUri, token.encoded, 'subaccount', options)
]);
const loggerMessage = createDestinationFetchLogs('instance', instance) +
createDestinationFetchLogs('subaccount', subaccount);
logger.debug(loggerMessage);
const allDestinations = [...instance, ...subaccount];
if (allDestinations?.length) {
logger.debug(`Successfully retrieved all destinations for account: "${subdomain}" from destination service.`);
}
else {
logger.debug("Didn't receive any destinations from destination service.");
return [];
}
const allDestinationsWithoutToken = allDestinations.map(destination => {
delete destination.authTokens;
return destination;
});
return allDestinationsWithoutToken;
}
//# sourceMappingURL=destination-accessor.js.map