@sap-ux/odata-service-inquirer 2.8.12 → 2.8.13
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/prompts/connectionValidator.d.ts +2 -4
- package/dist/prompts/connectionValidator.js +23 -13
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.d.ts +2 -5
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.js +3 -64
- package/dist/prompts/datasources/sap-system/shared-prompts/shared-prompts.d.ts +1 -1
- package/dist/prompts/datasources/sap-system/shared-prompts/shared-prompts.js +15 -7
- package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.d.ts +0 -7
- package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.js +5 -30
- package/dist/translations/odata-service-inquirer.i18n.json +3 -3
- package/dist/types.d.ts +1 -1
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.js +14 -0
- package/dist/utils/prompt-state.d.ts +5 -0
- package/dist/utils/prompt-state.js +4 -0
- package/package.json +11 -11
|
@@ -206,7 +206,6 @@ export declare class ConnectionValidator {
|
|
|
206
206
|
* @param connectConfig.serviceInfo the service info
|
|
207
207
|
* @param connectConfig.odataVersion the odata version to restrict the catalog requests if only a specific version is required
|
|
208
208
|
* @param connectConfig.destination the destination to connect with
|
|
209
|
-
* @param connectConfig.refreshToken
|
|
210
209
|
* @throws an error if the connection attempt fails, callers should handle the error
|
|
211
210
|
*/
|
|
212
211
|
private createSystemConnection;
|
|
@@ -229,7 +228,7 @@ export declare class ConnectionValidator {
|
|
|
229
228
|
*/
|
|
230
229
|
private refreshTokenChangedCb;
|
|
231
230
|
/**
|
|
232
|
-
* Get the service provider for the Abap
|
|
231
|
+
* Get the service provider for the Abap Cloud environment.
|
|
233
232
|
*
|
|
234
233
|
* @param url the system url
|
|
235
234
|
* @param serviceInfo the service info
|
|
@@ -244,10 +243,9 @@ export declare class ConnectionValidator {
|
|
|
244
243
|
*
|
|
245
244
|
* @param serviceInfo the service info containing the UAA details
|
|
246
245
|
* @param odataVersion the odata version to restrict the catalog requests if only a specific version is required
|
|
247
|
-
* @param refreshToken the refresh token for the Abap on Cloud environment, will be used to avoid re-authentication while the token is valid
|
|
248
246
|
* @returns true if the system is reachable and authenticated, if required, false if not, or an error message string
|
|
249
247
|
*/
|
|
250
|
-
validateServiceInfo(serviceInfo: ServiceInfo, odataVersion?: ODataVersion
|
|
248
|
+
validateServiceInfo(serviceInfo: ServiceInfo, odataVersion?: ODataVersion): Promise<ValidationResult>;
|
|
251
249
|
/**
|
|
252
250
|
* Validate the specified destination connectivity, determining if authentication is required or if the destination is misconfigured.
|
|
253
251
|
*
|
|
@@ -261,6 +261,9 @@ class ConnectionValidator {
|
|
|
261
261
|
const axiosConfig = this.createAxiosConfig(url, ignoreCertError, username, password);
|
|
262
262
|
if (isSystem) {
|
|
263
263
|
await this.createSystemConnection({ axiosConfig, url, odataVersion });
|
|
264
|
+
const systemInfo = await this.serviceProvider.getSystemInfo();
|
|
265
|
+
this._connectedUserName = systemInfo?.userName;
|
|
266
|
+
this._connectedSystemName = systemInfo?.systemID;
|
|
264
267
|
}
|
|
265
268
|
else {
|
|
266
269
|
// Full service URL
|
|
@@ -298,7 +301,8 @@ class ConnectionValidator {
|
|
|
298
301
|
ignoreCertErrors: ignoreCertError,
|
|
299
302
|
cookies: '',
|
|
300
303
|
baseURL: url.origin,
|
|
301
|
-
url: url.pathname
|
|
304
|
+
url: url.pathname,
|
|
305
|
+
logger: logger_helper_1.default.logger
|
|
302
306
|
};
|
|
303
307
|
if (username && password) {
|
|
304
308
|
axiosConfig = Object.assign(axiosConfig, {
|
|
@@ -386,14 +390,13 @@ class ConnectionValidator {
|
|
|
386
390
|
* @param connectConfig.serviceInfo the service info
|
|
387
391
|
* @param connectConfig.odataVersion the odata version to restrict the catalog requests if only a specific version is required
|
|
388
392
|
* @param connectConfig.destination the destination to connect with
|
|
389
|
-
* @param connectConfig.refreshToken
|
|
390
393
|
* @throws an error if the connection attempt fails, callers should handle the error
|
|
391
394
|
*/
|
|
392
|
-
async createSystemConnection({ axiosConfig, url, serviceInfo, destination, odataVersion
|
|
395
|
+
async createSystemConnection({ axiosConfig, url, serviceInfo, destination, odataVersion }) {
|
|
393
396
|
this.resetConnectionState();
|
|
394
397
|
this.resetValidity();
|
|
395
398
|
if (this.systemAuthType === 'reentranceTicket' || this.systemAuthType === 'serviceKey') {
|
|
396
|
-
this._serviceProvider = this.getAbapOnCloudServiceProvider(url, serviceInfo
|
|
399
|
+
this._serviceProvider = this.getAbapOnCloudServiceProvider(url, serviceInfo);
|
|
397
400
|
}
|
|
398
401
|
else if (destination) {
|
|
399
402
|
// Assumption: the destination configured URL is a valid URL, will be needed later for basic auth error handling
|
|
@@ -493,7 +496,7 @@ class ConnectionValidator {
|
|
|
493
496
|
this._refreshToken = refreshToken;
|
|
494
497
|
}
|
|
495
498
|
/**
|
|
496
|
-
* Get the service provider for the Abap
|
|
499
|
+
* Get the service provider for the Abap Cloud environment.
|
|
497
500
|
*
|
|
498
501
|
* @param url the system url
|
|
499
502
|
* @param serviceInfo the service info
|
|
@@ -504,7 +507,8 @@ class ConnectionValidator {
|
|
|
504
507
|
if (this.systemAuthType === 'reentranceTicket' && url) {
|
|
505
508
|
return (0, axios_extension_1.createForAbapOnCloud)({
|
|
506
509
|
environment: axios_extension_1.AbapCloudEnvironment.EmbeddedSteampunk,
|
|
507
|
-
url: new URL(url.pathname, url.origin).toString()
|
|
510
|
+
url: new URL(url.pathname, url.origin).toString(),
|
|
511
|
+
logger: logger_helper_1.default.logger
|
|
508
512
|
});
|
|
509
513
|
}
|
|
510
514
|
if (this.systemAuthType === 'serviceKey' && serviceInfo) {
|
|
@@ -512,7 +516,8 @@ class ConnectionValidator {
|
|
|
512
516
|
environment: axios_extension_1.AbapCloudEnvironment.Standalone,
|
|
513
517
|
service: serviceInfo,
|
|
514
518
|
refreshToken,
|
|
515
|
-
refreshTokenChangedCb: this.refreshTokenChangedCb.bind(this)
|
|
519
|
+
refreshTokenChangedCb: this.refreshTokenChangedCb.bind(this),
|
|
520
|
+
logger: logger_helper_1.default.logger
|
|
516
521
|
});
|
|
517
522
|
}
|
|
518
523
|
throw new Error('Invalid system auth type');
|
|
@@ -524,10 +529,9 @@ class ConnectionValidator {
|
|
|
524
529
|
*
|
|
525
530
|
* @param serviceInfo the service info containing the UAA details
|
|
526
531
|
* @param odataVersion the odata version to restrict the catalog requests if only a specific version is required
|
|
527
|
-
* @param refreshToken the refresh token for the Abap on Cloud environment, will be used to avoid re-authentication while the token is valid
|
|
528
532
|
* @returns true if the system is reachable and authenticated, if required, false if not, or an error message string
|
|
529
533
|
*/
|
|
530
|
-
async validateServiceInfo(serviceInfo, odataVersion
|
|
534
|
+
async validateServiceInfo(serviceInfo, odataVersion) {
|
|
531
535
|
if (!serviceInfo) {
|
|
532
536
|
return false;
|
|
533
537
|
}
|
|
@@ -538,7 +542,7 @@ class ConnectionValidator {
|
|
|
538
542
|
}
|
|
539
543
|
try {
|
|
540
544
|
this.systemAuthType = 'serviceKey';
|
|
541
|
-
await this.createSystemConnection({ serviceInfo, odataVersion
|
|
545
|
+
await this.createSystemConnection({ serviceInfo, odataVersion });
|
|
542
546
|
// Cache the user info
|
|
543
547
|
this._connectedUserName = await this.serviceProvider.user();
|
|
544
548
|
this._serviceInfo = serviceInfo;
|
|
@@ -657,6 +661,9 @@ class ConnectionValidator {
|
|
|
657
661
|
this.validity.urlFormat = false;
|
|
658
662
|
return false;
|
|
659
663
|
}
|
|
664
|
+
if (systemAuthType) {
|
|
665
|
+
this.systemAuthType = systemAuthType;
|
|
666
|
+
}
|
|
660
667
|
let url;
|
|
661
668
|
try {
|
|
662
669
|
// Check if the url is valid
|
|
@@ -664,13 +671,16 @@ class ConnectionValidator {
|
|
|
664
671
|
if (url.origin === 'null') {
|
|
665
672
|
return (0, i18n_1.t)('errors.invalidUrl', { input: serviceUrl });
|
|
666
673
|
}
|
|
674
|
+
// Dont allow non origin URLs in for re-entrance tickets as the error handling would become complex to analyize.
|
|
675
|
+
// The connection may succeed but later we will get auth errors since axios-extension does not validate this.
|
|
676
|
+
// The new system name would also include the additional paths which would not make sense either.
|
|
677
|
+
if (this.systemAuthType === 'reentranceTicket' && !(url.pathname.length === 0 || url.pathname === '/')) {
|
|
678
|
+
return (0, i18n_1.t)('prompts.validationMessages.reentranceTicketSystemHostOnly');
|
|
679
|
+
}
|
|
667
680
|
}
|
|
668
681
|
catch (error) {
|
|
669
682
|
return (0, i18n_1.t)('errors.invalidUrl', { input: serviceUrl });
|
|
670
683
|
}
|
|
671
|
-
if (systemAuthType) {
|
|
672
|
-
this.systemAuthType = systemAuthType;
|
|
673
|
-
}
|
|
674
684
|
try {
|
|
675
685
|
if (!forceReValidation && this.isUrlValidated(serviceUrl)) {
|
|
676
686
|
return this.validity.reachable ?? false;
|
|
@@ -7,14 +7,12 @@ import { type ServiceAnswer } from '../service-selection';
|
|
|
7
7
|
declare const systemUrlPromptName: "abapOnBtp:newSystemUrl";
|
|
8
8
|
declare const abapOnBtpPromptNames: {
|
|
9
9
|
readonly abapOnBtpAuthType: "abapOnBtpAuthType";
|
|
10
|
-
readonly serviceKey: "serviceKey";
|
|
11
10
|
readonly cloudFoundryAbapSystem: "cloudFoundryAbapSystem";
|
|
12
11
|
};
|
|
13
|
-
export type AbapOnBTPType = 'cloudFoundry' | '
|
|
12
|
+
export type AbapOnBTPType = 'cloudFoundry' | 'reentranceTicket';
|
|
14
13
|
interface AbapOnBtpAnswers extends Partial<OdataServiceAnswers> {
|
|
15
14
|
[abapOnBtpPromptNames.abapOnBtpAuthType]?: AbapOnBTPType;
|
|
16
15
|
[systemUrlPromptName]?: string;
|
|
17
|
-
[abapOnBtpPromptNames.serviceKey]?: string;
|
|
18
16
|
[abapOnBtpPromptNames.cloudFoundryAbapSystem]?: ServiceInstanceInfo;
|
|
19
17
|
}
|
|
20
18
|
/**
|
|
@@ -22,10 +20,9 @@ interface AbapOnBtpAnswers extends Partial<OdataServiceAnswers> {
|
|
|
22
20
|
*
|
|
23
21
|
* @param promptOptions The prompt options which control the service selection and system name]
|
|
24
22
|
* @param cachedConnectedSystem if available passing an already connected system connection will prevent re-authentication for re-entrance ticket and service keys connection types
|
|
25
|
-
* @param serviceKeyToggle Feature toggle to enable/disable the BTP service key option - enabled by default
|
|
26
23
|
* @returns The list of questions for the ABAP on BTP system
|
|
27
24
|
*/
|
|
28
|
-
export declare function getAbapOnBTPSystemQuestions(promptOptions?: OdataServicePromptOptions, cachedConnectedSystem?: ConnectedSystem
|
|
25
|
+
export declare function getAbapOnBTPSystemQuestions(promptOptions?: OdataServicePromptOptions, cachedConnectedSystem?: ConnectedSystem): Question<AbapOnBtpAnswers & ServiceAnswer>[];
|
|
29
26
|
/**
|
|
30
27
|
* Get the Cloud Foundry Abap system discovery prompt. This prompt will list all available ABAP environments in the connected Cloud Foundry space.
|
|
31
28
|
* If the Cloud Foundry connection fails, a warning message will be displayed.
|
|
@@ -18,26 +18,21 @@ const types_1 = require("../new-system/types");
|
|
|
18
18
|
const service_selection_1 = require("../service-selection");
|
|
19
19
|
const shared_prompts_1 = require("../shared-prompts/shared-prompts");
|
|
20
20
|
const prompt_helpers_2 = require("../system-selection/prompt-helpers");
|
|
21
|
-
const validators_1 = require("../validators");
|
|
22
|
-
const feature_toggle_1 = require("@sap-ux/feature-toggle");
|
|
23
21
|
const abapOnBtpPromptNamespace = 'abapOnBtp';
|
|
24
22
|
const systemUrlPromptName = `${abapOnBtpPromptNamespace}:${types_1.newSystemPromptNames.newSystemUrl}`;
|
|
25
23
|
const cliCfAbapServicePromptName = 'cliCfAbapService';
|
|
26
24
|
const abapOnBtpPromptNames = {
|
|
27
25
|
'abapOnBtpAuthType': 'abapOnBtpAuthType',
|
|
28
|
-
'serviceKey': 'serviceKey',
|
|
29
26
|
'cloudFoundryAbapSystem': 'cloudFoundryAbapSystem'
|
|
30
27
|
};
|
|
31
|
-
const SERVICE_KEY_FEATURE_TOGGLE = 'sap.ux.appGenerator.testBetaFeatures.disableBtpServiceKeyAuth';
|
|
32
28
|
/**
|
|
33
29
|
* Get the questions for the ABAP on BTP system within the VSCode platform. The questions will prompt the user for the system type (Cloud Foundry, Service Key, Re-entrance Ticket).
|
|
34
30
|
*
|
|
35
31
|
* @param promptOptions The prompt options which control the service selection and system name]
|
|
36
32
|
* @param cachedConnectedSystem if available passing an already connected system connection will prevent re-authentication for re-entrance ticket and service keys connection types
|
|
37
|
-
* @param serviceKeyToggle Feature toggle to enable/disable the BTP service key option - enabled by default
|
|
38
33
|
* @returns The list of questions for the ABAP on BTP system
|
|
39
34
|
*/
|
|
40
|
-
function getAbapOnBTPSystemQuestions(promptOptions, cachedConnectedSystem
|
|
35
|
+
function getAbapOnBTPSystemQuestions(promptOptions, cachedConnectedSystem) {
|
|
41
36
|
utils_1.PromptState.reset();
|
|
42
37
|
const connectValidator = new connectionValidator_1.ConnectionValidator();
|
|
43
38
|
const questions = [];
|
|
@@ -46,15 +41,6 @@ function getAbapOnBTPSystemQuestions(promptOptions, cachedConnectedSystem, servi
|
|
|
46
41
|
name: abapOnBtpPromptNames.abapOnBtpAuthType,
|
|
47
42
|
choices: [
|
|
48
43
|
{ name: (0, i18n_1.t)('prompts.abapOnBTPType.choiceCloudFoundry'), value: 'cloudFoundry' },
|
|
49
|
-
// Feature toggle the service key option - enabled by default, can be disabled via VS Code settings or ENV
|
|
50
|
-
...(!serviceKeyToggle
|
|
51
|
-
? [
|
|
52
|
-
{
|
|
53
|
-
name: (0, i18n_1.t)('prompts.abapOnBTPType.choiceServiceKey'),
|
|
54
|
-
value: 'serviceKey'
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
: []),
|
|
58
44
|
{ name: (0, i18n_1.t)('prompts.abapOnBTPType.choiceReentranceTicket'), value: 'reentranceTicket' }
|
|
59
45
|
],
|
|
60
46
|
message: (0, i18n_1.t)('prompts.abapOnBTPType.message'),
|
|
@@ -73,12 +59,7 @@ function getAbapOnBTPSystemQuestions(promptOptions, cachedConnectedSystem, servi
|
|
|
73
59
|
return true;
|
|
74
60
|
}
|
|
75
61
|
return false;
|
|
76
|
-
})[0]);
|
|
77
|
-
// Service Key file prompt - enabled by default
|
|
78
|
-
if (!serviceKeyToggle) {
|
|
79
|
-
questions.push((0, inquirer_common_1.withCondition)([getServiceKeyPrompt(connectValidator, cachedConnectedSystem)], (answers) => answers?.abapOnBtpAuthType === 'serviceKey')[0]);
|
|
80
|
-
}
|
|
81
|
-
questions.push(...(0, inquirer_common_1.withCondition)([...getCFDiscoverPrompts(connectValidator, undefined, undefined, cachedConnectedSystem)], (answers) => answers?.abapOnBtpAuthType === 'cloudFoundry'));
|
|
62
|
+
})[0], ...(0, inquirer_common_1.withCondition)([...getCFDiscoverPrompts(connectValidator, undefined, undefined, cachedConnectedSystem)], (answers) => answers?.abapOnBtpAuthType === 'cloudFoundry'));
|
|
82
63
|
// New system store name propmt
|
|
83
64
|
if (promptOptions?.userSystemName?.hide !== true) {
|
|
84
65
|
// New system question will allow user to give the system a user friendly name
|
|
@@ -128,7 +109,7 @@ async function validateCFServiceInfo(abapService, connectionValidator, requiredO
|
|
|
128
109
|
// In case the user has changed the URL, do not use the cached connection.
|
|
129
110
|
if (cachedConnectedSystem &&
|
|
130
111
|
cachedConnectedSystem.backendSystem?.url === uaaCreds.credentials.url &&
|
|
131
|
-
JSON.stringify(cachedConnectedSystem.backendSystem.serviceKeys
|
|
112
|
+
JSON.stringify(cachedConnectedSystem.backendSystem.serviceKeys?.uaa) ===
|
|
132
113
|
JSON.stringify(uaaCreds.credentials.uaa)) {
|
|
133
114
|
connectionValidator.setConnectedSystem(cachedConnectedSystem);
|
|
134
115
|
}
|
|
@@ -220,46 +201,4 @@ function getCFDiscoverPrompts(connectionValidator, promptNamespace, requiredOdat
|
|
|
220
201
|
}
|
|
221
202
|
return questions;
|
|
222
203
|
}
|
|
223
|
-
/**
|
|
224
|
-
* Get the service key prompt for the ABAP on BTP system. This prompt will allow the user to select a service key file from the file system.
|
|
225
|
-
*
|
|
226
|
-
* @param connectionValidator a connection validator instance
|
|
227
|
-
* @param cachedConnectedSystem if available passing an already connected system connection will prevent re-authentication for re-entrance ticket and service keys connection types
|
|
228
|
-
* @returns The service key prompt
|
|
229
|
-
*/
|
|
230
|
-
function getServiceKeyPrompt(connectionValidator, cachedConnectedSystem) {
|
|
231
|
-
const question = {
|
|
232
|
-
type: 'input',
|
|
233
|
-
name: abapOnBtpPromptNames.serviceKey,
|
|
234
|
-
message: (0, i18n_1.t)('prompts.serviceKey.message'),
|
|
235
|
-
guiType: 'file-browser',
|
|
236
|
-
guiOptions: {
|
|
237
|
-
hint: (0, i18n_1.t)('prompts.serviceKey.hint'),
|
|
238
|
-
mandatory: true
|
|
239
|
-
},
|
|
240
|
-
validate: async (keyPath) => {
|
|
241
|
-
utils_1.PromptState.resetConnectedSystem();
|
|
242
|
-
const serviceKeyValResult = (0, validators_1.validateServiceKey)(keyPath);
|
|
243
|
-
if (typeof serviceKeyValResult === 'string' || typeof serviceKeyValResult === 'boolean') {
|
|
244
|
-
return serviceKeyValResult;
|
|
245
|
-
}
|
|
246
|
-
// Backend systems validation supports using a cached connections from a previous step execution to prevent re-authentication (e.g. re-opening a browser window)
|
|
247
|
-
// In case the user has changed the URL, do not use the cached connection.
|
|
248
|
-
if (cachedConnectedSystem &&
|
|
249
|
-
cachedConnectedSystem.backendSystem?.url === serviceKeyValResult.url &&
|
|
250
|
-
JSON.stringify(cachedConnectedSystem.backendSystem.serviceKeys.uaa) ===
|
|
251
|
-
JSON.stringify(serviceKeyValResult.uaa)) {
|
|
252
|
-
connectionValidator.setConnectedSystem(cachedConnectedSystem);
|
|
253
|
-
}
|
|
254
|
-
const connectValResult = await connectionValidator.validateServiceInfo(serviceKeyValResult);
|
|
255
|
-
if (connectValResult === true && connectionValidator.serviceProvider) {
|
|
256
|
-
utils_1.PromptState.odataService.connectedSystem = {
|
|
257
|
-
serviceProvider: (0, utils_1.removeCircularFromServiceProvider)(connectionValidator.serviceProvider)
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
return connectValResult;
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
return question;
|
|
264
|
-
}
|
|
265
204
|
//# sourceMappingURL=questions.js.map
|
|
@@ -13,7 +13,7 @@ import { type NewSystemAnswers } from '../new-system/types';
|
|
|
13
13
|
* @param connectValidator a connection validator instance used to validate the system url
|
|
14
14
|
* @param promptNamespace The namespace for the prompt, used to identify the prompt instance and namespaced answers.
|
|
15
15
|
* @param requiredOdataVersion The required OData version for the system connection, only catalogs supporting the specifc odata version will be used.
|
|
16
|
-
* @param cachedConnectedSystem
|
|
16
|
+
* @param cachedConnectedSystem An existing connection may be passed which will prevent reauthentication
|
|
17
17
|
* @returns the system url prompt
|
|
18
18
|
*/
|
|
19
19
|
export declare function getSystemUrlQuestion<T extends Answers>(connectValidator: ConnectionValidator, promptNamespace?: string, requiredOdataVersion?: OdataVersion, cachedConnectedSystem?: ConnectedSystem): InputQuestion<T>;
|
|
@@ -19,8 +19,8 @@ const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
|
|
|
19
19
|
*/
|
|
20
20
|
function systemAuthTypeToAuthenticationType(systemAuthType) {
|
|
21
21
|
switch (systemAuthType) {
|
|
22
|
-
case 'serviceKey'
|
|
23
|
-
return store_1.AuthenticationType.
|
|
22
|
+
case 'serviceKey' /** @deprecated All cloud auth is reentrance ticket based, legacy stored entries are still supported */:
|
|
23
|
+
return store_1.AuthenticationType.ReentranceTicket;
|
|
24
24
|
case 'reentranceTicket':
|
|
25
25
|
return store_1.AuthenticationType.ReentranceTicket;
|
|
26
26
|
case 'basic':
|
|
@@ -35,7 +35,7 @@ function systemAuthTypeToAuthenticationType(systemAuthType) {
|
|
|
35
35
|
* @param connectValidator a connection validator instance used to validate the system url
|
|
36
36
|
* @param promptNamespace The namespace for the prompt, used to identify the prompt instance and namespaced answers.
|
|
37
37
|
* @param requiredOdataVersion The required OData version for the system connection, only catalogs supporting the specifc odata version will be used.
|
|
38
|
-
* @param cachedConnectedSystem
|
|
38
|
+
* @param cachedConnectedSystem An existing connection may be passed which will prevent reauthentication
|
|
39
39
|
* @returns the system url prompt
|
|
40
40
|
*/
|
|
41
41
|
function getSystemUrlQuestion(connectValidator, promptNamespace, requiredOdataVersion, cachedConnectedSystem) {
|
|
@@ -52,12 +52,21 @@ function getSystemUrlQuestion(connectValidator, promptNamespace, requiredOdataVe
|
|
|
52
52
|
validate: async (url) => {
|
|
53
53
|
utils_1.PromptState.resetConnectedSystem();
|
|
54
54
|
// Backend systems validation supports using a cached connections from a previous step execution to prevent re-authentication (e.g. re-opening a browser window)
|
|
55
|
-
// Only in the case
|
|
55
|
+
// Only in the case of re-entrance tickets will we reuse an existing connection.
|
|
56
56
|
if (cachedConnectedSystem &&
|
|
57
57
|
cachedConnectedSystem.backendSystem?.url === url &&
|
|
58
58
|
cachedConnectedSystem.backendSystem?.authenticationType === 'reentranceTicket') {
|
|
59
59
|
connectValidator.setConnectedSystem(cachedConnectedSystem);
|
|
60
60
|
}
|
|
61
|
+
else {
|
|
62
|
+
const existingBackend = (0, utils_1.isBackendSystemKeyExisting)(utils_1.PromptState.backendSystemsCache, url);
|
|
63
|
+
if (existingBackend) {
|
|
64
|
+
// Not a cached connection so re-validate as new backend system entry
|
|
65
|
+
return (0, i18n_1.t)('prompts.validationMessages.backendSystemExistsWarning', {
|
|
66
|
+
backendName: existingBackend.name
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
61
70
|
const valResult = await connectValidator.validateUrl(url, {
|
|
62
71
|
isSystem: true,
|
|
63
72
|
odataVersion: (0, utils_1.convertODataVersionType)(requiredOdataVersion)
|
|
@@ -143,13 +152,12 @@ function getUserSystemNameQuestion(connectValidator, promptNamespace) {
|
|
|
143
152
|
client: connectValidator.validatedClient,
|
|
144
153
|
username: connectValidator.axiosConfig?.auth?.username,
|
|
145
154
|
password: connectValidator.axiosConfig?.auth?.password,
|
|
146
|
-
serviceKeys: connectValidator.serviceInfo,
|
|
155
|
+
serviceKeys: connectValidator.serviceInfo, // This will not be persisted and is only used to determine cached connection equality for CF provided uaa keys
|
|
147
156
|
userDisplayName: connectValidator.connectedUserName,
|
|
148
157
|
systemType: (0, store_1.getBackendSystemType)({
|
|
149
158
|
serviceKeys: connectValidator.serviceInfo,
|
|
150
159
|
authenticationType: connectValidator.systemAuthType
|
|
151
|
-
})
|
|
152
|
-
refreshToken: connectValidator.refreshToken
|
|
160
|
+
})
|
|
153
161
|
});
|
|
154
162
|
utils_1.PromptState.odataService.connectedSystem.backendSystem = backendSystem;
|
|
155
163
|
utils_1.PromptState.odataService.connectedSystem.backendSystem.newOrUpdated = true;
|
|
@@ -35,13 +35,6 @@ export declare function connectWithBackendSystem(backendKey: BackendSystemKey, c
|
|
|
35
35
|
* @returns the validation result of the destination connection attempt
|
|
36
36
|
*/
|
|
37
37
|
export declare function connectWithDestination(destination: Destination, connectionValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion, addServicePath?: string): Promise<ValidationResult>;
|
|
38
|
-
/**
|
|
39
|
-
* Creates and returns a display name for the system, appending the system type and user display name if available.
|
|
40
|
-
*
|
|
41
|
-
* @param system the backend system to create a display name for
|
|
42
|
-
* @returns the display name for the system
|
|
43
|
-
*/
|
|
44
|
-
export declare function getBackendSystemDisplayName(system: BackendSystem): string;
|
|
45
38
|
/**
|
|
46
39
|
* Creates a list of choices for the system selection prompt using destinations or stored backend systems, depending on the environment.
|
|
47
40
|
*
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.CfAbapEnvServiceChoice = exports.NewSystemChoice = void 0;
|
|
7
7
|
exports.connectWithBackendSystem = connectWithBackendSystem;
|
|
8
8
|
exports.connectWithDestination = connectWithDestination;
|
|
9
|
-
exports.getBackendSystemDisplayName = getBackendSystemDisplayName;
|
|
10
9
|
exports.createSystemChoices = createSystemChoices;
|
|
11
10
|
exports.findDefaultSystemSelectionIndex = findDefaultSystemSelectionIndex;
|
|
12
11
|
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
@@ -15,6 +14,7 @@ const store_1 = require("@sap-ux/store");
|
|
|
15
14
|
const i18n_1 = require("../../../../i18n");
|
|
16
15
|
const utils_1 = require("../../../../utils");
|
|
17
16
|
const logger_helper_1 = __importDefault(require("../../../logger-helper"));
|
|
17
|
+
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
18
18
|
// New system choice value is a hard to guess string to avoid conflicts with existing system names or user named systems
|
|
19
19
|
// since it will be used as a new system value in the system selection prompt.
|
|
20
20
|
exports.NewSystemChoice = '!@£*&937newSystem*X~qy^';
|
|
@@ -49,7 +49,7 @@ async function connectWithBackendSystem(backendKey, connectionValidator, require
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
else if (backendSystem.serviceKeys) {
|
|
52
|
-
connectValResult = await connectionValidator.validateServiceInfo(backendSystem.serviceKeys, (0, utils_1.convertODataVersionType)(requiredOdataVersion)
|
|
52
|
+
connectValResult = await connectionValidator.validateServiceInfo(backendSystem.serviceKeys, (0, utils_1.convertODataVersionType)(requiredOdataVersion));
|
|
53
53
|
}
|
|
54
54
|
else if (backendSystem.authenticationType === 'basic' || !backendSystem.authenticationType) {
|
|
55
55
|
let errorType;
|
|
@@ -108,33 +108,6 @@ async function connectWithDestination(destination, connectionValidator, required
|
|
|
108
108
|
// Deal with all destination errors here
|
|
109
109
|
return connectValResult;
|
|
110
110
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Creates and returns a display name for the system, appending the system type and user display name if available.
|
|
113
|
-
*
|
|
114
|
-
* @param system the backend system to create a display name for
|
|
115
|
-
* @returns the display name for the system
|
|
116
|
-
*/
|
|
117
|
-
function getBackendSystemDisplayName(system) {
|
|
118
|
-
const userDisplayName = system.userDisplayName ? ` [${system.userDisplayName}]` : '';
|
|
119
|
-
const systemTypeName = getBackendSystemTypeName(system.systemType);
|
|
120
|
-
return `${system.name}${systemTypeName}${userDisplayName}`;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Returns the formatted system type name for the given backend system.
|
|
124
|
-
*
|
|
125
|
-
* @param systemType the system type to get the name for
|
|
126
|
-
* @returns system type name formatted as a string, e.g. " (BTP)" or " (S4HC)".
|
|
127
|
-
*/
|
|
128
|
-
function getBackendSystemTypeName(systemType) {
|
|
129
|
-
let systemTypeName = ''; // for on prem we do not show the system type
|
|
130
|
-
if (systemType === 'S4HC') {
|
|
131
|
-
systemTypeName = ` (${(0, i18n_1.t)('texts.systemTypeS4HC')})`;
|
|
132
|
-
}
|
|
133
|
-
else if (systemType === 'BTP') {
|
|
134
|
-
systemTypeName = ` (${(0, i18n_1.t)('texts.systemTypeBTP')})`;
|
|
135
|
-
}
|
|
136
|
-
return systemTypeName;
|
|
137
|
-
}
|
|
138
111
|
/**
|
|
139
112
|
* Matches the destination against the provided filters. Returns true if the destination matches any filters, false otherwise.
|
|
140
113
|
*
|
|
@@ -207,9 +180,11 @@ async function createSystemChoices(destinationFilters, includeCloudFoundryAbapEn
|
|
|
207
180
|
}
|
|
208
181
|
else {
|
|
209
182
|
const backendSystems = await new store_1.SystemService(logger_helper_1.default.logger).getAll({ includeSensitiveData: false });
|
|
183
|
+
// Cache the backend systems
|
|
184
|
+
utils_1.PromptState.backendSystemsCache = backendSystems;
|
|
210
185
|
systemChoices = backendSystems.map((system) => {
|
|
211
186
|
return {
|
|
212
|
-
name: getBackendSystemDisplayName(system),
|
|
187
|
+
name: (0, fiori_generator_shared_1.getBackendSystemDisplayName)(system),
|
|
213
188
|
value: {
|
|
214
189
|
system,
|
|
215
190
|
type: 'backendSystem'
|
|
@@ -58,7 +58,9 @@
|
|
|
58
58
|
"metadataFilePathNotValid": "The metadata file does not exist or is not accessible. Please specify a valid file path.",
|
|
59
59
|
"capProjectNotFound": "The folder you have selected does not contain a valid CAP project. Please check and try again.",
|
|
60
60
|
"warningCertificateValidationDisabled": "Certificate validation has been disabled by the user.",
|
|
61
|
-
"annotationsNotFound": "Annotations not found for the specified service."
|
|
61
|
+
"annotationsNotFound": "Annotations not found for the specified service.",
|
|
62
|
+
"backendSystemExistsWarning": "A saved system connection entry: \"{{- backendName}}\" already exists with the same URL and client. Please reuse the existing entry or remove it, using the systems panel, before adding a new connection.",
|
|
63
|
+
"reentranceTicketSystemHostOnly": "ABAP cloud system urls must only contain the hostname, for example, 'https://123.abc.com'"
|
|
62
64
|
},
|
|
63
65
|
"warnings": {
|
|
64
66
|
"nonUIServiceTypeWarningMessage": "Services of service type: {{serviceType}} or without a service type are not intended to be used for generating SAP Fiori UI applications.",
|
|
@@ -252,8 +254,6 @@
|
|
|
252
254
|
"suggestedSystemNameClient": ", client {{client}}",
|
|
253
255
|
"seeLogForDetails": "For more information, view the logs.",
|
|
254
256
|
"forUserName": "(for user [{{username}}])",
|
|
255
|
-
"systemTypeBTP": "BTP",
|
|
256
|
-
"systemTypeS4HC": "S4HC",
|
|
257
257
|
"httpStatus": "HTTP Status {{httpStatus}}",
|
|
258
258
|
"checkDestinationAuthConfig": "Please check the SAP BTP destination authentication configuration.",
|
|
259
259
|
"choiceNameNone": "None"
|
package/dist/types.d.ts
CHANGED
|
@@ -172,7 +172,7 @@ export interface EntitySelectionAnswers {
|
|
|
172
172
|
* Answers related to the Page Building Block prompt.
|
|
173
173
|
*/
|
|
174
174
|
export interface PageBuildingBlockAnswers {
|
|
175
|
-
/** Indicates if
|
|
175
|
+
/** Indicates if a Page Building Block should be addedn*/
|
|
176
176
|
[EntityPromptNames.addPageBuildingBlock]?: boolean;
|
|
177
177
|
/** The title for the Page Building Block, required if addPageBuildingBlock is true */
|
|
178
178
|
[EntityPromptNames.pageBuildingBlockTitle]?: string;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { OdataVersion } from '@sap-ux/odata-service-writer';
|
|
|
5
5
|
import type { ListChoiceOptions } from 'inquirer';
|
|
6
6
|
import { PromptState } from './prompt-state';
|
|
7
7
|
import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
|
|
8
|
+
import type { BackendSystem } from '@sap-ux/store';
|
|
8
9
|
/**
|
|
9
10
|
* Determine if the current prompting environment is cli or a hosted extension (app studio or vscode).
|
|
10
11
|
*
|
|
@@ -63,5 +64,14 @@ export declare function getDefaultChoiceIndex(list: ListChoiceOptions[]): number
|
|
|
63
64
|
* @returns the service provider with the circular dependencies removed
|
|
64
65
|
*/
|
|
65
66
|
export declare function removeCircularFromServiceProvider(serviceProvider: ServiceProvider): ServiceProvider;
|
|
67
|
+
/**
|
|
68
|
+
* Checks if the specified backend systems contain a match for the specified url and client.
|
|
69
|
+
*
|
|
70
|
+
* @param backendSystems backend systems to search for a matching key
|
|
71
|
+
* @param url the url component of the backend system key
|
|
72
|
+
* @param client the client component of of the backend system key
|
|
73
|
+
* @returns the backend system if found or undefined
|
|
74
|
+
*/
|
|
75
|
+
export declare function isBackendSystemKeyExisting(backendSystems: BackendSystem[], url: string, client?: string): BackendSystem | undefined;
|
|
66
76
|
export { PromptState };
|
|
67
77
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/utils/index.js
CHANGED
|
@@ -11,6 +11,7 @@ exports.originToRelative = originToRelative;
|
|
|
11
11
|
exports.convertODataVersionType = convertODataVersionType;
|
|
12
12
|
exports.getDefaultChoiceIndex = getDefaultChoiceIndex;
|
|
13
13
|
exports.removeCircularFromServiceProvider = removeCircularFromServiceProvider;
|
|
14
|
+
exports.isBackendSystemKeyExisting = isBackendSystemKeyExisting;
|
|
14
15
|
const axios_extension_1 = require("@sap-ux/axios-extension");
|
|
15
16
|
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
16
17
|
const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
|
|
@@ -23,6 +24,7 @@ Object.defineProperty(exports, "PromptState", { enumerable: true, get: function
|
|
|
23
24
|
const annotation_converter_1 = require("@sap-ux/annotation-converter");
|
|
24
25
|
const edmx_parser_1 = require("@sap-ux/edmx-parser");
|
|
25
26
|
const circular_reference_remover_1 = require("circular-reference-remover");
|
|
27
|
+
const store_1 = require("@sap-ux/store");
|
|
26
28
|
/**
|
|
27
29
|
* Determine if the current prompting environment is cli or a hosted extension (app studio or vscode).
|
|
28
30
|
*
|
|
@@ -146,4 +148,16 @@ function removeCircularFromServiceProvider(serviceProvider) {
|
|
|
146
148
|
}
|
|
147
149
|
return serviceProvider;
|
|
148
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Checks if the specified backend systems contain a match for the specified url and client.
|
|
153
|
+
*
|
|
154
|
+
* @param backendSystems backend systems to search for a matching key
|
|
155
|
+
* @param url the url component of the backend system key
|
|
156
|
+
* @param client the client component of of the backend system key
|
|
157
|
+
* @returns the backend system if found or undefined
|
|
158
|
+
*/
|
|
159
|
+
function isBackendSystemKeyExisting(backendSystems, url, client) {
|
|
160
|
+
const newBackendSystemId = new store_1.BackendSystemKey({ url, client }).getId();
|
|
161
|
+
return backendSystems.find((backendSystem) => store_1.BackendSystemKey.from(backendSystem).getId() === newBackendSystemId);
|
|
162
|
+
}
|
|
149
163
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BackendSystem } from '@sap-ux/store';
|
|
1
2
|
import type { OdataServiceAnswers } from '../types';
|
|
2
3
|
/**
|
|
3
4
|
* Much of the values returned by the service inquirer prompting are derived from prompt answers and are not direct answer values.
|
|
@@ -8,6 +9,10 @@ import type { OdataServiceAnswers } from '../types';
|
|
|
8
9
|
export declare class PromptState {
|
|
9
10
|
static odataService: Partial<OdataServiceAnswers>;
|
|
10
11
|
static isYUI: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* To prevent re-reads from store load the backend systems once.
|
|
14
|
+
*/
|
|
15
|
+
static backendSystemsCache: BackendSystem[];
|
|
11
16
|
static reset(): void;
|
|
12
17
|
static resetConnectedSystem(): void;
|
|
13
18
|
}
|
|
@@ -10,6 +10,10 @@ exports.PromptState = void 0;
|
|
|
10
10
|
class PromptState {
|
|
11
11
|
static odataService = {};
|
|
12
12
|
static isYUI = false;
|
|
13
|
+
/**
|
|
14
|
+
* To prevent re-reads from store load the backend systems once.
|
|
15
|
+
*/
|
|
16
|
+
static backendSystemsCache = [];
|
|
13
17
|
static reset() {
|
|
14
18
|
// Reset all values in the odataService object, do not reset the object reference itself as it may be used by external consumers
|
|
15
19
|
Object.keys(PromptState.odataService).forEach((key) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap-ux/odata-service-inquirer",
|
|
3
3
|
"description": "Prompts module that can prompt users for inputs required for odata service writing",
|
|
4
|
-
"version": "2.8.
|
|
4
|
+
"version": "2.8.13",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/SAP/open-ux-tools.git",
|
|
@@ -29,17 +29,17 @@
|
|
|
29
29
|
"i18next": "25.3.0",
|
|
30
30
|
"inquirer-autocomplete-prompt": "2.0.1",
|
|
31
31
|
"os-name": "4.0.1",
|
|
32
|
-
"@sap-ux/axios-extension": "1.
|
|
32
|
+
"@sap-ux/axios-extension": "1.23.0",
|
|
33
33
|
"@sap-ux/btp-utils": "1.1.4",
|
|
34
|
-
"@sap-ux/fiori-generator-shared": "0.13.
|
|
34
|
+
"@sap-ux/fiori-generator-shared": "0.13.23",
|
|
35
35
|
"@sap-ux/guided-answers-helper": "0.4.0",
|
|
36
|
-
"@sap-ux/telemetry": "0.6.
|
|
37
|
-
"@sap-ux/inquirer-common": "0.7.
|
|
36
|
+
"@sap-ux/telemetry": "0.6.29",
|
|
37
|
+
"@sap-ux/inquirer-common": "0.7.51",
|
|
38
38
|
"@sap-ux/logger": "0.7.0",
|
|
39
39
|
"@sap-ux/nodejs-utils": "0.2.7",
|
|
40
40
|
"@sap-ux/project-access": "1.32.4",
|
|
41
41
|
"@sap-ux/project-input-validator": "0.6.26",
|
|
42
|
-
"@sap-ux/store": "1.
|
|
42
|
+
"@sap-ux/store": "1.2.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@sap-ux/vocabularies-types": "0.13.0",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"@types/inquirer": "8.2.6",
|
|
49
49
|
"@types/lodash": "4.14.202",
|
|
50
50
|
"jest-extended": "6.0.0",
|
|
51
|
-
"@sap-ux/fiori-generator-shared": "0.13.
|
|
52
|
-
"@sap-ux/fiori-elements-writer": "2.7.
|
|
53
|
-
"@sap-ux/fiori-freestyle-writer": "2.4.
|
|
54
|
-
"@sap-ux/feature-toggle": "0.3.
|
|
51
|
+
"@sap-ux/fiori-generator-shared": "0.13.23",
|
|
52
|
+
"@sap-ux/fiori-elements-writer": "2.7.20",
|
|
53
|
+
"@sap-ux/fiori-freestyle-writer": "2.4.51",
|
|
54
|
+
"@sap-ux/feature-toggle": "0.3.2",
|
|
55
55
|
"@sap-ux/odata-service-writer": "0.27.25",
|
|
56
|
-
"@sap-ux/cap-config-writer": "0.12.
|
|
56
|
+
"@sap-ux/cap-config-writer": "0.12.14"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">=20.x"
|