@sap-ux/odata-service-inquirer 0.5.60 → 0.6.1
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.
- package/dist/i18n.js +15 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +10 -9
- package/dist/prompts/connectionValidator.d.ts +63 -12
- package/dist/prompts/connectionValidator.js +208 -50
- package/dist/prompts/datasources/cap-project/questions.js +2 -1
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.d.ts +3 -2
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.js +10 -10
- package/dist/prompts/datasources/sap-system/abap-on-prem/questions.d.ts +9 -11
- package/dist/prompts/datasources/sap-system/abap-on-prem/questions.js +21 -55
- package/dist/prompts/datasources/sap-system/credentials/questions.d.ts +21 -0
- package/dist/prompts/datasources/sap-system/credentials/questions.js +123 -0
- package/dist/prompts/datasources/sap-system/new-system/questions.d.ts +4 -26
- package/dist/prompts/datasources/sap-system/new-system/questions.js +18 -168
- package/dist/prompts/datasources/sap-system/new-system/types.d.ts +0 -10
- package/dist/prompts/datasources/sap-system/service-selection/index.d.ts +3 -0
- package/dist/prompts/datasources/sap-system/service-selection/index.js +19 -0
- package/dist/prompts/datasources/sap-system/service-selection/questions.d.ts +15 -0
- package/dist/prompts/datasources/sap-system/service-selection/questions.js +146 -0
- package/dist/prompts/datasources/sap-system/service-selection/service-helper.d.ts +71 -0
- package/dist/prompts/datasources/sap-system/service-selection/service-helper.js +282 -0
- package/dist/prompts/datasources/sap-system/service-selection/types.d.ts +11 -0
- package/dist/prompts/datasources/sap-system/service-selection/types.js +3 -0
- package/dist/prompts/datasources/sap-system/system-selection/index.d.ts +2 -0
- package/dist/prompts/datasources/sap-system/system-selection/index.js +18 -0
- package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.d.ts +44 -0
- package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.js +190 -0
- package/dist/prompts/datasources/sap-system/system-selection/questions.d.ts +40 -0
- package/dist/prompts/datasources/sap-system/system-selection/questions.js +182 -0
- package/dist/prompts/datasources/sap-system/validators.d.ts +8 -0
- package/dist/prompts/datasources/sap-system/validators.js +17 -0
- package/dist/prompts/datasources/service-url/questions.js +4 -3
- package/dist/prompts/datasources/service-url/validators.js +8 -9
- package/dist/prompts/prompt-helpers.d.ts +2 -3
- package/dist/prompts/prompt-helpers.js +4 -13
- package/dist/prompts/prompts.js +5 -34
- package/dist/prompts/validators.d.ts +1 -1
- package/dist/prompts/validators.js +1 -1
- package/dist/translations/odata-service-inquirer.i18n.json +25 -37
- package/dist/types.d.ts +57 -45
- package/dist/types.js +7 -41
- package/dist/utils/index.d.ts +5 -18
- package/dist/utils/index.js +10 -55
- package/package.json +10 -9
- package/dist/error-handler/error-handler.d.ts +0 -184
- package/dist/error-handler/error-handler.js +0 -465
- package/dist/prompts/datasources/sap-system/abap-on-btp/cf-helper.d.ts +0 -9
- package/dist/prompts/datasources/sap-system/abap-on-btp/cf-helper.js +0 -54
- package/dist/prompts/datasources/sap-system/new-system/service-helper.d.ts +0 -43
- package/dist/prompts/datasources/sap-system/new-system/service-helper.js +0 -175
|
@@ -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 inquirer_common_1 = require("@sap-ux/inquirer-common");
|
|
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 === inquirer_common_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 === inquirer_common_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
|
|
@@ -0,0 +1,182 @@
|
|
|
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.newSystemChoiceValue = void 0;
|
|
7
|
+
exports.getSystemSelectionQuestions = getSystemSelectionQuestions;
|
|
8
|
+
exports.getSystemConnectionQuestions = getSystemConnectionQuestions;
|
|
9
|
+
const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
|
|
10
|
+
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
11
|
+
const inquirer_common_1 = require("@sap-ux/inquirer-common");
|
|
12
|
+
const i18n_1 = require("../../../../i18n");
|
|
13
|
+
const types_1 = require("../../../../types");
|
|
14
|
+
const utils_1 = require("../../../../utils");
|
|
15
|
+
const connectionValidator_1 = require("../../../connectionValidator");
|
|
16
|
+
const logger_helper_1 = __importDefault(require("../../../logger-helper"));
|
|
17
|
+
const questions_1 = require("../credentials/questions");
|
|
18
|
+
const questions_2 = require("../new-system/questions");
|
|
19
|
+
const questions_3 = require("../service-selection/questions");
|
|
20
|
+
const validators_1 = require("../validators");
|
|
21
|
+
const prompt_helpers_1 = require("./prompt-helpers");
|
|
22
|
+
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
23
|
+
// New system choice value is a hard to guess string to avoid conflicts with existing system names or user named systems
|
|
24
|
+
// since it will be used as a new system value in the system selection prompt.
|
|
25
|
+
exports.newSystemChoiceValue = '!@£*&937newSystem*X~qy^';
|
|
26
|
+
const systemSelectionPromptNamespace = 'systemSelection';
|
|
27
|
+
const usernamePromptName = `${systemSelectionPromptNamespace}:${questions_1.BasicCredentialsPromptNames.systemUsername}`;
|
|
28
|
+
const passwordPromptName = `${systemSelectionPromptNamespace}:${questions_1.BasicCredentialsPromptNames.systemPassword}`;
|
|
29
|
+
const systemSelectionPromptNames = {
|
|
30
|
+
systemSelectionCli: 'systemSelectionCli',
|
|
31
|
+
destinationServicePath: 'destinationServicePath'
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Validates the system selection, connecting to the selected system and validating the connection.
|
|
35
|
+
*
|
|
36
|
+
* @param systemSelection
|
|
37
|
+
* @param connectionValidator
|
|
38
|
+
* @param requiredOdataVersion
|
|
39
|
+
* @returns the validation result of the selected system connection attempt
|
|
40
|
+
*/
|
|
41
|
+
async function validateSystemSelection(systemSelection, connectionValidator, requiredOdataVersion) {
|
|
42
|
+
utils_1.PromptState.reset();
|
|
43
|
+
if (systemSelection.type === 'newSystemChoice') {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
let connectValResult = false;
|
|
47
|
+
if (systemSelection.type === 'backendSystem') {
|
|
48
|
+
connectValResult = await (0, prompt_helpers_1.connectWithBackendSystem)(systemSelection.system, connectionValidator, requiredOdataVersion);
|
|
49
|
+
}
|
|
50
|
+
else if (systemSelection.type === 'destination') {
|
|
51
|
+
// Partial URL destinations will require additional service path prompt input, so we skip the connection validation here by returning true
|
|
52
|
+
// The service URL connection will need to be validated by the service path prompt
|
|
53
|
+
if ((0, btp_utils_1.isPartialUrlDestination)(systemSelection.system)) {
|
|
54
|
+
// Reset the connection state as we are deferring the connection validation to the service path prompt, any existing connection state should be cleared
|
|
55
|
+
// connectionValidator.resetConnectionState(true);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
connectValResult = await (0, prompt_helpers_1.connectWithDestination)(systemSelection.system, connectionValidator, requiredOdataVersion);
|
|
59
|
+
}
|
|
60
|
+
return connectValResult;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns a list of questions for creating a new system configuration or selecting an existing stored system.
|
|
64
|
+
*
|
|
65
|
+
* @param promptOptions prompt options that may be used to customize the questions
|
|
66
|
+
* @returns a list of questions for creating a new system configuration or selecting an existing stored system
|
|
67
|
+
*/
|
|
68
|
+
async function getSystemSelectionQuestions(promptOptions) {
|
|
69
|
+
utils_1.PromptState.reset();
|
|
70
|
+
const connectValidator = new connectionValidator_1.ConnectionValidator();
|
|
71
|
+
const questions = await getSystemConnectionQuestions(connectValidator, promptOptions);
|
|
72
|
+
// Existing system (BackendSystem or Destination) selected,
|
|
73
|
+
// In future, make the service prompt optional by wrapping in condition `[promptOptions?.serviceSelection?.hide]`
|
|
74
|
+
questions.push(...(0, inquirer_common_1.withCondition)((0, questions_3.getSystemServiceQuestion)(connectValidator, systemSelectionPromptNamespace, promptOptions), (answers) => answers.systemSelection?.type !== 'newSystemChoice'));
|
|
75
|
+
// Create new system connection for storage only supported on non-App Studio environments
|
|
76
|
+
if (!(0, btp_utils_1.isAppStudio)()) {
|
|
77
|
+
questions.push(...(0, inquirer_common_1.withCondition)((0, questions_2.getNewSystemQuestions)(promptOptions), (answers) => answers.systemSelection?.type === 'newSystemChoice'));
|
|
78
|
+
}
|
|
79
|
+
return questions;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns a list of existing systems, either destinations or backend systems from persistent store, depending on the environment.
|
|
83
|
+
* Note that destinations are only available in BAS environment and must include the destination attribute `WebIDEEnabled` to be listed.
|
|
84
|
+
* Additional destination attribute filters may be provided.
|
|
85
|
+
*
|
|
86
|
+
* @param connectionValidator A reference to the active connection validator, used to validate the service selection and retrieve service details.
|
|
87
|
+
* @param promptOptions
|
|
88
|
+
* @returns a list of existing systems
|
|
89
|
+
*/
|
|
90
|
+
async function getSystemConnectionQuestions(connectionValidator, promptOptions) {
|
|
91
|
+
const requiredOdataVersion = promptOptions?.serviceSelection?.requiredOdataVersion;
|
|
92
|
+
const destinationFilters = promptOptions?.systemSelection?.destinationFilters;
|
|
93
|
+
const systemChoices = await (0, prompt_helpers_1.createSystemChoices)(destinationFilters, promptOptions?.systemSelection?.includeCloudFoundryAbapEnvChoice);
|
|
94
|
+
const questions = [
|
|
95
|
+
{
|
|
96
|
+
type: promptOptions?.systemSelection?.useAutoComplete ? 'autocomplete' : 'list',
|
|
97
|
+
name: types_1.promptNames.systemSelection,
|
|
98
|
+
message: (0, i18n_1.t)('prompts.systemSelection.message'),
|
|
99
|
+
source: (prevAnswers, input) => (0, inquirer_common_1.searchChoices)(input, systemChoices),
|
|
100
|
+
choices: systemChoices,
|
|
101
|
+
validate: async (selectedSystem) => {
|
|
102
|
+
if (!selectedSystem) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
let selectedSystemAnswer = selectedSystem;
|
|
106
|
+
// Autocomplete passes the entire choice object as the answer, so we need to extract the value
|
|
107
|
+
if (promptOptions?.systemSelection?.useAutoComplete && selectedSystem.value) {
|
|
108
|
+
selectedSystemAnswer = selectedSystem.value;
|
|
109
|
+
}
|
|
110
|
+
return (validateSystemSelection(selectedSystemAnswer, connectionValidator, requiredOdataVersion) ?? false);
|
|
111
|
+
},
|
|
112
|
+
additionalMessages: async (selectedSystem) => {
|
|
113
|
+
// Backend systems credentials may need to be updated
|
|
114
|
+
if (selectedSystem.type === 'backendSystem' &&
|
|
115
|
+
connectionValidator.systemAuthType === 'basic' &&
|
|
116
|
+
(await connectionValidator.isAuthRequired())) {
|
|
117
|
+
return {
|
|
118
|
+
message: (0, i18n_1.t)('prompts.systemSelection.authenticationFailedUpdateCredentials'),
|
|
119
|
+
severity: yeoman_ui_types_1.Severity.information
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
];
|
|
125
|
+
if ((0, btp_utils_1.isAppStudio)()) {
|
|
126
|
+
// Additional service path prompt for partial URL destinations
|
|
127
|
+
const servicePathPrompt = {
|
|
128
|
+
when: (answers) => {
|
|
129
|
+
const selectedSystem = answers?.[types_1.promptNames.systemSelection];
|
|
130
|
+
if (selectedSystem?.type === 'destination') {
|
|
131
|
+
return (0, btp_utils_1.isPartialUrlDestination)(selectedSystem.system);
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
},
|
|
135
|
+
type: 'input',
|
|
136
|
+
name: systemSelectionPromptNames.destinationServicePath,
|
|
137
|
+
message: (0, i18n_1.t)('prompts.destinationServicePath.message'),
|
|
138
|
+
guiOptions: {
|
|
139
|
+
hint: (0, i18n_1.t)('prompts.destinationServicePath.hint'),
|
|
140
|
+
mandatory: true,
|
|
141
|
+
breadcrumb: true
|
|
142
|
+
},
|
|
143
|
+
validate: async (servicePath, answers) => {
|
|
144
|
+
if (!servicePath) {
|
|
145
|
+
return (0, i18n_1.t)('prompts.destinationServicePath.invalidServicePathWarning');
|
|
146
|
+
}
|
|
147
|
+
// Validate format of the service path, note this relies on the assumption that the destination is correctly configured with a valid URL
|
|
148
|
+
const selectedDestination = answers?.[types_1.promptNames.systemSelection]?.system;
|
|
149
|
+
const valUrlResult = (0, validators_1.validateServiceUrl)(selectedDestination.Host, servicePath);
|
|
150
|
+
if (valUrlResult !== true) {
|
|
151
|
+
return valUrlResult;
|
|
152
|
+
}
|
|
153
|
+
const connectValResult = await (0, prompt_helpers_1.connectWithDestination)(selectedDestination, connectionValidator, requiredOdataVersion, servicePath);
|
|
154
|
+
return connectValResult;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
questions.push(servicePathPrompt);
|
|
158
|
+
}
|
|
159
|
+
// Only for CLI use as `list` prompt validation does not run on CLI unless autocomplete plugin is used
|
|
160
|
+
if ((0, utils_1.getPromptHostEnvironment)() === fiori_generator_shared_1.hostEnvironment.cli && !promptOptions?.systemSelection?.useAutoComplete) {
|
|
161
|
+
questions.push({
|
|
162
|
+
when: async (answers) => {
|
|
163
|
+
const selectedSystem = answers?.[types_1.promptNames.systemSelection];
|
|
164
|
+
if (!selectedSystem) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
const connectValResult = await validateSystemSelection(selectedSystem, connectionValidator, requiredOdataVersion);
|
|
168
|
+
// An issue occurred with the selected system, there is no need to continue on the CLI, log and exit
|
|
169
|
+
// Note that for connection authentication errors, the result will be true, the user will be prompted to update their credentials in the next prompt
|
|
170
|
+
if (connectValResult !== true) {
|
|
171
|
+
logger_helper_1.default.logger.error(connectValResult.toString);
|
|
172
|
+
throw new Error(connectValResult.toString());
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
},
|
|
176
|
+
name: `${systemSelectionPromptNames.systemSelectionCli}`
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
questions.push(...(0, questions_1.getCredentialsPrompts)(connectionValidator, systemSelectionPromptNamespace));
|
|
180
|
+
return questions;
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=questions.js.map
|
|
@@ -13,4 +13,12 @@ export declare function validateSystemName(systemName: string): Promise<boolean
|
|
|
13
13
|
* @returns the service key info if the file is valid, otherwise an error message
|
|
14
14
|
*/
|
|
15
15
|
export declare function validateServiceKey(path: string): string | ServiceInfo | boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Validates the specified origin and service path can be used to form a valid URL.
|
|
18
|
+
*
|
|
19
|
+
* @param origin the origin of the service
|
|
20
|
+
* @param servicePath the path to the service
|
|
21
|
+
* @returns true if a URL can be created from the specified parameters, otherwise an error message
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateServiceUrl(origin: string, servicePath: string): string | boolean;
|
|
16
24
|
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.validateSystemName = validateSystemName;
|
|
7
7
|
exports.validateServiceKey = validateServiceKey;
|
|
8
|
+
exports.validateServiceUrl = validateServiceUrl;
|
|
8
9
|
const i18n_1 = require("../../../i18n");
|
|
9
10
|
const store_1 = require("@sap-ux/store");
|
|
10
11
|
const logger_helper_1 = __importDefault(require("../../logger-helper"));
|
|
@@ -59,4 +60,20 @@ function validateServiceKey(path) {
|
|
|
59
60
|
return error.name === 'SyntaxError' ? (0, i18n_1.t)('prompts.serviceKey.unparseableServiceKey') : error.message;
|
|
60
61
|
}
|
|
61
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Validates the specified origin and service path can be used to form a valid URL.
|
|
65
|
+
*
|
|
66
|
+
* @param origin the origin of the service
|
|
67
|
+
* @param servicePath the path to the service
|
|
68
|
+
* @returns true if a URL can be created from the specified parameters, otherwise an error message
|
|
69
|
+
*/
|
|
70
|
+
function validateServiceUrl(origin, servicePath) {
|
|
71
|
+
try {
|
|
72
|
+
new URL(servicePath, origin);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return (0, i18n_1.t)('errors.invalidUrl', { input: `${origin}${servicePath}` });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
62
79
|
//# sourceMappingURL=validators.js.map
|
|
@@ -12,6 +12,7 @@ const connectionValidator_1 = require("../../connectionValidator");
|
|
|
12
12
|
const logger_helper_1 = __importDefault(require("../../logger-helper"));
|
|
13
13
|
const types_2 = require("./types");
|
|
14
14
|
const validators_1 = require("./validators");
|
|
15
|
+
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
15
16
|
/**
|
|
16
17
|
* Prompt for the service URL.
|
|
17
18
|
*
|
|
@@ -168,15 +169,15 @@ function getPasswordPrompt(connectValidator, requiredVersion) {
|
|
|
168
169
|
applyDefaultWhenDirty: true,
|
|
169
170
|
mandatory: true
|
|
170
171
|
},
|
|
172
|
+
guiType: 'login',
|
|
171
173
|
name: types_1.promptNames.serviceUrlPassword,
|
|
172
174
|
message: (0, i18n_1.t)('prompts.servicePassword.message'),
|
|
173
|
-
guiType: 'login',
|
|
174
175
|
mask: '*',
|
|
175
176
|
validate: async (password, { username, serviceUrl, ignoreCertError, sapClient }) => {
|
|
176
177
|
if (!serviceUrl || !username || !password) {
|
|
177
178
|
return false;
|
|
178
179
|
}
|
|
179
|
-
const validAuth = await connectValidator.validateAuth(serviceUrl, username, password, {
|
|
180
|
+
const { valResult: validAuth } = await connectValidator.validateAuth(serviceUrl, username, password, {
|
|
180
181
|
ignoreCertError,
|
|
181
182
|
sapClient
|
|
182
183
|
});
|
|
@@ -207,7 +208,7 @@ function getServiceUrlQuestions({ serviceUrl: serviceUrlOpts, serviceUrlPassword
|
|
|
207
208
|
getServiceUrlPrompt(connectValidator, requiredVersion),
|
|
208
209
|
getIgnoreCertErrorsPrompt(connectValidator, requiredVersion)
|
|
209
210
|
];
|
|
210
|
-
if ((0, utils_1.
|
|
211
|
+
if ((0, utils_1.getPromptHostEnvironment)() === fiori_generator_shared_1.hostEnvironment.cli) {
|
|
211
212
|
questions.push(getCliIgnoreCertValidatePrompt(connectValidator, requiredVersion));
|
|
212
213
|
}
|
|
213
214
|
questions.push(getUsernamePrompt(connectValidator), getPasswordPrompt(connectValidator, requiredVersion));
|
|
@@ -5,13 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.validateService = validateService;
|
|
7
7
|
const axios_extension_1 = require("@sap-ux/axios-extension");
|
|
8
|
-
const
|
|
8
|
+
const inquirer_common_1 = require("@sap-ux/inquirer-common");
|
|
9
9
|
const i18n_1 = require("../../../i18n");
|
|
10
10
|
const types_1 = require("../../../types");
|
|
11
11
|
const utils_1 = require("../../../utils");
|
|
12
12
|
const connectionValidator_1 = require("../../connectionValidator");
|
|
13
13
|
const logger_helper_1 = __importDefault(require("../../logger-helper"));
|
|
14
14
|
const prompt_helpers_1 = require("../../prompt-helpers");
|
|
15
|
+
const validators_1 = require("../../validators");
|
|
15
16
|
/**
|
|
16
17
|
* Validates that a service specified by the service url is accessible, has the required version and returns valid metadata.
|
|
17
18
|
* Retrieves annotations (from Abap backends) if available and stores them in the PromptState.
|
|
@@ -30,13 +31,11 @@ async function validateService(url, { odataService, axiosConfig }, requiredVersi
|
|
|
30
31
|
connectionValidator_1.ConnectionValidator.setGlobalRejectUnauthorized(!ignoreCertError);
|
|
31
32
|
}
|
|
32
33
|
const metadata = await odataService.metadata();
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
return
|
|
36
|
-
serviceVersion: serviceOdataVersion,
|
|
37
|
-
requiredVersion
|
|
38
|
-
})}`;
|
|
34
|
+
const odataVersionValResult = (0, validators_1.validateODataVersion)(metadata, requiredVersion);
|
|
35
|
+
if (odataVersionValResult.validationMsg) {
|
|
36
|
+
return odataVersionValResult.validationMsg;
|
|
39
37
|
}
|
|
38
|
+
const serviceOdataVersion = odataVersionValResult.version;
|
|
40
39
|
// Remove all occurrences of the origin from the metadata to make backend uris relative
|
|
41
40
|
utils_1.PromptState.odataService.metadata = (0, utils_1.originToRelative)(metadata);
|
|
42
41
|
utils_1.PromptState.odataService.odataVersion = serviceOdataVersion;
|
|
@@ -69,9 +68,9 @@ async function validateService(url, { odataService, axiosConfig }, requiredVersi
|
|
|
69
68
|
catch (error) {
|
|
70
69
|
delete utils_1.PromptState.odataService.metadata;
|
|
71
70
|
// Provide a more specific error message if the metadata service URL is not found
|
|
72
|
-
if (
|
|
71
|
+
if (inquirer_common_1.ErrorHandler.getErrorType(error) === inquirer_common_1.ERROR_TYPE.NOT_FOUND) {
|
|
73
72
|
// No metadata implies not a valid odata service
|
|
74
|
-
return
|
|
73
|
+
return inquirer_common_1.ErrorHandler.getErrorMsgFromType(inquirer_common_1.ERROR_TYPE.ODATA_URL_NOT_FOUND) ?? false;
|
|
75
74
|
}
|
|
76
75
|
return prompt_helpers_1.errorHandler.logErrorMsgs(error);
|
|
77
76
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ListChoiceOptions } from 'inquirer';
|
|
2
|
-
import { ErrorHandler } from '
|
|
2
|
+
import { ErrorHandler } from '@sap-ux/inquirer-common';
|
|
3
3
|
import { type DatasourceTypePromptOptions } from '../types';
|
|
4
4
|
export declare const errorHandler: ErrorHandler;
|
|
5
5
|
/**
|
|
@@ -7,8 +7,7 @@ export declare const errorHandler: ErrorHandler;
|
|
|
7
7
|
*
|
|
8
8
|
* @param options - optionally include some of the supported datasource type choices
|
|
9
9
|
* @param options.includeNone - Include the `NONE` option in the datasource type prompt
|
|
10
|
-
* @param options.includeProjectSpecificDest - Include the `projectSpecificDestination` option in the datasource type prompt
|
|
11
10
|
* @returns The datasource type choices
|
|
12
11
|
*/
|
|
13
|
-
export declare function getDatasourceTypeChoices({ includeNone
|
|
12
|
+
export declare function getDatasourceTypeChoices({ includeNone }?: DatasourceTypePromptOptions): ListChoiceOptions[];
|
|
14
13
|
//# sourceMappingURL=prompt-helpers.d.ts.map
|
|
@@ -2,21 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.errorHandler = void 0;
|
|
4
4
|
exports.getDatasourceTypeChoices = getDatasourceTypeChoices;
|
|
5
|
-
const
|
|
6
|
-
const error_handler_1 = require("../error-handler/error-handler");
|
|
5
|
+
const inquirer_common_1 = require("@sap-ux/inquirer-common");
|
|
7
6
|
const i18n_1 = require("../i18n");
|
|
8
7
|
const types_1 = require("../types");
|
|
9
8
|
// Error handling is a cross-cutting concern, a single instance is required
|
|
10
|
-
exports.errorHandler = new
|
|
9
|
+
exports.errorHandler = new inquirer_common_1.ErrorHandler();
|
|
11
10
|
/**
|
|
12
11
|
* Get the datasource type choices.
|
|
13
12
|
*
|
|
14
13
|
* @param options - optionally include some of the supported datasource type choices
|
|
15
14
|
* @param options.includeNone - Include the `NONE` option in the datasource type prompt
|
|
16
|
-
* @param options.includeProjectSpecificDest - Include the `projectSpecificDestination` option in the datasource type prompt
|
|
17
15
|
* @returns The datasource type choices
|
|
18
16
|
*/
|
|
19
|
-
function getDatasourceTypeChoices({ includeNone = false
|
|
17
|
+
function getDatasourceTypeChoices({ includeNone = false } = {}) {
|
|
20
18
|
const choices = [
|
|
21
19
|
{
|
|
22
20
|
name: (0, i18n_1.t)('prompts.datasourceType.sapSystemChoiceText'),
|
|
@@ -25,15 +23,8 @@ function getDatasourceTypeChoices({ includeNone = false, includeProjectSpecificD
|
|
|
25
23
|
{
|
|
26
24
|
name: (0, i18n_1.t)('prompts.datasourceType.odataServiceUrlChoiceText'),
|
|
27
25
|
value: types_1.DatasourceType.odataServiceUrl
|
|
28
|
-
}
|
|
29
|
-
{ name: (0, i18n_1.t)('prompts.datasourceType.businessHubChoiceText'), value: types_1.DatasourceType.businessHub }
|
|
26
|
+
}
|
|
30
27
|
];
|
|
31
|
-
if ((0, btp_utils_1.isAppStudio)() && includeProjectSpecificDest) {
|
|
32
|
-
choices.push({
|
|
33
|
-
name: (0, i18n_1.t)('prompts.datasourceType.projectSpecificDestChoiceText'),
|
|
34
|
-
value: types_1.DatasourceType.projectSpecificDestination
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
28
|
choices.push({ name: (0, i18n_1.t)('prompts.datasourceType.capProjectChoiceText'), value: types_1.DatasourceType.capProject });
|
|
38
29
|
choices.push({ name: (0, i18n_1.t)('prompts.datasourceType.metadataFileChoiceText'), value: types_1.DatasourceType.metadataFile });
|
|
39
30
|
if (includeNone) {
|