@sap-ux/odata-service-inquirer 0.5.60 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/error-handler/error-handler.d.ts +25 -3
  2. package/dist/error-handler/error-handler.js +154 -52
  3. package/dist/i18n.js +15 -3
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +1 -3
  6. package/dist/prompts/connectionValidator.d.ts +63 -12
  7. package/dist/prompts/connectionValidator.js +196 -38
  8. package/dist/prompts/datasources/sap-system/abap-on-btp/questions.d.ts +2 -1
  9. package/dist/prompts/datasources/sap-system/abap-on-btp/questions.js +3 -1
  10. package/dist/prompts/datasources/sap-system/abap-on-prem/questions.d.ts +9 -11
  11. package/dist/prompts/datasources/sap-system/abap-on-prem/questions.js +21 -55
  12. package/dist/prompts/datasources/sap-system/credentials/questions.d.ts +21 -0
  13. package/dist/prompts/datasources/sap-system/credentials/questions.js +123 -0
  14. package/dist/prompts/datasources/sap-system/new-system/questions.d.ts +4 -26
  15. package/dist/prompts/datasources/sap-system/new-system/questions.js +18 -168
  16. package/dist/prompts/datasources/sap-system/new-system/types.d.ts +0 -10
  17. package/dist/prompts/datasources/sap-system/service-selection/index.d.ts +3 -0
  18. package/dist/prompts/datasources/sap-system/service-selection/index.js +19 -0
  19. package/dist/prompts/datasources/sap-system/service-selection/questions.d.ts +15 -0
  20. package/dist/prompts/datasources/sap-system/service-selection/questions.js +146 -0
  21. package/dist/prompts/datasources/sap-system/service-selection/service-helper.d.ts +71 -0
  22. package/dist/prompts/datasources/sap-system/service-selection/service-helper.js +281 -0
  23. package/dist/prompts/datasources/sap-system/service-selection/types.d.ts +11 -0
  24. package/dist/prompts/datasources/sap-system/service-selection/types.js +3 -0
  25. package/dist/prompts/datasources/sap-system/system-selection/index.d.ts +2 -0
  26. package/dist/prompts/datasources/sap-system/system-selection/index.js +18 -0
  27. package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.d.ts +44 -0
  28. package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.js +190 -0
  29. package/dist/prompts/datasources/sap-system/system-selection/questions.d.ts +40 -0
  30. package/dist/prompts/datasources/sap-system/system-selection/questions.js +181 -0
  31. package/dist/prompts/datasources/sap-system/validators.d.ts +8 -0
  32. package/dist/prompts/datasources/sap-system/validators.js +17 -0
  33. package/dist/prompts/datasources/service-url/questions.js +2 -2
  34. package/dist/prompts/datasources/service-url/validators.js +5 -6
  35. package/dist/prompts/prompt-helpers.d.ts +1 -2
  36. package/dist/prompts/prompt-helpers.js +2 -11
  37. package/dist/prompts/prompts.js +5 -34
  38. package/dist/prompts/validators.d.ts +1 -1
  39. package/dist/prompts/validators.js +1 -1
  40. package/dist/translations/odata-service-inquirer.i18n.json +36 -15
  41. package/dist/types.d.ts +57 -10
  42. package/dist/types.js +7 -1
  43. package/dist/utils/index.d.ts +12 -3
  44. package/dist/utils/index.js +27 -5
  45. package/package.json +6 -6
  46. package/dist/prompts/datasources/sap-system/new-system/service-helper.d.ts +0 -43
  47. package/dist/prompts/datasources/sap-system/new-system/service-helper.js +0 -175
