@sap-ux/odata-service-inquirer 0.6.8 → 0.6.10

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/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { OdataVersion } from '@sap-ux/odata-service-writer';
4
4
  import { type ToolsSuiteTelemetryClient } from '@sap-ux/telemetry';
5
5
  import { ERROR_TYPE, ErrorHandler } from '@sap-ux/inquirer-common';
6
6
  import { SystemSelectionAnswerType } from './prompts/datasources/sap-system/system-selection';
7
+ import type { NewSystemChoice, CfAbapEnvServiceChoice } from './prompts/datasources/sap-system/system-selection/prompt-helpers';
7
8
  import { DatasourceType, promptNames, type CapRuntime, type CapService, type OdataServiceAnswers, type OdataServicePromptOptions, type OdataServiceQuestion, type SapSystemType } from './types';
8
9
  /**
9
10
  * Get the inquirer prompts for odata service.
@@ -31,5 +32,5 @@ declare function getPrompts(promptOptions?: OdataServicePromptOptions, logger?:
31
32
  * @returns the prompt answers
32
33
  */
33
34
  declare function prompt(adapter: InquirerAdapter, promptOptions?: OdataServicePromptOptions, logger?: Logger, enableGuidedAnswers?: boolean, telemetryClient?: ToolsSuiteTelemetryClient, isYUI?: boolean): Promise<OdataServiceAnswers>;
34
- export { DatasourceType, ERROR_TYPE, ErrorHandler, getPrompts, OdataVersion, prompt, promptNames, SystemSelectionAnswerType, type CapRuntime, type CapService, type InquirerAdapter, type OdataServiceAnswers, type OdataServicePromptOptions, type SapSystemType };
35
+ export { DatasourceType, ERROR_TYPE, ErrorHandler, getPrompts, OdataVersion, prompt, promptNames, SystemSelectionAnswerType, type CapRuntime, type CapService, type InquirerAdapter, type OdataServiceAnswers, type OdataServicePromptOptions, type SapSystemType, NewSystemChoice, CfAbapEnvServiceChoice };
35
36
  //# sourceMappingURL=index.d.ts.map
