@sap-ux/odata-service-inquirer 2.0.1 → 2.1.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.
@@ -29,6 +29,9 @@ function getSystemServiceQuestion(connectValidator, promptNamespace, promptOptio
29
29
  let previousSystemUrl;
30
30
  let previousClient;
31
31
  let previousService;
32
+ // State shared across validate and additionalMessages functions
33
+ let hasBackendAnnotations;
34
+ let convertedMetadata;
32
35
  const requiredOdataVersion = promptOptions?.requiredOdataVersion;
33
36
  const serviceSelectionPromptName = `${promptNamespace}:${types_1.promptNames.serviceSelection}`;
34
37
  let systemServiceQuestion = {
@@ -81,15 +84,16 @@ function getSystemServiceQuestion(connectValidator, promptNamespace, promptOptio
81
84
  }
82
85
  return serviceChoices;
83
86
  },
84
- additionalMessages: (selectedService) => {
85
- // Additional messages is executed after validation, so we can assume the PromptState has been updated
86
- let hasBackendAnnotations = false;
87
- if (selectedService && utils_1.PromptState.odataService.servicePath === selectedService.servicePath) {
88
- hasBackendAnnotations =
89
- !!utils_1.PromptState.odataService.annotations && utils_1.PromptState.odataService.annotations.length > 0;
90
- }
91
- return (0, service_helper_1.getSelectedServiceMessage)(serviceChoices, selectedService, connectValidator, requiredOdataVersion, hasBackendAnnotations);
92
- },
87
+ additionalMessages: (selectedService) => (0, service_helper_1.getSelectedServiceMessage)(serviceChoices, selectedService, connectValidator, {
88
+ requiredOdataVersion,
89
+ hasAnnotations: hasBackendAnnotations,
90
+ showCollabDraftWarnOptions: convertedMetadata
91
+ ? {
92
+ showCollabDraftWarning: !!promptOptions?.showCollaborativeDraftWarning,
93
+ edmx: convertedMetadata
94
+ }
95
+ : undefined
96
+ }),
93
97
  default: () => (0, utils_1.getDefaultChoiceIndex)(serviceChoices),
94
98
  // Warning: only executes in YUI and cli when automcomplete is used
95
99
  validate: async (service) => {
@@ -107,8 +111,13 @@ function getSystemServiceQuestion(connectValidator, promptNamespace, promptOptio
107
111
  }
108
112
  // Dont re-request the same service details
109
113
  if (serviceAnswer && previousService?.servicePath !== serviceAnswer.servicePath) {
114
+ hasBackendAnnotations = undefined;
115
+ convertedMetadata = undefined;
110
116
  previousService = serviceAnswer;
111
- return await (0, service_helper_1.getServiceDetails)(serviceAnswer, connectValidator, requiredOdataVersion);
117
+ const validationResult = await (0, service_helper_1.validateService)(serviceAnswer, connectValidator, requiredOdataVersion);
118
+ hasBackendAnnotations = validationResult.hasAnnotations;
119
+ convertedMetadata = validationResult.convertedMetadata;
120
+ return validationResult.validationResult;
112
121
  }
113
122
  return true;
114
123
  }
@@ -127,10 +136,10 @@ function getSystemServiceQuestion(connectValidator, promptNamespace, promptOptio
127
136
  when: async (answers) => {
128
137
  const selectedService = answers?.[`${promptNamespace}:${types_1.promptNames.serviceSelection}`];
129
138
  if (selectedService && connectValidator.validatedUrl) {
130
- const result = await (0, service_helper_1.getServiceDetails)(selectedService, connectValidator);
131
- if (typeof result === 'string') {
132
- logger_helper_1.default.logger.error(result);
133
- throw new Error(result);
139
+ const { validationResult } = await (0, service_helper_1.validateService)(selectedService, connectValidator);
140
+ if (typeof validationResult === 'string') {
141
+ logger_helper_1.default.logger.error(validationResult);
142
+ throw new Error(validationResult);
134
143
  }
135
144
  }
136
145
  if (serviceChoices.length === 0 && prompt_helpers_1.errorHandler.hasError()) {
@@ -5,6 +5,7 @@ import { OdataVersion } from '@sap-ux/odata-service-writer';
5
5
  import type { ListChoiceOptions } from 'inquirer';
6
6
  import type { ConnectionValidator } from '../../../connectionValidator';
7
7
  import type { ServiceAnswer } from './types';
8
+ import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
8
9
  export declare const telemEventBASServiceSuccess = "SERVICE_INQUIRER_BAS_SUCCESS";
9
10
  /**
10
11
  * Refines the error type and logs based on the specified options. This should log more precise error messages based on inputs
@@ -40,6 +41,11 @@ export declare function sendDestinationServiceSuccessTelemetryEvent(destination:
40
41
  * @returns service type
41
42
  */
42
43
  export declare function getServiceType(servicePath: string, serviceType: string | undefined, catalog: V2CatalogService): Promise<ServiceType | undefined>;
44
+ type ValidateServiceResult = {
45
+ validationResult: boolean | string;
46
+ hasAnnotations?: boolean;
47
+ convertedMetadata?: ConvertedMetadata;
48
+ };
43
49
  /**
44
50
  * Requests and sets the service details to the PromptState.odataService properties.
45
51
  * If an error occurs, the error message is returned for use in validators.
@@ -49,7 +55,7 @@ export declare function getServiceType(servicePath: string, serviceType: string
49
55
  * @param requiredOdataVersion the required OData version used to validate the service
50
56
  * @returns true if successful, setting the PromptState.odataService properties, or an error message indicating why the service details could not be retrieved.
51
57
  */
52
- export declare function getServiceDetails(service: ServiceAnswer, connectionValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion): Promise<string | boolean>;
58
+ export declare function validateService(service: ServiceAnswer, connectionValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion): Promise<ValidateServiceResult>;
53
59
  /**
54
60
  * Create a value for the service selection prompt message, which may include thge active connected user name.
55
61
  *
@@ -57,6 +63,10 @@ export declare function getServiceDetails(service: ServiceAnswer, connectionVali
57
63
  * @returns The service selection prompt message
58
64
  */
59
65
  export declare function getSelectedServiceLabel(username: string | undefined): string;
66
+ type ShowCollabDraftWarnOptions = {
67
+ edmx: ConvertedMetadata;
68
+ showCollabDraftWarning: boolean;
69
+ };
60
70
  /**
61
71
  * Get the service selection prompt additional message. This prompt will make an additional call to the system backend
62
72
  * to retrieve the service type and display a warning message if the service type is not UI.
@@ -64,9 +74,17 @@ export declare function getSelectedServiceLabel(username: string | undefined): s
64
74
  * @param serviceChoices a list of service choices
65
75
  * @param selectedService the selected service
66
76
  * @param connectValidator the connection validator
67
- * @param requiredOdataVersion the required OData version for the service
68
- * @param hasAnnotations used to determine whether to show a warning message that annotations could not be retrieved
77
+ * @param options additional options
78
+ * @param options.requiredOdataVersion the required OData version for the service
79
+ * @param options.hasAnnotations used to determine whether to show a warning message that annotations could not be retrieved
80
+ * @param options.showCollabDraftWarnOptions to show the collaborative draft warning, the option `showCollabDraftWarning` must be true
81
+ * and the edmx metadata must be provided
69
82
  * @returns the service selection prompt additional message
70
83
  */
71
- export declare function getSelectedServiceMessage(serviceChoices: ListChoiceOptions<ServiceAnswer>[], selectedService: ServiceAnswer, connectValidator: ConnectionValidator, requiredOdataVersion?: OdataVersion, hasAnnotations?: boolean): Promise<IMessageSeverity | undefined>;
84
+ export declare function getSelectedServiceMessage(serviceChoices: ListChoiceOptions<ServiceAnswer>[], selectedService: ServiceAnswer, connectValidator: ConnectionValidator, { requiredOdataVersion, hasAnnotations, showCollabDraftWarnOptions }: {
85
+ requiredOdataVersion?: OdataVersion;
86
+ hasAnnotations?: boolean;
87
+ showCollabDraftWarnOptions?: ShowCollabDraftWarnOptions;
88
+ }): Promise<IMessageSeverity | undefined>;
89
+ export {};
72
90
  //# sourceMappingURL=service-helper.d.ts.map
@@ -7,7 +7,7 @@ exports.telemEventBASServiceSuccess = void 0;
7
7
  exports.getServiceChoices = getServiceChoices;
8
8
  exports.sendDestinationServiceSuccessTelemetryEvent = sendDestinationServiceSuccessTelemetryEvent;
9
9
  exports.getServiceType = getServiceType;
10
- exports.getServiceDetails = getServiceDetails;
10
+ exports.validateService = validateService;
11
11
  exports.getSelectedServiceLabel = getSelectedServiceLabel;
12
12
  exports.getSelectedServiceMessage = getSelectedServiceMessage;
13
13
  const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
@@ -20,6 +20,7 @@ const utils_1 = require("../../../../utils");
20
20
  const logger_helper_1 = __importDefault(require("../../../logger-helper"));
21
21
  const prompt_helpers_1 = require("../../../prompt-helpers");
22
22
  const validators_1 = require("../../../validators");
23
+ const service_helpers_1 = require("../../service-helpers/service-helpers");
23
24
  // Service ids continaining these paths should not be offered as UI compatible services
24
25
  const nonUIServicePaths = ['/IWBEP/COMMON/'];
25
26
  // Telemetry event name for successful service validation on BAS, note: legacy event names should not be changed
@@ -192,11 +193,11 @@ async function getServiceType(servicePath, serviceType, catalog) {
192
193
  * @param requiredOdataVersion the required OData version used to validate the service
193
194
  * @returns true if successful, setting the PromptState.odataService properties, or an error message indicating why the service details could not be retrieved.
194
195
  */
195
- async function getServiceDetails(service, connectionValidator, requiredOdataVersion) {
196
+ async function validateService(service, connectionValidator, requiredOdataVersion) {
196
197
  const serviceCatalog = connectionValidator.catalogs?.[service.serviceODataVersion];
197
198
  if (!connectionValidator.serviceProvider) {
198
199
  logger_helper_1.default.logger.error('ConnectionValidator connection is not initialized');
199
- return false;
200
+ return { validationResult: false };
200
201
  }
201
202
  // We may already have an odata service endpoint connection
202
203
  let odataService = connectionValidator.odataService;
@@ -205,11 +206,11 @@ async function getServiceDetails(service, connectionValidator, requiredOdataVers
205
206
  }
206
207
  const serviceResult = await getServiceMetadata(service.servicePath, odataService, serviceCatalog);
207
208
  if (typeof serviceResult === 'string') {
208
- return serviceResult;
209
+ return { validationResult: serviceResult };
209
210
  }
210
- const { validationMsg, version } = (0, validators_1.validateODataVersion)(serviceResult.metadata, requiredOdataVersion);
211
+ const { validationMsg, version, convertedMetadata } = (0, validators_1.validateODataVersion)(serviceResult.metadata, requiredOdataVersion);
211
212
  if (validationMsg) {
212
- return validationMsg;
213
+ return { validationResult: validationMsg };
213
214
  }
214
215
  // If destinationUrl is available, use it, as validatedUrl may be in the form <protocal>:<destinationName>.dest
215
216
  const url = connectionValidator.destinationUrl ?? connectionValidator.validatedUrl;
@@ -224,7 +225,11 @@ async function getServiceDetails(service, connectionValidator, requiredOdataVers
224
225
  utils_1.PromptState.odataService.servicePath = service.servicePath;
225
226
  utils_1.PromptState.odataService.origin = origin;
226
227
  utils_1.PromptState.odataService.sapClient = connectionValidator.validatedClient;
227
- return true;
228
+ return {
229
+ validationResult: true,
230
+ hasAnnotations: !!utils_1.PromptState.odataService.annotations && utils_1.PromptState.odataService.annotations.length > 0,
231
+ convertedMetadata
232
+ };
228
233
  }
229
234
  /**
230
235
  * Create a value for the service selection prompt message, which may include thge active connected user name.
@@ -246,11 +251,14 @@ function getSelectedServiceLabel(username) {
246
251
  * @param serviceChoices a list of service choices
247
252
  * @param selectedService the selected service
248
253
  * @param connectValidator the connection validator
249
- * @param requiredOdataVersion the required OData version for the service
250
- * @param hasAnnotations used to determine whether to show a warning message that annotations could not be retrieved
254
+ * @param options additional options
255
+ * @param options.requiredOdataVersion the required OData version for the service
256
+ * @param options.hasAnnotations used to determine whether to show a warning message that annotations could not be retrieved
257
+ * @param options.showCollabDraftWarnOptions to show the collaborative draft warning, the option `showCollabDraftWarning` must be true
258
+ * and the edmx metadata must be provided
251
259
  * @returns the service selection prompt additional message
252
260
  */
253
- async function getSelectedServiceMessage(serviceChoices, selectedService, connectValidator, requiredOdataVersion, hasAnnotations = true) {
261
+ async function getSelectedServiceMessage(serviceChoices, selectedService, connectValidator, { requiredOdataVersion, hasAnnotations = true, showCollabDraftWarnOptions }) {
254
262
  if (serviceChoices?.length === 0) {
255
263
  if (requiredOdataVersion) {
256
264
  return {
@@ -279,6 +287,16 @@ async function getSelectedServiceMessage(serviceChoices, selectedService, connec
279
287
  }
280
288
  serviceType = await getServiceType(selectedService.servicePath, selectedService.serviceType, connectValidator.catalogs[axios_extension_1.ODataVersion.v2]);
281
289
  }
290
+ else if (showCollabDraftWarnOptions?.showCollabDraftWarning &&
291
+ selectedService.serviceODataVersion === axios_extension_1.ODataVersion.v4) {
292
+ const result = (0, service_helpers_1.showCollabDraftWarning)(showCollabDraftWarnOptions.edmx);
293
+ if (result) {
294
+ return {
295
+ message: (0, i18n_1.t)('prompts.warnings.collaborativeDraftMessage'),
296
+ severity: yeoman_ui_types_1.Severity.warning
297
+ };
298
+ }
299
+ }
282
300
  if (serviceType && serviceType !== axios_extension_1.ServiceType.UI) {
283
301
  return {
284
302
  message: (0, i18n_1.t)('prompts.warnings.nonUIServiceTypeWarningMessage', { serviceType: 'A2X' }),
@@ -0,0 +1,9 @@
1
+ import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
2
+ /**
3
+ * Determines if the collaborative draft warning should be shown.
4
+ *
5
+ * @param edmx metadata string or converted metadata can also be provided to prevent re-parsing
6
+ * @returns true if the warning should be shown
7
+ */
8
+ export declare function showCollabDraftWarning(edmx: string | ConvertedMetadata): boolean;
9
+ //# sourceMappingURL=service-helpers.d.ts.map
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.showCollabDraftWarning = showCollabDraftWarning;
7
+ const annotation_converter_1 = require("@sap-ux/annotation-converter");
8
+ const edmx_parser_1 = require("@sap-ux/edmx-parser");
9
+ const entity_helper_1 = require("../../edmx/entity-helper");
10
+ const logger_helper_1 = __importDefault(require("../../logger-helper"));
11
+ const i18n_1 = require("../../../i18n");
12
+ /**
13
+ * If any of the draft root annotated entity sets have the share action property, then collaborative draft is enabled.
14
+ *
15
+ * @param draftEnabledEntitySets entity sets with draft enabled property `HasDraftEntity`
16
+ * @returns
17
+ */
18
+ function hasCollaborativeDraft(draftEnabledEntitySets) {
19
+ const entitySetWithDraftRootAndShareAction = draftEnabledEntitySets.find((entitySet) => entitySet.annotations?.Common?.DraftRoot ? !!entitySet.annotations.Common.DraftRoot.ShareAction : false);
20
+ return !!entitySetWithDraftRootAndShareAction;
21
+ }
22
+ /**
23
+ * Determines if the collaborative draft warning should be shown.
24
+ *
25
+ * @param edmx metadata string or converted metadata can also be provided to prevent re-parsing
26
+ * @returns true if the warning should be shown
27
+ */
28
+ function showCollabDraftWarning(edmx) {
29
+ let showWarning = false;
30
+ try {
31
+ let convertedMetadata;
32
+ if (typeof edmx === 'string') {
33
+ convertedMetadata = (0, annotation_converter_1.convert)((0, edmx_parser_1.parse)(edmx));
34
+ }
35
+ else {
36
+ convertedMetadata = edmx;
37
+ }
38
+ const draftEnabledEntitySets = (0, entity_helper_1.filterDraftEnabledEntities)(convertedMetadata.entitySets) ?? [];
39
+ if (draftEnabledEntitySets?.length > 0) {
40
+ showWarning = !hasCollaborativeDraft(draftEnabledEntitySets);
41
+ }
42
+ }
43
+ catch (err) {
44
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.unparseableMetadata', { error: err.message }));
45
+ }
46
+ return showWarning;
47
+ }
48
+ //# sourceMappingURL=service-helpers.js.map
@@ -1,12 +1,10 @@
1
1
  import type { Question } from 'inquirer';
2
- import type { OdataServiceAnswers, OdataServicePromptOptions } from '../../../types';
2
+ import type { OdataServiceAnswers, OdataServiceUrlPromptOptions } from '../../../types';
3
3
  /**
4
4
  * Get the service URL questions.
5
5
  *
6
- * @param promptOptions prompt options that can be passed to the service URL questions to configure behaviour
7
- * @param promptOptions.serviceUrl see {@link OdataServicePromptOptions}
8
- * @param promptOptions.serviceUrlPassword see {@link OdataServicePromptOptions}
6
+ * @param serviceUrlPromptOptions Options used to control prompt behaviour, see {@link OdataServiceUrlPromptOptions} for details
9
7
  * @returns the odata service URL questions
10
8
  */
11
- export declare function getServiceUrlQuestions({ serviceUrl: serviceUrlOpts, serviceUrlPassword: passwordOpts }?: OdataServicePromptOptions): Question<OdataServiceAnswers>[];
9
+ export declare function getServiceUrlQuestions(serviceUrlPromptOptions?: OdataServiceUrlPromptOptions): Question<OdataServiceAnswers>[];
12
10
  //# sourceMappingURL=questions.d.ts.map
@@ -4,23 +4,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getServiceUrlQuestions = getServiceUrlQuestions;
7
+ const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
8
+ const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
7
9
  const inquirer_common_1 = require("@sap-ux/inquirer-common");
8
10
  const i18n_1 = require("../../../i18n");
9
11
  const types_1 = require("../../../types");
10
12
  const utils_1 = require("../../../utils");
11
13
  const connectionValidator_1 = require("../../connectionValidator");
12
14
  const logger_helper_1 = __importDefault(require("../../logger-helper"));
15
+ const service_helpers_1 = require("../service-helpers/service-helpers");
13
16
  const types_2 = require("./types");
14
17
  const validators_1 = require("./validators");
15
- const fiori_generator_shared_1 = require("@sap-ux/fiori-generator-shared");
16
18
  /**
17
19
  * Prompt for the service URL.
18
20
  *
19
21
  * @param connectValidator Connection validator instance
20
22
  * @param requiredVersion The required OData version of the service
23
+ * @param showCollabDraftWarn
21
24
  * @returns the service URL prompt
22
25
  */
23
- function getServiceUrlPrompt(connectValidator, requiredVersion) {
26
+ function getServiceUrlPrompt(connectValidator, requiredVersion, showCollabDraftWarn) {
27
+ let showAnnotationWarning = false;
28
+ let convertedMetadata;
24
29
  return {
25
30
  type: 'input',
26
31
  name: types_1.promptNames.serviceUrl,
@@ -31,6 +36,7 @@ function getServiceUrlPrompt(connectValidator, requiredVersion) {
31
36
  },
32
37
  message: (0, i18n_1.t)('prompts.odataServiceUrl.message', { odataVersion: requiredVersion }),
33
38
  validate: async (url) => {
39
+ showAnnotationWarning = false;
34
40
  const urlValidationState = await connectValidator.validateUrl(url);
35
41
  // Check if we have a cert error, the user will be prompted to ignore it later
36
42
  if (connectValidator.validity.canSkipCertError) {
@@ -38,25 +44,57 @@ function getServiceUrlPrompt(connectValidator, requiredVersion) {
38
44
  }
39
45
  if (urlValidationState === true) {
40
46
  if (!connectValidator.validity.authRequired && connectValidator.odataService) {
41
- return (0, validators_1.validateService)(url, {
47
+ showAnnotationWarning = false;
48
+ convertedMetadata = undefined;
49
+ const valResult = await (0, validators_1.validateService)(url, {
42
50
  odataService: connectValidator.odataService,
43
51
  axiosConfig: connectValidator.axiosConfig
44
52
  }, requiredVersion);
53
+ showAnnotationWarning = !!valResult.showAnnotationWarning;
54
+ convertedMetadata = valResult.convertedMetadata;
55
+ return valResult.validationResult;
45
56
  }
46
57
  return true;
47
58
  }
48
59
  return urlValidationState;
49
- }
60
+ },
61
+ additionalMessages: () => getAdditionalMessages(showAnnotationWarning, showCollabDraftWarn, convertedMetadata)
50
62
  };
51
63
  }
64
+ /**
65
+ * Get an additional message (IMessageSeverity) based on the specified parameters.
66
+ *
67
+ * @param showAnnotationWarning true to show annotation warning, this will take precedence over collaborative draft warning
68
+ * @param showCollabDraftWarn true to show collaborative draft warning, this will be shown only if `showAnnotationWarning` is false
69
+ * and determines that collaborative draft is not enabled
70
+ * @param convertedMetadata provided to avoid reparsing the metadata
71
+ * @returns
72
+ */
73
+ function getAdditionalMessages(showAnnotationWarning, showCollabDraftWarn, convertedMetadata) {
74
+ if (showAnnotationWarning) {
75
+ return {
76
+ message: (0, i18n_1.t)('prompts.warnings.noAnnotations'),
77
+ severity: yeoman_ui_types_1.Severity.warning
78
+ };
79
+ }
80
+ if (convertedMetadata && showCollabDraftWarn && (0, service_helpers_1.showCollabDraftWarning)(convertedMetadata)) {
81
+ return {
82
+ message: (0, i18n_1.t)('prompts.warnings.collaborativeDraftMessage'),
83
+ severity: yeoman_ui_types_1.Severity.warning
84
+ };
85
+ }
86
+ }
52
87
  /**
53
88
  * Prompt to ignore cert errors.
54
89
  *
55
90
  * @param connectValidator Connection validator instance
56
91
  * @param requiredVersion The required OData version of the service
92
+ * @param showCollabDraftWarn
57
93
  * @returns the ignore cert errors prompt
58
94
  */
59
- function getIgnoreCertErrorsPrompt(connectValidator, requiredVersion) {
95
+ function getIgnoreCertErrorsPrompt(connectValidator, requiredVersion, showCollabDraftWarn) {
96
+ let showAnnotationWarning = false;
97
+ let convertedMetadata;
60
98
  return {
61
99
  when: ({ serviceUrl }) => {
62
100
  if (serviceUrl && connectValidator.validity.canSkipCertError) {
@@ -69,6 +107,7 @@ function getIgnoreCertErrorsPrompt(connectValidator, requiredVersion) {
69
107
  message: (0, i18n_1.t)('prompts.ignoreCertErrors.message'),
70
108
  default: false,
71
109
  validate: async (ignoreCertError, { serviceUrl }) => {
110
+ showAnnotationWarning = false;
72
111
  if (!serviceUrl) {
73
112
  return false;
74
113
  }
@@ -81,15 +120,19 @@ function getIgnoreCertErrorsPrompt(connectValidator, requiredVersion) {
81
120
  });
82
121
  if (validUrl === true) {
83
122
  if (!connectValidator.validity.authRequired && connectValidator.odataService) {
84
- return (0, validators_1.validateService)(serviceUrl, {
123
+ const valResult = await (0, validators_1.validateService)(serviceUrl, {
85
124
  odataService: connectValidator.odataService,
86
125
  axiosConfig: connectValidator.axiosConfig
87
126
  }, requiredVersion, ignoreCertError);
127
+ showAnnotationWarning = !!valResult.showAnnotationWarning;
128
+ convertedMetadata = valResult.convertedMetadata;
129
+ return valResult.validationResult;
88
130
  }
89
131
  return true;
90
132
  }
91
133
  return validUrl;
92
- }
134
+ },
135
+ additionalMessages: () => getAdditionalMessages(showAnnotationWarning, showCollabDraftWarn, convertedMetadata)
93
136
  };
94
137
  }
95
138
  /**
@@ -122,12 +165,12 @@ function getCliIgnoreCertValidatePrompt(connectValidator, requiredVersion) {
122
165
  }
123
166
  if (!connectValidator.validity.authRequired && connectValidator.odataService) {
124
167
  // Will log on CLI
125
- const validService = await (0, validators_1.validateService)(serviceUrl, {
168
+ const { validationResult } = await (0, validators_1.validateService)(serviceUrl, {
126
169
  odataService: connectValidator.odataService,
127
170
  axiosConfig: connectValidator.axiosConfig
128
171
  }, requiredVersion, true);
129
- if (validService !== true) {
130
- throw new Error((0, i18n_1.t)('errors.exitingGeneration', { exitReason: validService.toString() }));
172
+ if (validationResult !== true) {
173
+ throw new Error((0, i18n_1.t)('errors.exitingGeneration', { exitReason: validationResult.toString() }));
131
174
  }
132
175
  }
133
176
  }
@@ -159,9 +202,12 @@ function getUsernamePrompt(connectValidator) {
159
202
  *
160
203
  * @param connectValidator Connection validator instance
161
204
  * @param requiredVersion The required OData version of the service
205
+ * @param showCollabDraftWarn
162
206
  * @returns the password prompt
163
207
  */
164
- function getPasswordPrompt(connectValidator, requiredVersion) {
208
+ function getPasswordPrompt(connectValidator, requiredVersion, showCollabDraftWarn) {
209
+ let showAnnotationWarning = false;
210
+ let convertedMetadata;
165
211
  return {
166
212
  when: () => (connectValidator.validity.reachable ? connectValidator.validity.authRequired === true : false),
167
213
  type: 'password',
@@ -182,43 +228,54 @@ function getPasswordPrompt(connectValidator, requiredVersion) {
182
228
  sapClient
183
229
  });
184
230
  if (validAuth === true && connectValidator.odataService) {
185
- return (0, validators_1.validateService)(serviceUrl, {
231
+ showAnnotationWarning = false;
232
+ convertedMetadata = undefined;
233
+ const valResult = await (0, validators_1.validateService)(serviceUrl, {
186
234
  odataService: connectValidator.odataService,
187
235
  axiosConfig: connectValidator.axiosConfig
188
236
  }, requiredVersion, ignoreCertError);
237
+ showAnnotationWarning = !!valResult.showAnnotationWarning;
238
+ convertedMetadata = valResult.convertedMetadata;
239
+ return valResult.validationResult;
189
240
  }
190
241
  return validAuth;
191
- }
242
+ },
243
+ additionalMessages: () => getAdditionalMessages(showAnnotationWarning, showCollabDraftWarn, convertedMetadata)
192
244
  };
193
245
  }
194
246
  /**
195
247
  * Get the service URL questions.
196
248
  *
197
- * @param promptOptions prompt options that can be passed to the service URL questions to configure behaviour
198
- * @param promptOptions.serviceUrl see {@link OdataServicePromptOptions}
199
- * @param promptOptions.serviceUrlPassword see {@link OdataServicePromptOptions}
249
+ * @param serviceUrlPromptOptions Options used to control prompt behaviour, see {@link OdataServiceUrlPromptOptions} for details
200
250
  * @returns the odata service URL questions
201
251
  */
202
- function getServiceUrlQuestions({ serviceUrl: serviceUrlOpts, serviceUrlPassword: passwordOpts } = {}) {
252
+ function getServiceUrlQuestions(serviceUrlPromptOptions = {}) {
203
253
  // Connection validator maintains connection state and validity across multiple prompts
204
254
  const connectValidator = new connectionValidator_1.ConnectionValidator();
205
- const requiredVersion = serviceUrlOpts?.requiredOdataVersion;
255
+ const requiredVersion = serviceUrlPromptOptions?.requiredOdataVersion;
206
256
  utils_1.PromptState.reset();
207
257
  let questions = [
208
- getServiceUrlPrompt(connectValidator, requiredVersion),
209
- getIgnoreCertErrorsPrompt(connectValidator, requiredVersion)
258
+ getServiceUrlPrompt(connectValidator, requiredVersion, serviceUrlPromptOptions?.showCollaborativeDraftWarning),
259
+ getIgnoreCertErrorsPrompt(connectValidator, requiredVersion, serviceUrlPromptOptions?.showCollaborativeDraftWarning)
210
260
  ];
211
261
  if ((0, utils_1.getPromptHostEnvironment)() === fiori_generator_shared_1.hostEnvironment.cli) {
212
262
  questions.push(getCliIgnoreCertValidatePrompt(connectValidator, requiredVersion));
213
263
  }
214
- questions.push(getUsernamePrompt(connectValidator), getPasswordPrompt(connectValidator, requiredVersion));
215
- // Add additional messages to prompts if specified in the prompt options
264
+ questions.push(getUsernamePrompt(connectValidator), getPasswordPrompt(connectValidator, requiredVersion, serviceUrlPromptOptions?.showCollaborativeDraftWarning));
265
+ // Add additional messages to prompts if specified in the prompt options.
266
+ // Note that the additional messages specified for the service URL prompt will also be added to the ignore cert errors prompt and password prompt
267
+ // this is to ensure that the messages are rendered in YUI regardless of authorization or cert prompts being displayed.
216
268
  let promptsOptToExtend = {};
217
- if (serviceUrlOpts?.additionalMessages) {
218
- promptsOptToExtend = { serviceUrl: serviceUrlOpts };
219
- }
220
- if (passwordOpts?.additionalMessages) {
221
- promptsOptToExtend = { ...promptsOptToExtend, serviceUrlPassword: passwordOpts };
269
+ if (serviceUrlPromptOptions?.additionalMessages) {
270
+ promptsOptToExtend = {
271
+ [types_1.promptNames.serviceUrl]: serviceUrlPromptOptions,
272
+ [types_1.promptNames.serviceUrlPassword]: {
273
+ additionalMessages: serviceUrlPromptOptions?.additionalMessages
274
+ },
275
+ [types_2.serviceUrlInternalPromptNames.ignoreCertError]: {
276
+ additionalMessages: serviceUrlPromptOptions?.additionalMessages
277
+ }
278
+ };
222
279
  }
223
280
  if (promptsOptToExtend) {
224
281
  questions = (0, inquirer_common_1.extendWithOptions)(questions, promptsOptToExtend, utils_1.PromptState.odataService);
@@ -1,5 +1,11 @@
1
1
  import { type AxiosRequestConfig, type ODataService } from '@sap-ux/axios-extension';
2
- import type { OdataVersion } from '@sap-ux/odata-service-writer';
2
+ import { OdataVersion } from '@sap-ux/odata-service-writer';
3
+ import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
4
+ type ValidateServiceUrlResult = {
5
+ validationResult: boolean | string;
6
+ showAnnotationWarning?: boolean;
7
+ convertedMetadata?: ConvertedMetadata;
8
+ };
3
9
  /**
4
10
  * Validates that a service specified by the service url is accessible, has the required version and returns valid metadata.
5
11
  * Retrieves annotations (from Abap backends) if available and stores them in the PromptState.
@@ -15,5 +21,6 @@ import type { OdataVersion } from '@sap-ux/odata-service-writer';
15
21
  export declare function validateService(url: string, { odataService, axiosConfig }: {
16
22
  odataService: ODataService;
17
23
  axiosConfig: AxiosRequestConfig;
18
- }, requiredVersion?: OdataVersion | undefined, ignoreCertError?: boolean): Promise<boolean | string>;
24
+ }, requiredVersion?: OdataVersion | undefined, ignoreCertError?: boolean): Promise<ValidateServiceUrlResult>;
25
+ export {};
19
26
  //# sourceMappingURL=validators.d.ts.map
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.validateService = validateService;
7
7
  const axios_extension_1 = require("@sap-ux/axios-extension");
8
8
  const inquirer_common_1 = require("@sap-ux/inquirer-common");
9
+ const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
9
10
  const i18n_1 = require("../../../i18n");
10
11
  const types_1 = require("../../../types");
11
12
  const utils_1 = require("../../../utils");
@@ -33,7 +34,9 @@ async function validateService(url, { odataService, axiosConfig }, requiredVersi
33
34
  const metadata = await odataService.metadata();
34
35
  const odataVersionValResult = (0, validators_1.validateODataVersion)(metadata, requiredVersion);
35
36
  if (odataVersionValResult.validationMsg) {
36
- return odataVersionValResult.validationMsg;
37
+ return {
38
+ validationResult: odataVersionValResult.validationMsg
39
+ };
37
40
  }
38
41
  const serviceOdataVersion = odataVersionValResult.version;
39
42
  // Remove all occurrences of the origin from the metadata to make backend uris relative
@@ -46,6 +49,7 @@ async function validateService(url, { odataService, axiosConfig }, requiredVersi
46
49
  utils_1.PromptState.odataService.servicePath = `${fullUrl.pathname}${fullUrl.search}`;
47
50
  utils_1.PromptState.odataService.origin = fullUrl.origin;
48
51
  utils_1.PromptState.odataService.sapClient = sapClient;
52
+ let showAnnotationWarning = false;
49
53
  // Best effort attempt to get annotations but dont throw an error if it fails as this may not even be an Abap system
50
54
  try {
51
55
  // Create an abap provider instance to get the annotations using the same request config
@@ -57,22 +61,34 @@ async function validateService(url, { odataService, axiosConfig }, requiredVersi
57
61
  logger_helper_1.default.logger.debug(`Annotations array of length: ${annotations?.length} returned`);
58
62
  if (annotations?.length === 0 || !annotations) {
59
63
  logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.annotationsNotFound'));
64
+ // Only show the warning if the service is v2, since these are backend annotations
65
+ showAnnotationWarning = odataVersionValResult.version === odata_service_writer_1.OdataVersion.v2;
60
66
  }
61
67
  utils_1.PromptState.odataService.annotations = annotations;
62
68
  }
63
69
  catch (err) {
64
70
  logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.annotationsNotFound'));
71
+ // Only show the warning if the service is v2, since these are backend annotations
72
+ showAnnotationWarning = odataVersionValResult.version === odata_service_writer_1.OdataVersion.v2;
65
73
  }
66
- return true;
74
+ return {
75
+ validationResult: true,
76
+ showAnnotationWarning,
77
+ convertedMetadata: odataVersionValResult.convertedMetadata
78
+ };
67
79
  }
68
80
  catch (error) {
69
81
  delete utils_1.PromptState.odataService.metadata;
70
82
  // Provide a more specific error message if the metadata service URL is not found
71
83
  if (inquirer_common_1.ErrorHandler.getErrorType(error) === inquirer_common_1.ERROR_TYPE.NOT_FOUND) {
72
84
  // No metadata implies not a valid odata service
73
- return inquirer_common_1.ErrorHandler.getErrorMsgFromType(inquirer_common_1.ERROR_TYPE.ODATA_URL_NOT_FOUND) ?? false;
85
+ return {
86
+ validationResult: inquirer_common_1.ErrorHandler.getErrorMsgFromType(inquirer_common_1.ERROR_TYPE.ODATA_URL_NOT_FOUND) ?? false
87
+ };
74
88
  }
75
- return prompt_helpers_1.errorHandler.logErrorMsgs(error);
89
+ return {
90
+ validationResult: prompt_helpers_1.errorHandler.logErrorMsgs(error)
91
+ };
76
92
  }
77
93
  finally {
78
94
  connectionValidator_1.ConnectionValidator.setGlobalRejectUnauthorized(true);
@@ -13,7 +13,7 @@ const utils_1 = require("../../utils");
13
13
  * @returns the matching `UI.selectionPresentationVariant` qualifers as prompt choices
14
14
  */
15
15
  function getQualifierChoices(annotations, entityType) {
16
- const qualifierChoices = [{ name: (0, i18n_1.t)('texts.choiceNameNone'), value: undefined }];
16
+ const qualifierChoices = [{ name: (0, i18n_1.t)('texts.choiceNameNone'), value: '' }];
17
17
  const parsedDefinitions = (0, utils_1.xmlToJson)(annotations?.Definitions) || {};
18
18
  const parsedAnnotations = parsedDefinitions.Edmx.DataServices.Schema?.Annotations;
19
19
  let filteredAnnotations = [];
@@ -56,11 +56,11 @@ function getQualifierChoices(annotations, entityType) {
56
56
  function getAnalyticListPageQuestions(odataVersion, annotations, hideTableLayoutPrompts = false) {
57
57
  const alpQuestions = [];
58
58
  if (annotations && odataVersion === odata_service_writer_1.OdataVersion.v2) {
59
- const qualifierChoices = [];
59
+ let qualifierChoices = [];
60
60
  alpQuestions.push({
61
61
  when: (answers) => {
62
62
  if (answers.mainEntity) {
63
- qualifierChoices.push(...getQualifierChoices(annotations, answers.mainEntity?.entitySetType));
63
+ qualifierChoices = getQualifierChoices(annotations, answers.mainEntity?.entitySetType);
64
64
  }
65
65
  return qualifierChoices.length > 1;
66
66
  },
@@ -1,5 +1,5 @@
1
1
  import { OdataVersion } from '@sap-ux/odata-service-writer';
2
- import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
2
+ import type { ConvertedMetadata, EntitySet } from '@sap-ux/vocabularies-types';
3
3
  import type { ListChoiceOptions } from 'inquirer';
4
4
  export type EntityAnswer = {
5
5
  entitySetName: string;
@@ -44,4 +44,11 @@ export declare function getEntityChoices(edmx: string, { useEntityTypeAsName, en
44
44
  * @returns the navigation entity choices
45
45
  */
46
46
  export declare function getNavigationEntityChoices(metadata: ConvertedMetadata, odataVersion: OdataVersion, mainEntityName: string): ListChoiceOptions<NavigationEntityAnswer>[];
47
+ /**
48
+ * Returns only entities that have a type property of 'HasDraftEnabled'.
49
+ *
50
+ * @param entitySets the entity sets to filter by draft enabled entities
51
+ * @returns the filtered entity sets
52
+ */
53
+ export declare function filterDraftEnabledEntities(entitySets: EntitySet[]): EntitySet[] | undefined;
47
54
  //# sourceMappingURL=entity-helper.d.ts.map
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getEntityChoices = getEntityChoices;
7
7
  exports.getNavigationEntityChoices = getNavigationEntityChoices;
8
+ exports.filterDraftEnabledEntities = filterDraftEnabledEntities;
8
9
  const annotation_converter_1 = require("@sap-ux/annotation-converter");
9
10
  const edmx_parser_1 = require("@sap-ux/edmx-parser");
10
11
  const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
@@ -51,7 +51,7 @@ async function getDatasourceTypeConditionalQuestions(promptOptions) {
51
51
  conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((await (0, system_selection_1.getSystemSelectionQuestions)(promptOptions)), (answers) => answers.datasourceType === types_1.DatasourceType.sapSystem));
52
52
  conditionalQuestions.push(...(0, inquirer_common_1.withCondition)([(0, metadata_file_1.getMetadataFileQuestion)(promptOptions?.metadataFilePath)], (answers) => answers.datasourceType === types_1.DatasourceType.metadataFile));
53
53
  conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((0, questions_1.getLocalCapProjectPrompts)(promptOptions), (answers) => answers.datasourceType === types_1.DatasourceType.capProject));
54
- conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((0, questions_2.getServiceUrlQuestions)(promptOptions), (answers) => answers.datasourceType === types_1.DatasourceType.odataServiceUrl));
54
+ conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((0, questions_2.getServiceUrlQuestions)(promptOptions?.serviceUrl), (answers) => answers.datasourceType === types_1.DatasourceType.odataServiceUrl));
55
55
  return conditionalQuestions;
56
56
  }
57
57
  //# sourceMappingURL=prompts.js.map
@@ -1,6 +1,9 @@
1
1
  import type { OdataVersion } from '@sap-ux/odata-service-writer';
2
+ import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
2
3
  /**
3
4
  * Validator function to verify if the specified metadata edmx version matches the specified required odata version.
5
+ * Note that this parses the edmx to determine the odata version and also returns the converted metadata as a side effect to
6
+ * avoid consumers having to parse the edmx again.
4
7
  *
5
8
  * @param edmx the edmx to validate
6
9
  * @param requiredVersion the required odata version to validate against
@@ -9,5 +12,6 @@ import type { OdataVersion } from '@sap-ux/odata-service-writer';
9
12
  export declare function validateODataVersion(edmx: string, requiredVersion?: OdataVersion): {
10
13
  validationMsg?: string;
11
14
  version?: OdataVersion;
15
+ convertedMetadata?: ConvertedMetadata;
12
16
  };
13
17
  //# sourceMappingURL=validators.d.ts.map
@@ -9,6 +9,8 @@ const logger_helper_1 = __importDefault(require("./logger-helper"));
9
9
  const utils_1 = require("../utils");
10
10
  /**
11
11
  * Validator function to verify if the specified metadata edmx version matches the specified required odata version.
12
+ * Note that this parses the edmx to determine the odata version and also returns the converted metadata as a side effect to
13
+ * avoid consumers having to parse the edmx again.
12
14
  *
13
15
  * @param edmx the edmx to validate
14
16
  * @param requiredVersion the required odata version to validate against
@@ -16,10 +18,10 @@ const utils_1 = require("../utils");
16
18
  */
17
19
  function validateODataVersion(edmx, requiredVersion) {
18
20
  try {
19
- const serviceOdataVersion = (0, utils_1.parseOdataVersion)(edmx);
20
- if (requiredVersion && requiredVersion !== serviceOdataVersion) {
21
+ const { convertedMetadata, odataVersion } = (0, utils_1.parseOdataVersion)(edmx);
22
+ if (requiredVersion && requiredVersion !== odataVersion) {
21
23
  const odataErrorMsg = (0, i18n_1.t)('prompts.validationMessages.odataVersionMismatch', {
22
- providedOdataVersion: serviceOdataVersion,
24
+ providedOdataVersion: odataVersion,
23
25
  requiredOdataVersion: requiredVersion
24
26
  });
25
27
  logger_helper_1.default.logger.error(odataErrorMsg);
@@ -28,7 +30,8 @@ function validateODataVersion(edmx, requiredVersion) {
28
30
  };
29
31
  }
30
32
  return {
31
- version: serviceOdataVersion
33
+ version: odataVersion,
34
+ convertedMetadata: convertedMetadata
32
35
  };
33
36
  }
34
37
  catch (err) {
@@ -64,7 +64,8 @@
64
64
  "nonUIServiceTypeWarningMessage": "Please note that {{serviceType}} services, or not classified services, are not intended to be used for the generation of SAP Fiori UI applications",
65
65
  "noServicesAvailable": "No services available for the selected system, see logs for further details.",
66
66
  "noServicesAvailableForOdataVersion": "There are no V{{odataVersion}} OData services available from the selected system and the template you have chosen supports V{{odataVersion}} OData services only",
67
- "noAnnotations": "No backend annotations associated with this service were retrieved and may result in an invalid application being created"
67
+ "noAnnotations": "No backend annotations associated with this service were retrieved and may result in an invalid application being created",
68
+ "collaborativeDraftMessage": "The selected service is draft enabled but does not support collaborative draft."
68
69
  },
69
70
  "systemUrl": {
70
71
  "message": "System URL",
package/dist/types.d.ts CHANGED
@@ -283,6 +283,11 @@ export type ServiceSelectionPromptOptions = {
283
283
  * If the service selection prompt is hidden then the odata service related answer properties will not be returned.
284
284
  */
285
285
  hide?: boolean;
286
+ /**
287
+ * If true, warn the user if the selected service has draft root annotated entity sets but does not have the share action property set.
288
+ * This is used to indicate that the service does not support collaborative draft.
289
+ */
290
+ showCollaborativeDraftWarning?: boolean;
286
291
  } & Pick<CommonPromptOptions, 'additionalMessages'>;
287
292
  export type SystemNamePromptOptions = {
288
293
  /**
@@ -296,12 +301,16 @@ export type OdataServiceUrlPromptOptions = {
296
301
  * Used to validate the service specified by the url is of the required odata version edmx
297
302
  */
298
303
  requiredOdataVersion?: OdataVersion;
304
+ /**
305
+ * If true, warn the user if the selected service has draft root annotated entity sets but does not have the share action property set.
306
+ * This is used to indicate that the service does not support collaborative draft.
307
+ */
308
+ showCollaborativeDraftWarning?: boolean;
299
309
  } & Pick<CommonPromptOptions, 'additionalMessages'>;
300
- export type OdataServiceUrlPasswordOptions = Pick<CommonPromptOptions, 'additionalMessages'>;
301
310
  /**
302
311
  * Provide the correct type checking for prompt options
303
312
  */
304
- type odataServiceInquirerPromptOptions = Record<promptNames.datasourceType, DatasourceTypePromptOptions> & Record<promptNames.metadataFilePath, MetadataPromptOptions> & Record<promptNames.capProject, CapProjectPromptOptions> & Record<promptNames.capService, CapServicePromptOptions> & Record<promptNames.serviceUrl, OdataServiceUrlPromptOptions> & Record<promptNames.serviceUrlPassword, OdataServiceUrlPasswordOptions> & Record<promptNames.serviceSelection, ServiceSelectionPromptOptions> & Record<promptNames.userSystemName, SystemNamePromptOptions> & Record<promptNames.systemSelection, SystemSelectionPromptOptions>;
313
+ type odataServiceInquirerPromptOptions = Record<promptNames.datasourceType, DatasourceTypePromptOptions> & Record<promptNames.metadataFilePath, MetadataPromptOptions> & Record<promptNames.capProject, CapProjectPromptOptions> & Record<promptNames.capService, CapServicePromptOptions> & Record<promptNames.serviceUrl, OdataServiceUrlPromptOptions> & Record<promptNames.serviceSelection, ServiceSelectionPromptOptions> & Record<promptNames.userSystemName, SystemNamePromptOptions> & Record<promptNames.systemSelection, SystemSelectionPromptOptions>;
305
314
  export type OdataServiceQuestion = YUIQuestion<OdataServiceAnswers>;
306
315
  export type OdataServicePromptOptions = Partial<odataServiceInquirerPromptOptions>;
307
316
  /**
@@ -3,6 +3,7 @@ import { type HostEnvironmentId } from '@sap-ux/fiori-generator-shared';
3
3
  import { OdataVersion } from '@sap-ux/odata-service-writer';
4
4
  import type { ListChoiceOptions } from 'inquirer';
5
5
  import { PromptState } from './prompt-state';
6
+ import type { ConvertedMetadata } from '@sap-ux/vocabularies-types';
6
7
  /**
7
8
  * Determine if the current prompting environment is cli or a hosted extension (app studio or vscode).
8
9
  *
@@ -16,9 +17,13 @@ export declare function getPromptHostEnvironment(): {
16
17
  * Validate xml and parse the odata version from the metadata xml.
17
18
  *
18
19
  * @param metadata a metadata string
19
- * @returns the odata version of the specified metadata, throws an error if the metadata is invalid
20
+ * @returns the odata version of the specified metadata, along with the converted metadata in case further processing may be required to avoid re-parsing.
21
+ * Throws an error if the metadata or odata version is invalid.
20
22
  */
21
- export declare function parseOdataVersion(metadata: string): OdataVersion;
23
+ export declare function parseOdataVersion(metadata: string): {
24
+ odataVersion: OdataVersion;
25
+ convertedMetadata: ConvertedMetadata;
26
+ };
22
27
  /**
23
28
  * Convert specified xml string to JSON.
24
29
  *
@@ -19,6 +19,8 @@ const i18n_1 = require("../i18n");
19
19
  const logger_helper_1 = __importDefault(require("../prompts/logger-helper"));
20
20
  const prompt_state_1 = require("./prompt-state");
21
21
  Object.defineProperty(exports, "PromptState", { enumerable: true, get: function () { return prompt_state_1.PromptState; } });
22
+ const annotation_converter_1 = require("@sap-ux/annotation-converter");
23
+ const edmx_parser_1 = require("@sap-ux/edmx-parser");
22
24
  /**
23
25
  * Determine if the current prompting environment is cli or a hosted extension (app studio or vscode).
24
26
  *
@@ -36,13 +38,23 @@ function getPromptHostEnvironment() {
36
38
  * Validate xml and parse the odata version from the metadata xml.
37
39
  *
38
40
  * @param metadata a metadata string
39
- * @returns the odata version of the specified metadata, throws an error if the metadata is invalid
41
+ * @returns the odata version of the specified metadata, along with the converted metadata in case further processing may be required to avoid re-parsing.
42
+ * Throws an error if the metadata or odata version is invalid.
40
43
  */
41
44
  function parseOdataVersion(metadata) {
42
45
  try {
43
- const parsed = xmlToJson(metadata);
44
- const odataVersion = parsed['Edmx']['Version'] === 1 ? odata_service_writer_1.OdataVersion.v2 : odata_service_writer_1.OdataVersion.v4;
45
- return odataVersion;
46
+ const convertedMetadata = (0, annotation_converter_1.convert)((0, edmx_parser_1.parse)(metadata));
47
+ const parsedOdataVersion = parseInt(convertedMetadata?.version, 10);
48
+ if (Number.isNaN(parsedOdataVersion)) {
49
+ logger_helper_1.default.logger.error((0, i18n_1.t)('errors.unparseableOdataVersion'));
50
+ throw new Error((0, i18n_1.t)('errors.unparseableOdataVersion'));
51
+ }
52
+ // Note that odata version > `4` e.g. `4.1`, is not currently supported by `@sap-ux/edmx-converter`
53
+ const odataVersion = parsedOdataVersion === 4 ? odata_service_writer_1.OdataVersion.v4 : odata_service_writer_1.OdataVersion.v2;
54
+ return {
55
+ odataVersion,
56
+ convertedMetadata
57
+ };
46
58
  }
47
59
  catch (error) {
48
60
  logger_helper_1.default.logger.error(error);
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.0.1",
4
+ "version": "2.1.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -33,7 +33,7 @@
33
33
  "@sap-ux/fiori-generator-shared": "0.7.22",
34
34
  "@sap-ux/guided-answers-helper": "0.2.1",
35
35
  "@sap-ux/telemetry": "0.5.54",
36
- "@sap-ux/inquirer-common": "0.6.8",
36
+ "@sap-ux/inquirer-common": "0.6.9",
37
37
  "@sap-ux/logger": "0.6.0",
38
38
  "@sap-ux/project-access": "1.29.2",
39
39
  "@sap-ux/project-input-validator": "0.3.4",