@@ -0,0 +1,71 @@
1
+ import { type IMessageSeverity } from '@sap-devx/yeoman-ui-types';
2
+ import { type CatalogService, ServiceType, V2CatalogService } from '@sap-ux/axios-extension';
3
+ import type { Destination } from '@sap-ux/btp-utils';
4
+ import { OdataVersion } from '@sap-ux/odata-service-writer';
5
+ import type { ListChoiceOptions } from 'inquirer';
6
+ import type { ConnectionValidator } from '../../../connectionValidator';
7
+ import type { ServiceAnswer } from './types';
8
+ export declare const telemEventBASServiceSuccess = "SERVICE_INQUIRER_BAS_SUCCESS";
9
+ /**
10
+ * Refines the error type and logs based on the specified options. This should log more precise error messages based on inputs
11
+ * and the platform making the call i.e. VSC | SBAS. Errors are mapped to GA links if the platform is SBAS.
12
+ *
13
+ * @param options Options
14
+ * @param options.system - sap system used
15
+ * @param options.catRequestErrorTypes - all catalog service request error types, used to do further root cause analysis
16
+ * @param options.rootCauseErrorType - the error type as determined by the caller, will be used if a more precise error type cannot be determined by rca
17
+ * @param options.logMsg - the log message that will be used if a better root cause is not determined
18
+ * @param options.error - the original error, used to determine the error log message if otherwise not determined
19
+ * @param option.reqVersion - specific odata version that is required by the template
20
+ */
21
+ /**
22
+ * Get the service choices from the specified catalogs.
23
+ *
24
+ * @param catalogs catalogs to get the services from. There should be one per odata version required.
25
+ * @returns service choices based on the provided catalogs
26
+ */
27
+ export declare function getServiceChoices(catalogs: CatalogService[]): Promise<ListChoiceOptions<ServiceAnswer>[]>;
28
+ /**
29
+ * Generates a telemetry event for successfully listing service(s) using a destination.
30
+ *
31
+ * @param destination the destination used to list the service(s)
32
+ */
33
+ export declare function sendDestinationServiceSuccessTelemetryEvent(destination: Destination): void;
34
+ /**
35
+ * Get service type for 'Not Determined' services from `ServiceTypeForHUBServices()`
36
+ *
37
+ * @param servicePath service path
38
+ * @param serviceType service type
39
+ * @param catalog the catalog service used to get the service type for the specified service path
40
+ * @returns service type
41
+ */
42
+ export declare function getServiceType(servicePath: string, serviceType: string | undefined, catalog: V2CatalogService): Promise<ServiceType | undefined>;
43
+ /**
44
+ * Requests and sets the service details to the PromptState.odataService properties.
45
+ * If an error occurs, the error message is returned for use in validators.
46
+ *
47
+ * @param service the specific service to get details for
48
+ * @param connectionValidator a reference to the connection validator which has an active connection to the backend
49
+ * @param requiredOdataVersion
50
+ * @returns true if successful, setting the PromptState.odataService properties, or an error message indicating why the service details could not be retrieved.
51
+ */
52
+ export declare function getServiceDetails(service: ServiceAnswer, connectionValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion): Promise<string | boolean>;
53
+ /**
54
+ * Create a value for the service selection prompt message, which may include thge active connected user name.
55
+ *
56
+ * @param username The connected user name
57
+ * @returns The service selection prompt message
58
+ */
59
+ export declare function getSelectedServiceLabel(username: string | undefined): string;
60
+ /**
61
+ * Get the service selection prompt additional message. This prompt will make an additional call to the system backend
62
+ * to retrieve the service type and display a warning message if the service type is not UI.
63
+ *
64
+ * @param serviceChoices a list of service choices
65
+ * @param selectedService the selected service
66
+ * @param connectValidator the connection validator
67
+ * @param requiredOdataVersion the required OData version for the service
68
+ * @returns the service selection prompt additional message
69
+ */
70
+ export declare function getSelectedServiceMessage(serviceChoices: ListChoiceOptions<ServiceAnswer>[], selectedService: ServiceAnswer, connectValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion): Promise<IMessageSeverity | undefined>;
71
+ //# sourceMappingURL=service-helper.d.ts.map
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.telemEventBASServiceSuccess = void 0;
7
+ exports.getServiceChoices = getServiceChoices;
8
+ exports.sendDestinationServiceSuccessTelemetryEvent = sendDestinationServiceSuccessTelemetryEvent;
9
+ exports.getServiceType = getServiceType;
10
+ exports.getServiceDetails = getServiceDetails;
11
+ exports.getSelectedServiceLabel = getSelectedServiceLabel;
12
+ exports.getSelectedServiceMessage = getSelectedServiceMessage;
13
+ const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
14
+ const axios_extension_1 = require("@sap-ux/axios-extension");
15
+ const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
16
+ const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
17
+ const i18n_1 = require("../../../../i18n");
18
+ const utils_1 = require("../../../../utils");
19
+ const logger_helper_1 = __importDefault(require("../../../logger-helper"));
20
+ const prompt_helpers_1 = require("../../../prompt-helpers");
21
+ const validators_1 = require("../../../validators");
22
+ // Service ids continaining these paths should not be offered as UI compatible services
23
+ const nonUIServicePaths = ['/IWBEP/COMMON/'];
24
+ // Telemetry event name for successful service validation on BAS, note: legacy event names should not be changed
25
+ exports.telemEventBASServiceSuccess = 'SERVICE_INQUIRER_BAS_SUCCESS';
26
+ /**
27
+ * Builds and formats the service choices list.
28
+ *
29
+ * @param serviceInfos service information to build the choices from. Services with a service id containing '/IWBEP/COMMON' are ignored.
30
+ * @returns service choices list
31
+ */
32
+ const createServiceChoices = (serviceInfos) => {
33
+ const choices = [];
34
+ // Provide additional service information in trace mode (YUI only)
35
+ let isLogTrace = false;
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Only specific loggers have this method
37
+ if (typeof logger_helper_1.default.logger.getLogLevel === 'function') {
38
+ isLogTrace = logger_helper_1.default.logger.getLogLevel() === 'trace';
39
+ }
40
+ serviceInfos
41
+ // Exclude non-UI compatible services
42
+ ?.filter((service) => !nonUIServicePaths.some((path) => service.path.includes(path)))
43
+ .forEach((service) => {
44
+ let serviceName = service.name;
45
+ const servicePath = service.path;
46
+ serviceName = `${serviceName} (${service.serviceVersion}) - OData V${service.odataVersion}`;
47
+ if (isLogTrace) {
48
+ serviceName = `${serviceName} Service Type: ${service.serviceType}`;
49
+ }
50
+ choices.push({
51
+ name: serviceName,
52
+ value: {
53
+ servicePath,
54
+ serviceODataVersion: service.odataVersion,
55
+ toString: () => serviceName,
56
+ serviceType: service.serviceType
57
+ }
58
+ });
59
+ });
60
+ return choices.sort((a, b) => (a.name ? a.name.localeCompare(b.name ?? '') : 0));
61
+ };
62
+ /**
63
+ * Logs the catalog request errors using the error handler.
64
+ *
65
+ * @param requestErrors catalog request errors, keyed by the OData version of the catalog service, with the error, status code number or error message as the value
66
+ * @param numOfRequests
67
+ */
68
+ function logServiceCatalogErrorsForHelp(requestErrors, numOfRequests) {
69
+ const catalogRequesErrors = Object.values(requestErrors);
70
+ catalogRequesErrors.forEach((error) => {
71
+ prompt_helpers_1.errorHandler.logErrorMsgs(error); // Log and process the error -> error type
72
+ });
73
+ // If all requests failed, log a generic message, this will be stored in the error handler
74
+ if (numOfRequests === catalogRequesErrors.length) {
75
+ prompt_helpers_1.errorHandler.logErrorMsgs((0, i18n_1.t)('errors.allCatalogServiceRequestsFailed', { version: Object.keys(requestErrors).join(', ') }));
76
+ }
77
+ }
78
+ /**
79
+ * Refines the error type and logs based on the specified options. This should log more precise error messages based on inputs
80
+ * and the platform making the call i.e. VSC | SBAS. Errors are mapped to GA links if the platform is SBAS.
81
+ *
82
+ * @param options Options
83
+ * @param options.system - sap system used
84
+ * @param options.catRequestErrorTypes - all catalog service request error types, used to do further root cause analysis
85
+ * @param options.rootCauseErrorType - the error type as determined by the caller, will be used if a more precise error type cannot be determined by rca
86
+ * @param options.logMsg - the log message that will be used if a better root cause is not determined
87
+ * @param options.error - the original error, used to determine the error log message if otherwise not determined
88
+ * @param option.reqVersion - specific odata version that is required by the template
89
+ */
90
+ /**
91
+ * Get the service choices from the specified catalogs.
92
+ *
93
+ * @param catalogs catalogs to get the services from. There should be one per odata version required.
94
+ * @returns service choices based on the provided catalogs
95
+ */
96
+ async function getServiceChoices(catalogs) {
97
+ const requestErrors = {};
98
+ const listServicesRequests = catalogs.map(async (catalog) => {
99
+ try {
100
+ return await catalog.listServices();
101
+ }
102
+ catch (error) {
103
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.serviceCatalogRequest', {
104
+ catalogRequestUri: catalog.getUri(),
105
+ entitySet: catalog.entitySet,
106
+ error
107
+ }));
108
+ // Save any errors for processing later as we may show more useful message to the user
109
+ Object.assign(requestErrors, {
110
+ [catalog instanceof axios_extension_1.V2CatalogService ? axios_extension_1.ODataVersion.v2 : axios_extension_1.ODataVersion.v4]: error
111
+ });
112
+ return [];
113
+ }
114
+ });
115
+ const serviceInfos = await Promise.all(listServicesRequests);
116
+ const flatServices = serviceInfos?.flat() ?? [];
117
+ logger_helper_1.default.logger.debug(`Number of services available: ${flatServices.length}`);
118
+ if (flatServices.length === 0) {
119
+ logServiceCatalogErrorsForHelp(requestErrors, catalogs.length);
120
+ }
121
+ return createServiceChoices(flatServices);
122
+ }
123
+ /**
124
+ * Generates a telemetry event for successfully listing service(s) using a destination.
125
+ *
126
+ * @param destination the destination used to list the service(s)
127
+ */
128
+ function sendDestinationServiceSuccessTelemetryEvent(destination) {
129
+ // May return undefined if the same event was already sent within some time frame
130
+ const telemetryData = fiori_generator_shared_1.TelemetryHelper.createTelemetryData({
131
+ destODataType: (0, utils_1.getTelemPropertyDestinationType)(destination)
132
+ }) ?? {};
133
+ (0, utils_1.sendTelemetryEvent)(exports.telemEventBASServiceSuccess, telemetryData);
134
+ }
135
+ /**
136
+ * Gets the service metadata and annotations for the specified service path.
137
+ *
138
+ * @param servicePath service path
139
+ * @param odataService the odata service used to get the metadata for the specified service path
140
+ * @param catalog the catalog service used to get the annotations for the specified service path
141
+ * @returns Promise<string | boolean>, string error message or true if successful
142
+ */
143
+ async function getServiceMetadata(servicePath, odataService, catalog) {
144
+ let annotations = [];
145
+ try {
146
+ if (catalog) {
147
+ try {
148
+ annotations = await catalog.getAnnotations({ path: servicePath });
149
+ }
150
+ catch {
151
+ logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.noAnnotations'));
152
+ }
153
+ }
154
+ const metadata = await odataService.metadata();
155
+ return {
156
+ annotations,
157
+ metadata
158
+ };
159
+ }
160
+ catch (error) {
161
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.serviceMetadataErrorLog', { servicePath, error }));
162
+ return (0, i18n_1.t)('errors.serviceMetadataErrorUI', { servicePath });
163
+ }
164
+ }
165
+ /**
166
+ * Get service type for 'Not Determined' services from `ServiceTypeForHUBServices()`
167
+ *
168
+ * @param servicePath service path
169
+ * @param serviceType service type
170
+ * @param catalog the catalog service used to get the service type for the specified service path
171
+ * @returns service type
172
+ */
173
+ async function getServiceType(servicePath, serviceType, catalog) {
174
+ let resolvedServiceType;
175
+ if (serviceType === axios_extension_1.ServiceType.NotDetermined) {
176
+ try {
177
+ resolvedServiceType = (await catalog.getServiceType(servicePath)) ?? axios_extension_1.ServiceType.NotDetermined;
178
+ }
179
+ catch (e) {
180
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.serviceTypeRequestError', { error: e.message }));
181
+ }
182
+ }
183
+ return resolvedServiceType ?? serviceType;
184
+ }
185
+ /**
186
+ * Requests and sets the service details to the PromptState.odataService properties.
187
+ * If an error occurs, the error message is returned for use in validators.
188
+ *
189
+ * @param service the specific service to get details for
190
+ * @param connectionValidator a reference to the connection validator which has an active connection to the backend
191
+ * @param requiredOdataVersion
192
+ * @returns true if successful, setting the PromptState.odataService properties, or an error message indicating why the service details could not be retrieved.
193
+ */
194
+ async function getServiceDetails(service, connectionValidator, requiredOdataVersion) {
195
+ const serviceCatalog = connectionValidator.catalogs?.[service.serviceODataVersion];
196
+ if (!connectionValidator.serviceProvider) {
197
+ logger_helper_1.default.logger.error('ConnectionValidator connection is not initialized');
198
+ return false;
199
+ }
200
+ // We may already have an odata service endpoint connection
201
+ let odataService = connectionValidator.odataService;
202
+ if (!odataService) {
203
+ odataService = connectionValidator.serviceProvider.service(service.servicePath);
204
+ }
205
+ const serviceResult = await getServiceMetadata(service.servicePath, odataService, serviceCatalog);
206
+ if (typeof serviceResult === 'string') {
207
+ return serviceResult;
208
+ }
209
+ const { validationMsg, version } = (0, validators_1.validateODataVersion)(serviceResult.metadata, requiredOdataVersion);
210
+ if (validationMsg) {
211
+ return validationMsg;
212
+ }
213
+ // If destinationUrl is available, use it, as validatedUrl may be in the form <protocal>:<destinationName>.dest
214
+ const url = connectionValidator.destinationUrl ?? connectionValidator.validatedUrl;
215
+ let origin;
216
+ if (url) {
217
+ origin = new URL(url).origin;
218
+ }
219
+ utils_1.PromptState.odataService.annotations = serviceResult?.annotations;
220
+ utils_1.PromptState.odataService.metadata = serviceResult?.metadata;
221
+ utils_1.PromptState.odataService.odataVersion =
222
+ version ?? service.serviceODataVersion === axios_extension_1.ODataVersion.v2 ? odata_service_writer_1.OdataVersion.v2 : odata_service_writer_1.OdataVersion.v4;
223
+ utils_1.PromptState.odataService.servicePath = service.servicePath;
224
+ utils_1.PromptState.odataService.origin = origin;
225
+ utils_1.PromptState.odataService.sapClient = connectionValidator.validatedClient;
226
+ return true;
227
+ }
228
+ /**
229
+ * Create a value for the service selection prompt message, which may include thge active connected user name.
230
+ *
231
+ * @param username The connected user name
232
+ * @returns The service selection prompt message
233
+ */
234
+ function getSelectedServiceLabel(username) {
235
+ let message = (0, i18n_1.t)('prompts.systemService.message');
236
+ if (username) {
237
+ message = message.concat(` ${(0, i18n_1.t)('texts.forUserName', { username })}`);
238
+ }
239
+ return message;
240
+ }
241
+ /**
242
+ * Get the service selection prompt additional message. This prompt will make an additional call to the system backend
243
+ * to retrieve the service type and display a warning message if the service type is not UI.
244
+ *
245
+ * @param serviceChoices a list of service choices
246
+ * @param selectedService the selected service
247
+ * @param connectValidator the connection validator
248
+ * @param requiredOdataVersion the required OData version for the service
249
+ * @returns the service selection prompt additional message
250
+ */
251
+ async function getSelectedServiceMessage(serviceChoices, selectedService, connectValidator, requiredOdataVersion) {
252
+ if (serviceChoices?.length === 0) {
253
+ if (requiredOdataVersion) {
254
+ return {
255
+ message: (0, i18n_1.t)('prompts.warnings.noServicesAvailableForOdataVersion', {
256
+ odataVersion: requiredOdataVersion
257
+ }),
258
+ severity: yeoman_ui_types_1.Severity.warning
259
+ };
260
+ }
261
+ else {
262
+ return {
263
+ message: (0, i18n_1.t)('prompts.warnings.noServicesAvailable'),
264
+ severity: yeoman_ui_types_1.Severity.warning
265
+ };
266
+ }
267
+ }
268
+ if (selectedService) {
269
+ let serviceType = selectedService.serviceType;
270
+ if (selectedService.serviceODataVersion === axios_extension_1.ODataVersion.v2) {
271
+ serviceType = await getServiceType(selectedService.servicePath, selectedService.serviceType, connectValidator.catalogs[axios_extension_1.ODataVersion.v2]);
272
+ }
273
+ if (serviceType && serviceType !== axios_extension_1.ServiceType.UI) {
274
+ return {
275
+ message: (0, i18n_1.t)('prompts.warnings.nonUIServiceTypeWarningMessage', { serviceType: 'A2X' }),
276
+ severity: yeoman_ui_types_1.Severity.warning
277
+ };
278
+ }
279
+ }
280
+ }
281
+ //# sourceMappingURL=service-helper.js.map
@@ -0,0 +1,11 @@
1
+ import type { ODataVersion } from '@sap-ux/axios-extension';
2
+ /**
3
+ * Sap System service answer
4
+ */
5
+ export type ServiceAnswer = {
6
+ servicePath: string;
7
+ serviceODataVersion: ODataVersion;
8
+ toString: () => string;
9
+ serviceType?: string;
10
+ };
11
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,2 @@
1
+ export * from './questions';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./questions"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,44 @@
1
+ import type { Destination } from '@sap-ux/btp-utils';
2
+ import type { OdataVersion } from '@sap-ux/odata-service-writer';
3
+ import type { BackendSystem } from '@sap-ux/store';
4
+ import type { ListChoiceOptions } from 'inquirer';
5
+ import { type DestinationFilters } from '../../../../types';
6
+ import type { ConnectionValidator, ValidationResult } from '../../../connectionValidator';
7
+ import { type SystemSelectionAnswers } from './questions';
8
+ /**
9
+ * Connects to the specified backend system and validates the connection.
10
+ * Note this will return true in the case of basic auth validation failure to defer validation to the credentials prompt.
11
+ *
12
+ * @param backendSystem the backend system to connect to
13
+ * @param connectionValidator the connection validator to use for the connection
14
+ * @param requiredOdataVersion the required OData version for the service, this will be used to narrow the catalog service connections
15
+ * @returns the validation result of the backend system connection
16
+ */
17
+ export declare function connectWithBackendSystem(backendSystem: BackendSystem, connectionValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion): Promise<ValidationResult>;
18
+ /**
19
+ * Connects to the specified destination and validates the connection.
20
+ * Note that a destination may be a system or a service connection.
21
+ *
22
+ * @param destination the destination specifying the connection details
23
+ * @param connectionValidator the connection validator to use for the connection
24
+ * @param requiredOdataVersion the required OData version for the service, this will be used to narrow the catalog service connections
25
+ * @param addServicePath the service path to add to the destination URL
26
+ * @returns the validation result of the destination connection attempt
27
+ */
28
+ export declare function connectWithDestination(destination: Destination, connectionValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion, addServicePath?: string): Promise<ValidationResult>;
29
+ /**
30
+ * Creates and returns a display name for the system, appending the system type and user display name if available.
31
+ *
32
+ * @param system the backend system to create a display name for
33
+ * @returns the display name for the system
34
+ */
35
+ export declare function getBackendSystemDisplayName(system: BackendSystem): string;
36
+ /**
37
+ * Creates a list of choices for the system selection prompt using destinations or stored backend systems, depending on the environment.
38
+ *
39
+ * @param destinationFilters
40
+ * @param includeCloudFoundryAbapEnvChoice
41
+ * @returns a list of choices for the system selection prompt
42
+ */
43
+ export declare function createSystemChoices(destinationFilters?: Partial<DestinationFilters>, includeCloudFoundryAbapEnvChoice?: boolean): Promise<ListChoiceOptions<SystemSelectionAnswers>[]>;
44
+ //# sourceMappingURL=prompt-helpers.d.ts.map
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.connectWithBackendSystem = connectWithBackendSystem;
7
+ exports.connectWithDestination = connectWithDestination;
8
+ exports.getBackendSystemDisplayName = getBackendSystemDisplayName;
9
+ exports.createSystemChoices = createSystemChoices;
10
+ const btp_utils_1 = require("@sap-ux/btp-utils");
11
+ const store_1 = require("@sap-ux/store");
12
+ const error_handler_1 = require("../../../../error-handler/error-handler");
13
+ const i18n_1 = require("../../../../i18n");
14
+ const utils_1 = require("../../../../utils");
15
+ const logger_helper_1 = __importDefault(require("../../../logger-helper"));
16
+ const questions_1 = require("./questions");
17
+ /**
18
+ * Connects to the specified backend system and validates the connection.
19
+ * Note this will return true in the case of basic auth validation failure to defer validation to the credentials prompt.
20
+ *
21
+ * @param backendSystem the backend system to connect to
22
+ * @param connectionValidator the connection validator to use for the connection
23
+ * @param requiredOdataVersion the required OData version for the service, this will be used to narrow the catalog service connections
24
+ * @returns the validation result of the backend system connection
25
+ */
26
+ async function connectWithBackendSystem(backendSystem, connectionValidator, requiredOdataVersion) {
27
+ // Create a new connection with the selected system
28
+ let connectValResult = false;
29
+ if (backendSystem) {
30
+ // Assumption: non-BAS systems are BackendSystems
31
+ if (backendSystem.authenticationType === 'reentranceTicket') {
32
+ connectValResult = await connectionValidator.validateUrl(backendSystem.url, {
33
+ isSystem: true,
34
+ odataVersion: (0, utils_1.convertODataVersionType)(requiredOdataVersion),
35
+ systemAuthType: 'reentranceTicket'
36
+ });
37
+ }
38
+ else if (backendSystem.serviceKeys) {
39
+ connectValResult = await connectionValidator.validateServiceInfo(backendSystem.serviceKeys);
40
+ }
41
+ else if (backendSystem.authenticationType === 'basic' || !backendSystem.authenticationType) {
42
+ let errorType;
43
+ ({ valResult: connectValResult, errorType } = await connectionValidator.validateAuth(backendSystem.url, backendSystem.username, backendSystem.password, {
44
+ isSystem: true,
45
+ odataVersion: (0, utils_1.convertODataVersionType)(requiredOdataVersion),
46
+ sapClient: backendSystem.client
47
+ }));
48
+ // If authentication failed with existing credentials the user will be prompted to enter new credentials.
49
+ // We log the error in case there is another issue (unresolveable) with the stored backend configuration.
50
+ if (errorType === error_handler_1.ERROR_TYPE.AUTH && backendSystem.username && backendSystem.password) {
51
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.storedSystemConnectionError', { systemName: backendSystem.name, error: connectValResult }));
52
+ return true;
53
+ }
54
+ }
55
+ // If the connection is successful, we will return the connected system from the inquirer
56
+ if (connectValResult === true && connectionValidator.serviceProvider) {
57
+ utils_1.PromptState.odataService.connectedSystem = {
58
+ serviceProvider: connectionValidator.serviceProvider,
59
+ backendSystem
60
+ };
61
+ }
62
+ }
63
+ return connectValResult;
64
+ }
65
+ /**
66
+ * Connects to the specified destination and validates the connection.
67
+ * Note that a destination may be a system or a service connection.
68
+ *
69
+ * @param destination the destination specifying the connection details
70
+ * @param connectionValidator the connection validator to use for the connection
71
+ * @param requiredOdataVersion the required OData version for the service, this will be used to narrow the catalog service connections
72
+ * @param addServicePath the service path to add to the destination URL
73
+ * @returns the validation result of the destination connection attempt
74
+ */
75
+ async function connectWithDestination(destination, connectionValidator, requiredOdataVersion, addServicePath) {
76
+ const { valResult: connectValResult, errorType } = await connectionValidator.validateDestination(destination, (0, utils_1.convertODataVersionType)(requiredOdataVersion), addServicePath);
77
+ // If authentication failed with an auth error, and the system connection auth type is basic, we will defer validation to the credentials prompt.
78
+ if (errorType === error_handler_1.ERROR_TYPE.AUTH && connectionValidator.systemAuthType === 'basic') {
79
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.destination.authError', { systemName: destination.Name, error: connectValResult }));
80
+ return true;
81
+ }
82
+ // If the connection is successful, we will return the connected system from the inquirer
83
+ if (connectValResult === true && connectionValidator.serviceProvider) {
84
+ utils_1.PromptState.odataService.connectedSystem = {
85
+ serviceProvider: connectionValidator.serviceProvider,
86
+ destination
87
+ };
88
+ }
89
+ // Deal with all destination errors here
90
+ return connectValResult;
91
+ }
92
+ /**
93
+ * Creates and returns a display name for the system, appending the system type and user display name if available.
94
+ *
95
+ * @param system the backend system to create a display name for
96
+ * @returns the display name for the system
97
+ */
98
+ function getBackendSystemDisplayName(system) {
99
+ const userDisplayName = system.userDisplayName ? ` [${system.userDisplayName}]` : '';
100
+ let systemTypeName = '';
101
+ if (system.authenticationType === 'reentranceTicket') {
102
+ systemTypeName = ` (${(0, i18n_1.t)('texts.systemTypeS4HC')})`;
103
+ }
104
+ if (system.authenticationType === 'oauth2') {
105
+ systemTypeName = ` (${(0, i18n_1.t)('texts.systemTypeBTP')})`;
106
+ }
107
+ return `${system.name}${systemTypeName}${userDisplayName}`;
108
+ }
109
+ /**
110
+ * Matches the destination against the provided filters. Returns true if the destination matches any filters, false otherwise.
111
+ *
112
+ * @param destination
113
+ * @param filters
114
+ * @returns true if the destination matches any filters, false otherwise
115
+ */
116
+ function matchesFilters(destination, filters) {
117
+ if (!filters) {
118
+ return true;
119
+ }
120
+ if (filters.odata_abap && (0, btp_utils_1.isAbapODataDestination)(destination)) {
121
+ return true;
122
+ }
123
+ if (filters.odata_generic && (0, btp_utils_1.isGenericODataDestination)(destination)) {
124
+ return true;
125
+ }
126
+ if (filters.full_service_url && (0, btp_utils_1.isFullUrlDestination)(destination)) {
127
+ return true;
128
+ }
129
+ if (filters.partial_service_url && (0, btp_utils_1.isPartialUrlDestination)(destination)) {
130
+ return true;
131
+ }
132
+ logger_helper_1.default.logger.debug(`Destination: ${destination.Name} does not match any filters and will be excluded as a prompt choice. Destination configuration: ${JSON.stringify(destination)}`);
133
+ return false;
134
+ }
135
+ /**
136
+ * Creates a list of choices for the system selection prompt using destinations or stored backend systems, depending on the environment.
137
+ *
138
+ * @param destinationFilters
139
+ * @param includeCloudFoundryAbapEnvChoice
140
+ * @returns a list of choices for the system selection prompt
141
+ */
142
+ async function createSystemChoices(destinationFilters, includeCloudFoundryAbapEnvChoice = false) {
143
+ let systemChoices = [];
144
+ let newSystemChoice;
145
+ // If this is BAS, return destinations, otherwise return stored backend systems
146
+ if ((0, btp_utils_1.isAppStudio)()) {
147
+ const destinations = await (0, btp_utils_1.listDestinations)();
148
+ systemChoices = Object.values(destinations)
149
+ .filter((destination) => {
150
+ return matchesFilters(destination, destinationFilters);
151
+ })
152
+ .map((destination) => {
153
+ return {
154
+ name: (0, btp_utils_1.getDisplayName)(destination),
155
+ value: {
156
+ type: 'destination',
157
+ system: destination
158
+ }
159
+ };
160
+ });
161
+ if (includeCloudFoundryAbapEnvChoice) {
162
+ newSystemChoice = {
163
+ name: (0, i18n_1.t)('prompts.newSystemType.choiceCFAbapEnvServiceOnBtp'),
164
+ value: { type: 'cfAbapEnvService', system: 'cfAbapEnvService' }
165
+ };
166
+ }
167
+ }
168
+ else {
169
+ const backendSystems = await new store_1.SystemService(logger_helper_1.default.logger).getAll();
170
+ systemChoices = backendSystems.map((system) => {
171
+ return {
172
+ name: getBackendSystemDisplayName(system),
173
+ value: {
174
+ system,
175
+ type: 'backendSystem'
176
+ }
177
+ };
178
+ });
179
+ newSystemChoice = {
180
+ name: (0, i18n_1.t)('prompts.systemSelection.newSystemChoiceLabel'),
181
+ value: { system: questions_1.newSystemChoiceValue, type: 'newSystemChoice' }
182
+ };
183
+ }
184
+ systemChoices.sort(({ name: nameA }, { name: nameB }) => nameA.localeCompare(nameB, undefined, { numeric: true, caseFirst: 'lower' }));
185
+ if (newSystemChoice) {
186
+ systemChoices.unshift(newSystemChoice);
187
+ }
188
+ return systemChoices;
189
+ }
190
+ //# sourceMappingURL=prompt-helpers.js.map
@@ -0,0 +1,40 @@
1
+ import type { Destination } from '@sap-ux/btp-utils';
2
+ import type { BackendSystem } from '@sap-ux/store';
3
+ import type { Question } from 'inquirer';
4
+ import { promptNames, type OdataServicePromptOptions } from '../../../../types';
5
+ import { ConnectionValidator } from '../../../connectionValidator';
6
+ import type { ServiceAnswer } from '../service-selection';
7
+ export declare const newSystemChoiceValue = "!@\u00A3*&937newSystem*X~qy^";
8
+ type NewSystemChoice = typeof newSystemChoiceValue;
9
+ declare const usernamePromptName: "systemSelection:systemUsername";
10
+ declare const passwordPromptName: "systemSelection:systemPassword";
11
+ export type SystemSelectionAnswerType = {
12
+ type: 'destination' | 'backendSystem' | 'newSystemChoice' | 'cfAbapEnvService';
13
+ system: Destination | BackendSystem | NewSystemChoice | 'cfAbapEnvService';
14
+ };
15
+ interface SystemSelectionCredentialsAnswers {
16
+ [usernamePromptName]?: string;
17
+ [passwordPromptName]?: string;
18
+ }
19
+ export interface SystemSelectionAnswers extends SystemSelectionCredentialsAnswers {
20
+ [promptNames.systemSelection]?: SystemSelectionAnswerType;
21
+ }
22
+ /**
23
+ * Returns a list of questions for creating a new system configuration or selecting an existing stored system.
24
+ *
25
+ * @param promptOptions prompt options that may be used to customize the questions
26
+ * @returns a list of questions for creating a new system configuration or selecting an existing stored system
27
+ */
28
+ export declare function getSystemSelectionQuestions(promptOptions?: OdataServicePromptOptions): Promise<Question<SystemSelectionAnswers & ServiceAnswer>[]>;
29
+ /**
30
+ * Returns a list of existing systems, either destinations or backend systems from persistent store, depending on the environment.
31
+ * Note that destinations are only available in BAS environment and must include the destination attribute `WebIDEEnabled` to be listed.
32
+ * Additional destination attribute filters may be provided.
33
+ *
34
+ * @param connectionValidator A reference to the active connection validator, used to validate the service selection and retrieve service details.
35
+ * @param promptOptions
36
+ * @returns a list of existing systems
37
+ */
38
+ export declare function getSystemConnectionQuestions(connectionValidator: ConnectionValidator, promptOptions?: OdataServicePromptOptions): Promise<Question<SystemSelectionAnswers>[]>;
39
+ export {};
40
+ //# sourceMappingURL=questions.d.ts.map