@@ -476,15 +476,20 @@ class ConnectionValidator {
476
476
  this.resetValidity();
477
477
  // Get the destination URL in the BAS specific form <protocol>://<destinationName>.dest
478
478
  const destUrl = (0, btp_utils_1.getDestinationUrlForAppStudio)(destination.Name, servicePath);
479
- // Get the destination URL in the portable form <protocol>://<host>:<port>
480
- this._destinationUrl = servicePath ? new URL(`${destination.Host}${servicePath}`).toString() : destination.Host;
479
+ // Get the destination URL in the portable form <protocol>://<host>:<port>.
480
+ // We remove trailing slashes (up to 10, infinite would allow DOS attack) from the host to avoid double slashes when appending the service path.
481
+ this._destinationUrl = servicePath
482
+ ? destUrl.replace(`https://${destination.Name}.dest`, destination.Host.replace(/\/{1,10}$/, ''))
483
+ : destination.Host;
481
484
  this._destination = destination;
482
485
  // No need to apply sap-client as this happens automatically (from destination config) when going through the BAS proxy
483
486
  const status = await this.checkUrl(new URL(destUrl), undefined, undefined, {
484
487
  odataVersion: requiredOdataVersion
485
488
  });
486
- this._validatedUrl = destUrl;
487
489
  const validationResult = this.getValidationResultFromStatusCode(status);
490
+ if (this.validity.reachable && (!this.validity.authRequired || this.validity.authenticated)) {
491
+ this._validatedUrl = destUrl;
492
+ }
488
493
  if (!this.validity.reachable) {
489
494
  // Log the error
490
495
  const errorLog = prompt_helpers_1.errorHandler.logErrorMsgs(status);
@@ -4,7 +4,11 @@ import type { BackendSystem } from '@sap-ux/store';
4
4
  import type { ListChoiceOptions } from 'inquirer';
5
5
  import { type DestinationFilters } from '../../../../types';
6
6
  import type { ConnectionValidator, ValidationResult } from '../../../connectionValidator';
7
- import { type SystemSelectionAnswers } from './questions';
7
+ import { type SystemSelectionAnswerType } from './questions';
8
+ export declare const NewSystemChoice = "!@\u00A3*&937newSystem*X~qy^";
9
+ export type NewSystemChoice = typeof NewSystemChoice;
10
+ export declare const CfAbapEnvServiceChoice = "cfAbapEnvService";
11
+ export type CfAbapEnvServiceChoice = typeof CfAbapEnvServiceChoice;
8
12
  /**
9
13
  * Connects to the specified backend system and validates the connection.
10
14
  * Note this will return true in the case of basic auth validation failure to defer validation to the credentials prompt.
@@ -40,5 +44,13 @@ export declare function getBackendSystemDisplayName(system: BackendSystem): stri
40
44
  * @param includeCloudFoundryAbapEnvChoice whether to include the Cloud Foundry ABAP environment choice in the list
41
45
  * @returns a list of choices for the system selection prompt
42
46
  */
43
- export declare function createSystemChoices(destinationFilters?: Partial<DestinationFilters>, includeCloudFoundryAbapEnvChoice?: boolean): Promise<ListChoiceOptions<SystemSelectionAnswers>[]>;
47
+ export declare function createSystemChoices(destinationFilters?: Partial<DestinationFilters>, includeCloudFoundryAbapEnvChoice?: boolean): Promise<ListChoiceOptions<SystemSelectionAnswerType>[]>;
48
+ /**
49
+ * Find the default selection index based on the default choice value.
50
+ *
51
+ * @param systemChoices the list of system choices
52
+ * @param defaultChoice the default choice value
53
+ * @returns the index of the default choice in the system choices list
54
+ */
55
+ export declare function findDefaultSystemSelectionIndex(systemChoices: ListChoiceOptions<SystemSelectionAnswerType>[], defaultChoice: string | undefined): number;
44
56
  //# sourceMappingURL=prompt-helpers.d.ts.map
@@ -3,17 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CfAbapEnvServiceChoice = exports.NewSystemChoice = void 0;
6
7
  exports.connectWithBackendSystem = connectWithBackendSystem;
7
8
  exports.connectWithDestination = connectWithDestination;
8
9
  exports.getBackendSystemDisplayName = getBackendSystemDisplayName;
9
10
  exports.createSystemChoices = createSystemChoices;
11
+ exports.findDefaultSystemSelectionIndex = findDefaultSystemSelectionIndex;
10
12
  const btp_utils_1 = require("@sap-ux/btp-utils");
11
13
  const store_1 = require("@sap-ux/store");
12
14
  const inquirer_common_1 = require("@sap-ux/inquirer-common");
13
15
  const i18n_1 = require("../../../../i18n");
14
16
  const utils_1 = require("../../../../utils");
15
17
  const logger_helper_1 = __importDefault(require("../../../logger-helper"));
16
- const questions_1 = require("./questions");
18
+ // New system choice value is a hard to guess string to avoid conflicts with existing system names or user named systems
19
+ // since it will be used as a new system value in the system selection prompt.
20
+ exports.NewSystemChoice = '!@£*&937newSystem*X~qy^';
21
+ exports.CfAbapEnvServiceChoice = 'cfAbapEnvService';
17
22
  /**
18
23
  * Connects to the specified backend system and validates the connection.
19
24
  * Note this will return true in the case of basic auth validation failure to defer validation to the credentials prompt.
@@ -161,7 +166,10 @@ async function createSystemChoices(destinationFilters, includeCloudFoundryAbapEn
161
166
  if (includeCloudFoundryAbapEnvChoice) {
162
167
  newSystemChoice = {
163
168
  name: (0, i18n_1.t)('prompts.newSystemType.choiceCFAbapEnvServiceOnBtp'),
164
- value: { type: 'cfAbapEnvService', system: 'cfAbapEnvService' }
169
+ value: {
170
+ type: exports.CfAbapEnvServiceChoice,
171
+ system: exports.CfAbapEnvServiceChoice
172
+ }
165
173
  };
166
174
  }
167
175
  }
@@ -178,7 +186,7 @@ async function createSystemChoices(destinationFilters, includeCloudFoundryAbapEn
178
186
  });
179
187
  newSystemChoice = {
180
188
  name: (0, i18n_1.t)('prompts.systemSelection.newSystemChoiceLabel'),
181
- value: { system: questions_1.newSystemChoiceValue, type: 'newSystemChoice' }
189
+ value: { type: 'newSystemChoice', system: exports.NewSystemChoice }
182
190
  };
183
191
  }
184
192
  systemChoices.sort(({ name: nameA }, { name: nameB }) => nameA.localeCompare(nameB, undefined, { numeric: true, caseFirst: 'lower' }));
@@ -187,4 +195,32 @@ async function createSystemChoices(destinationFilters, includeCloudFoundryAbapEn
187
195
  }
188
196
  return systemChoices;
189
197
  }
198
+ /**
199
+ * Find the default selection index based on the default choice value.
200
+ *
201
+ * @param systemChoices the list of system choices
202
+ * @param defaultChoice the default choice value
203
+ * @returns the index of the default choice in the system choices list
204
+ */
205
+ function findDefaultSystemSelectionIndex(systemChoices, defaultChoice) {
206
+ if (!defaultChoice) {
207
+ return -1;
208
+ }
209
+ const defaultChoiceIndex = systemChoices.findIndex((choice) => {
210
+ const { type: systemType, system } = choice.value;
211
+ if (systemType === 'destination') {
212
+ return system.Name === defaultChoice;
213
+ }
214
+ if (systemType === 'backendSystem') {
215
+ return system.name === defaultChoice;
216
+ }
217
+ if (systemType === 'newSystemChoice') {
218
+ return defaultChoice === exports.NewSystemChoice;
219
+ }
220
+ if (systemType === 'cfAbapEnvService') {
221
+ return defaultChoice === exports.CfAbapEnvServiceChoice;
222
+ }
223
+ });
224
+ return defaultChoiceIndex;
225
+ }
190
226
  //# sourceMappingURL=prompt-helpers.js.map
@@ -1,16 +1,15 @@
1
1
  import type { Destination } from '@sap-ux/btp-utils';
2
2
  import type { BackendSystem } from '@sap-ux/store';
3
3
  import type { Question } from 'inquirer';
4
- import { promptNames, type OdataServicePromptOptions } from '../../../../types';
4
+ import { type OdataServicePromptOptions, promptNames } from '../../../../types';
5
5
  import { ConnectionValidator } from '../../../connectionValidator';
6
6
  import type { ServiceAnswer } from '../service-selection';
7
- export declare const newSystemChoiceValue = "!@\u00A3*&937newSystem*X~qy^";
8
- type NewSystemChoice = typeof newSystemChoiceValue;
7
+ import { type CfAbapEnvServiceChoice, type NewSystemChoice } from './prompt-helpers';
9
8
  declare const usernamePromptName: "systemSelection:systemUsername";
10
9
  declare const passwordPromptName: "systemSelection:systemPassword";
11
10
  export type SystemSelectionAnswerType = {
12
- type: 'destination' | 'backendSystem' | 'newSystemChoice' | 'cfAbapEnvService';
13
- system: Destination | BackendSystem | NewSystemChoice | 'cfAbapEnvService';
11
+ type: 'destination' | 'backendSystem' | 'newSystemChoice' | CfAbapEnvServiceChoice;
12
+ system: Destination | BackendSystem | NewSystemChoice | CfAbapEnvServiceChoice;
14
13
  };
15
14
  interface SystemSelectionCredentialsAnswers {
16
15
  [usernamePromptName]?: string;
@@ -3,11 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.newSystemChoiceValue = void 0;
7
6
  exports.getSystemSelectionQuestions = getSystemSelectionQuestions;
8
7
  exports.getSystemConnectionQuestions = getSystemConnectionQuestions;
9
8
  const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
10
9
  const btp_utils_1 = require("@sap-ux/btp-utils");
10
+ const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
11
11
  const inquirer_common_1 = require("@sap-ux/inquirer-common");
12
12
  const i18n_1 = require("../../../../i18n");
13
13
  const types_1 = require("../../../../types");
@@ -19,10 +19,6 @@ const questions_2 = require("../new-system/questions");
19
19
  const questions_3 = require("../service-selection/questions");
20
20
  const validators_1 = require("../validators");
21
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
22
  const systemSelectionPromptNamespace = 'systemSelection';
27
23
  const usernamePromptName = `${systemSelectionPromptNamespace}:${questions_1.BasicCredentialsPromptNames.systemUsername}`;
28
24
  const passwordPromptName = `${systemSelectionPromptNamespace}:${questions_1.BasicCredentialsPromptNames.systemPassword}`;
@@ -91,6 +87,7 @@ async function getSystemConnectionQuestions(connectionValidator, promptOptions)
91
87
  const requiredOdataVersion = promptOptions?.serviceSelection?.requiredOdataVersion;
92
88
  const destinationFilters = promptOptions?.systemSelection?.destinationFilters;
93
89
  const systemChoices = await (0, prompt_helpers_1.createSystemChoices)(destinationFilters, promptOptions?.systemSelection?.includeCloudFoundryAbapEnvChoice);
90
+ const defaultChoiceIndex = (0, prompt_helpers_1.findDefaultSystemSelectionIndex)(systemChoices, promptOptions?.systemSelection?.defaultChoice);
94
91
  const questions = [
95
92
  {
96
93
  type: promptOptions?.systemSelection?.useAutoComplete ? 'autocomplete' : 'list',
@@ -99,6 +96,7 @@ async function getSystemConnectionQuestions(connectionValidator, promptOptions)
99
96
  hint: (0, i18n_1.t)('prompts.systemSelection.hint'),
100
97
  source: (prevAnswers, input) => (0, inquirer_common_1.searchChoices)(input, systemChoices),
101
98
  choices: systemChoices,
99
+ default: defaultChoiceIndex,
102
100
  validate: async (selectedSystem) => {
103
101
  if (!selectedSystem) {
104
102
  return false;
@@ -139,16 +137,22 @@ async function getSystemConnectionQuestions(connectionValidator, promptOptions)
139
137
  guiOptions: {
140
138
  hint: (0, i18n_1.t)('prompts.destinationServicePath.hint'),
141
139
  mandatory: true,
142
- breadcrumb: true
140
+ breadcrumb: true,
141
+ applyDefaultWhenDirty: true
143
142
  },
143
+ default: '',
144
144
  validate: async (servicePath, answers) => {
145
- if (!servicePath) {
145
+ // @sap-ux/btp-utils getDestinationUrlForAppStudio() enforces a path length of > 1, even though it could be a valid path
146
+ // Double slashes are not allowed at the start of the path as they break URL construction
147
+ if (!servicePath || servicePath.trim().length < 2 || servicePath.startsWith('//')) {
148
+ connectionValidator.resetConnectionState(true);
146
149
  return (0, i18n_1.t)('prompts.destinationServicePath.invalidServicePathWarning');
147
150
  }
148
151
  // Validate format of the service path, note this relies on the assumption that the destination is correctly configured with a valid URL
149
152
  const selectedDestination = answers?.[types_1.promptNames.systemSelection]?.system;
150
153
  const valUrlResult = (0, validators_1.validateServiceUrl)(selectedDestination.Host, servicePath);
151
154
  if (valUrlResult !== true) {
155
+ connectionValidator.resetConnectionState(true);
152
156
  return valUrlResult;
153
157
  }
154
158
  const connectValResult = await (0, prompt_helpers_1.connectWithDestination)(selectedDestination, connectionValidator, requiredOdataVersion, servicePath);
package/dist/types.d.ts CHANGED
@@ -231,6 +231,13 @@ export type SystemSelectionPromptOptions = {
231
231
  * Note that there is no implementation for this option in this module and handling of the prompt optin and subsequent prompting must be implemented by the consumer.
232
232
  */
233
233
  includeCloudFoundryAbapEnvChoice?: boolean;
234
+ /**
235
+ * Provide a default choice for the system selection prompt, this is used to pre-select a system based on the system name.
236
+ * Set as string literal types `NewSystemChoice` or `CfAbapEnvServiceChoice` to specify the default choice to create a new system connection config in VSCode
237
+ * or to select the Cloud Foundry Abap environments service discovery choice in BAS respectively.
238
+ *
239
+ */
240
+ defaultChoice?: string;
234
241
  };
235
242
  export type MetadataPromptOptions = {
236
243
  /**
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": "0.6.8",
4
+ "version": "0.6.10",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -28,13 +28,13 @@
28
28
  "os-name": "4.0.1",
29
29
  "@sap-ux/axios-extension": "1.17.4",
30
30
  "@sap-ux/btp-utils": "0.17.0",
31
- "@sap-ux/fiori-generator-shared": "0.7.10",
32
31
  "@sap-ux/guided-answers-helper": "0.1.0",
33
- "@sap-ux/telemetry": "0.5.44",
32
+ "@sap-ux/fiori-generator-shared": "0.7.10",
34
33
  "@sap-ux/inquirer-common": "0.5.4",
35
- "@sap-ux/logger": "0.6.0",
36
34
  "@sap-ux/project-access": "1.28.7",
35
+ "@sap-ux/telemetry": "0.5.44",
37
36
  "@sap-ux/project-input-validator": "0.3.3",
37
+ "@sap-ux/logger": "0.6.0",
38
38
  "@sap-ux/store": "0.9.3"
39
39
  },
40
40
  "devDependencies": {
@@ -43,9 +43,9 @@
43
43
  "@types/inquirer": "8.2.6",
44
44
  "@types/lodash": "4.14.202",
45
45
  "jest-extended": "3.2.4",
46
- "@sap-ux/fiori-generator-shared": "0.7.10",
47
46
  "@sap-ux/feature-toggle": "0.2.2",
48
- "@sap-ux/odata-service-writer": "0.23.3"
47
+ "@sap-ux/odata-service-writer": "0.23.3",
48
+ "@sap-ux/fiori-generator-shared": "0.7.10"
49
49
  },
50
50
  "engines": {
51
51
  "node": ">=18.x"