@sap-ux/odata-service-inquirer 2.8.12 → 2.9.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.
- 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/prompts/edmx/entity-helper.d.ts +3 -2
- package/dist/prompts/edmx/entity-helper.js +62 -10
- package/dist/prompts/edmx/questions.js +9 -2
- 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'
|
|
@@ -29,7 +29,7 @@ export type EntitySetFilter = 'filterDraftEnabled' | 'filterAggregateTransformat
|
|
|
29
29
|
* Returns the entity choice options for use in a list inquirer prompt.
|
|
30
30
|
*
|
|
31
31
|
* @param edmx metadata string
|
|
32
|
-
* @param options
|
|
32
|
+
* @param options Configuration options for entity filtering and selection
|
|
33
33
|
* @param options.entitySetFilter
|
|
34
34
|
* `filterDraftEnabled` : Only draft enabled entities wil be returned when true, useful for Form Object Page app generation.
|
|
35
35
|
* `filterAggregateTransformationsOnly` : Only return entity choices that have an aggregate annotation (Aggregation.ApplySupported) with the `Transformations` property set,
|
|
@@ -63,11 +63,12 @@ export declare function filterDraftEnabledEntities(entitySets: EntitySet[]): Ent
|
|
|
63
63
|
* @param templateType the template type of the application to be generated from the prompt answers
|
|
64
64
|
* @param metadata the metadata (edmx) string of the service
|
|
65
65
|
* @param odataVersion the OData version of the service
|
|
66
|
+
* @param isCapService whether the service is a CAP service or not
|
|
66
67
|
* @param mainEntitySetName the name of the main entity set
|
|
67
68
|
* @param currentTableType the current table type selected by the user
|
|
68
69
|
* @returns the default table type and a boolean indicating if AnalyticalTable should be set as default
|
|
69
70
|
*/
|
|
70
|
-
export declare function getDefaultTableType(templateType: TemplateType, metadata: ConvertedMetadata, odataVersion: OdataVersion, mainEntitySetName?: string, currentTableType?: TableType): {
|
|
71
|
+
export declare function getDefaultTableType(templateType: TemplateType, metadata: ConvertedMetadata, odataVersion: OdataVersion, isCapService: boolean, mainEntitySetName?: string, currentTableType?: TableType): {
|
|
71
72
|
tableType: TableType;
|
|
72
73
|
setAnalyticalTableDefault: boolean;
|
|
73
74
|
};
|
|
@@ -57,7 +57,7 @@ function getNavigationPropertyForParameterisedEntity(entitySet, entityTypes) {
|
|
|
57
57
|
* Returns the entity choice options for use in a list inquirer prompt.
|
|
58
58
|
*
|
|
59
59
|
* @param edmx metadata string
|
|
60
|
-
* @param options
|
|
60
|
+
* @param options Configuration options for entity filtering and selection
|
|
61
61
|
* @param options.entitySetFilter
|
|
62
62
|
* `filterDraftEnabled` : Only draft enabled entities wil be returned when true, useful for Form Object Page app generation.
|
|
63
63
|
* `filterAggregateTransformationsOnly` : Only return entity choices that have an aggregate annotation (Aggregation.ApplySupported) with the `Transformations` property set,
|
|
@@ -147,7 +147,7 @@ function findEntitySetName(entitySets, entityType) {
|
|
|
147
147
|
*/
|
|
148
148
|
function getNavigationEntityChoices(metadata, odataVersion, mainEntityName) {
|
|
149
149
|
const choices = [];
|
|
150
|
-
const mainEntitySet =
|
|
150
|
+
const mainEntitySet = (0, inquirer_common_1.findEntitySetByName)(metadata, mainEntityName);
|
|
151
151
|
let navProps = [];
|
|
152
152
|
if (odataVersion === odata_service_writer_1.OdataVersion.v4) {
|
|
153
153
|
navProps = mainEntitySet?.entityType.navigationProperties.filter((navProp) => navProp.isCollection) ?? [];
|
|
@@ -181,28 +181,80 @@ function filterDraftEnabledEntities(entitySets) {
|
|
|
181
181
|
return !!entitySetTypeProperties.find((property) => property.name === 'HasDraftEntity');
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Determines if AnalyticalTable should be used based on entity annotations and service type.
|
|
186
|
+
*
|
|
187
|
+
* AnalyticalTable is used when entity has hierarchical and analytical data together, for CAP services with analytical data,
|
|
188
|
+
* or for non-CAP services with complete analytical transformations.
|
|
189
|
+
*
|
|
190
|
+
* @param entitySet The entity set to check for annotations.
|
|
191
|
+
* @param isCapService Whether the service is a CAP service (affects analytical requirements).
|
|
192
|
+
* @returns True if AnalyticalTable should be used, false otherwise.
|
|
193
|
+
*/
|
|
194
|
+
function shouldUseAnalyticalTable(entitySet, isCapService) {
|
|
195
|
+
// Evaluate annotations once to avoid multiple iterations
|
|
196
|
+
const hasAnalytical = (0, inquirer_common_1.hasAggregateTransformations)(entitySet);
|
|
197
|
+
const hasHierarchy = (0, inquirer_common_1.hasRecursiveHierarchyForEntitySet)(entitySet);
|
|
198
|
+
// No analytical data means no need for AnalyticalTable
|
|
199
|
+
if (!hasAnalytical) {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
// If entity has both analytical and hierarchical data, always use AnalyticalTable
|
|
203
|
+
if (hasHierarchy) {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
// For CAP services, analytical annotations are sufficient
|
|
207
|
+
if (isCapService) {
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
// For non-CAP services, require complete analytical transformations
|
|
211
|
+
return (0, inquirer_common_1.hasAggregateTransformationsForEntitySet)(entitySet, inquirer_common_1.transformationsRequiredForAnalyticalTable);
|
|
212
|
+
}
|
|
184
213
|
/**
|
|
185
214
|
* Get the default table type based on the template type and previous answers.
|
|
186
215
|
*
|
|
187
216
|
* @param templateType the template type of the application to be generated from the prompt answers
|
|
188
217
|
* @param metadata the metadata (edmx) string of the service
|
|
189
218
|
* @param odataVersion the OData version of the service
|
|
219
|
+
* @param isCapService whether the service is a CAP service or not
|
|
190
220
|
* @param mainEntitySetName the name of the main entity set
|
|
191
221
|
* @param currentTableType the current table type selected by the user
|
|
192
222
|
* @returns the default table type and a boolean indicating if AnalyticalTable should be set as default
|
|
193
223
|
*/
|
|
194
|
-
function getDefaultTableType(templateType, metadata, odataVersion, mainEntitySetName, currentTableType) {
|
|
224
|
+
function getDefaultTableType(templateType, metadata, odataVersion, isCapService, mainEntitySetName, currentTableType) {
|
|
195
225
|
let tableType;
|
|
196
226
|
let setAnalyticalTableDefault = false;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
227
|
+
// Find the entity set once for all annotation checks
|
|
228
|
+
const entitySet = mainEntitySetName ? (0, inquirer_common_1.findEntitySetByName)(metadata, mainEntitySetName) : undefined;
|
|
229
|
+
if (entitySet) {
|
|
230
|
+
if ((templateType === 'lrop' || templateType === 'worklist') &&
|
|
231
|
+
odataVersion === odata_service_writer_1.OdataVersion.v4 &&
|
|
232
|
+
shouldUseAnalyticalTable(entitySet, isCapService)) {
|
|
233
|
+
// Use AnalyticalTable for entities with analytical data based on optimized annotation evaluation
|
|
234
|
+
tableType = 'AnalyticalTable';
|
|
235
|
+
setAnalyticalTableDefault = true;
|
|
236
|
+
}
|
|
237
|
+
else if ((templateType === 'lrop' || templateType === 'worklist') &&
|
|
238
|
+
odataVersion === odata_service_writer_1.OdataVersion.v4 &&
|
|
239
|
+
(0, inquirer_common_1.hasRecursiveHierarchyForEntitySet)(entitySet)) {
|
|
240
|
+
// If the main entity type is annotated with Hierarchy.RecursiveHierarchy, use TreeTable as default
|
|
241
|
+
tableType = 'TreeTable';
|
|
242
|
+
}
|
|
243
|
+
else if (templateType === 'alp') {
|
|
244
|
+
// For ALP, use AnalyticalTable as default
|
|
245
|
+
tableType = 'AnalyticalTable';
|
|
246
|
+
}
|
|
247
|
+
else if (currentTableType) {
|
|
248
|
+
// If the user has already selected a table type use it
|
|
249
|
+
tableType = currentTableType;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
// Default to ResponsiveTable for other cases
|
|
253
|
+
tableType = 'ResponsiveTable';
|
|
254
|
+
}
|
|
203
255
|
}
|
|
204
256
|
else if (templateType === 'alp') {
|
|
205
|
-
// For ALP, use AnalyticalTable as default
|
|
257
|
+
// For ALP, use AnalyticalTable as default even if entity set is not found
|
|
206
258
|
tableType = 'AnalyticalTable';
|
|
207
259
|
}
|
|
208
260
|
else if (currentTableType) {
|
|
@@ -213,7 +213,7 @@ function getTableLayoutQuestions(templateType, odataVersion, isCapService, metad
|
|
|
213
213
|
},
|
|
214
214
|
choices: tableTypeChoices,
|
|
215
215
|
default: (prevAnswers) => {
|
|
216
|
-
const tableTypeDefault = (0, entity_helper_1.getDefaultTableType)(templateType, metadata, odataVersion, prevAnswers?.mainEntity?.entitySetName, prevAnswers?.tableType);
|
|
216
|
+
const tableTypeDefault = (0, entity_helper_1.getDefaultTableType)(templateType, metadata, odataVersion, isCapService, prevAnswers?.mainEntity?.entitySetName, prevAnswers?.tableType);
|
|
217
217
|
setAnalyticalTableDefault = tableTypeDefault.setAnalyticalTableDefault;
|
|
218
218
|
return tableTypeDefault.tableType;
|
|
219
219
|
},
|
|
@@ -236,7 +236,14 @@ function getTableLayoutQuestions(templateType, odataVersion, isCapService, metad
|
|
|
236
236
|
breadcrumb: true,
|
|
237
237
|
mandatory: true
|
|
238
238
|
},
|
|
239
|
-
default:
|
|
239
|
+
default: (prevAnswers) => {
|
|
240
|
+
// Auto-populate qualifier from RecursiveHierarchy annotation if available
|
|
241
|
+
if (prevAnswers?.mainEntity?.entitySetName) {
|
|
242
|
+
const entitySet = (0, inquirer_common_1.findEntitySetByName)(metadata, prevAnswers.mainEntity.entitySetName);
|
|
243
|
+
return entitySet ? (0, inquirer_common_1.getRecursiveHierarchyQualifierForEntitySet)(entitySet) : '';
|
|
244
|
+
}
|
|
245
|
+
return '';
|
|
246
|
+
},
|
|
240
247
|
validate: (input) => {
|
|
241
248
|
if (!input) {
|
|
242
249
|
return (0, i18n_1.t)('prompts.hierarchyQualifier.qualifierRequiredForV4Warning');
|
|
@@ -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.
|
|
4
|
+
"version": "2.9.0",
|
|
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.
|
|
36
|
+
"@sap-ux/telemetry": "0.6.29",
|
|
37
|
+
"@sap-ux/inquirer-common": "0.8.0",
|
|
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.24",
|
|
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"
|