@sap-ux/odata-service-inquirer 0.2.3 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getServiceUrlQuestions = void 0;
16
+ const inquirer_common_1 = require("@sap-ux/inquirer-common");
17
+ const i18n_1 = require("../../../i18n");
18
+ const types_1 = require("../../../types");
19
+ const utils_1 = require("../../../utils");
20
+ const logger_helper_1 = __importDefault(require("../../logger-helper"));
21
+ const connectionValidator_1 = require("./connectionValidator");
22
+ const types_2 = require("./types");
23
+ const validators_1 = require("./validators");
24
+ /**
25
+ * Prompt for the service URL.
26
+ *
27
+ * @param connectValidator Connection validator instance
28
+ * @param requiredVersion The required OData version of the service
29
+ * @returns the service URL prompt
30
+ */
31
+ function getServiceUrlPrompt(connectValidator, requiredVersion) {
32
+ return {
33
+ type: 'input',
34
+ name: types_1.promptNames.serviceUrl,
35
+ guiOptions: {
36
+ hint: 'https://<hostname>:<port>/path/to/odata/service/',
37
+ mandatory: true,
38
+ breadcrumb: true
39
+ },
40
+ message: (0, i18n_1.t)('prompts.odataServiceUrl.message', { odataVersion: requiredVersion }),
41
+ validate: (url) => __awaiter(this, void 0, void 0, function* () {
42
+ const urlValidationState = yield connectValidator.validateUrl(url);
43
+ // Check if we have a cert error, the user will be prompted to ignore it later
44
+ if (connectValidator.validity.canSkipCertError) {
45
+ return true;
46
+ }
47
+ if (urlValidationState === true) {
48
+ if (!connectValidator.validity.authRequired) {
49
+ return (0, validators_1.validateService)(url, connectValidator, requiredVersion);
50
+ }
51
+ return true;
52
+ }
53
+ return urlValidationState;
54
+ })
55
+ };
56
+ }
57
+ /**
58
+ * Prompt to ignore cert errors.
59
+ *
60
+ * @param connectValidator Connection validator instance
61
+ * @param requiredVersion The required OData version of the service
62
+ * @returns the ignore cert errors prompt
63
+ */
64
+ function getIgnoreCertErrorsPrompt(connectValidator, requiredVersion) {
65
+ return {
66
+ when: ({ serviceUrl }) => {
67
+ if (serviceUrl && connectValidator.validity.canSkipCertError) {
68
+ return true;
69
+ }
70
+ return false;
71
+ },
72
+ type: 'confirm',
73
+ name: types_2.serviceUrlInternalPromptNames.ignoreCertError,
74
+ message: (0, i18n_1.t)('prompts.ignoreCertErrors.message'),
75
+ default: false,
76
+ validate: (ignoreCertError, { serviceUrl }) => __awaiter(this, void 0, void 0, function* () {
77
+ if (!serviceUrl) {
78
+ return false;
79
+ }
80
+ if (ignoreCertError) {
81
+ logger_helper_1.default.logger.warn((0, i18n_1.t)('prompts.validationMessages.warningCertificateValidationDisabled'));
82
+ }
83
+ const validUrl = yield connectValidator.validateUrl(serviceUrl, ignoreCertError, true);
84
+ if (validUrl === true) {
85
+ if (!connectValidator.validity.authRequired) {
86
+ return (0, validators_1.validateService)(serviceUrl, connectValidator, requiredVersion, ignoreCertError);
87
+ }
88
+ return true;
89
+ }
90
+ return validUrl;
91
+ })
92
+ };
93
+ }
94
+ /**
95
+ * Prompt used to validate the service based on ignoring cert errors since 'confirm' prompt validators don't run on CLI.
96
+ *
97
+ * @param connectValidator Connection validator instance
98
+ * @param requiredVersion The required OData version of the service
99
+ * @returns the ignore cert errors cli only prompt
100
+ */
101
+ function getCliIgnoreCertValidatePrompt(connectValidator, requiredVersion) {
102
+ return {
103
+ // Add dummy prompt for CLI to revalidate since "confirm" prompt validators don't run on CLI
104
+ // The `when` condition should never return true (so it does not get rendered in GUI prompts) but will throw an error to exit generation
105
+ // if the user chooses to not ignore cert errors or if the odata service is not valid
106
+ when: ({ serviceUrl, ignoreCertError }) => __awaiter(this, void 0, void 0, function* () {
107
+ if (serviceUrl && connectValidator.validity.canSkipCertError) {
108
+ // If the user choose to not ignore cert errors, we cannot continue
109
+ if (!ignoreCertError) {
110
+ throw new Error((0, i18n_1.t)('errors.exitingGeneration', { exitReason: (0, i18n_1.t)('errors.certValidationRequired') }));
111
+ }
112
+ // If the user choose to ignore cert errors, we need to re-validate
113
+ logger_helper_1.default.logger.warn((0, i18n_1.t)('prompts.validationMessages.warningCertificateValidationDisabled'));
114
+ // Re-check if auth required as the cert error would have prevented this check earlier
115
+ const validUrl = yield connectValidator.validateUrl(serviceUrl, ignoreCertError, true);
116
+ if (validUrl !== true) {
117
+ throw new Error(validUrl.toString()); // exit
118
+ }
119
+ if (!connectValidator.validity.authRequired) {
120
+ // Will log on CLI
121
+ const validService = yield (0, validators_1.validateService)(serviceUrl, connectValidator, requiredVersion, true);
122
+ if (validService !== true) {
123
+ throw new Error((0, i18n_1.t)('errors.exitingGeneration', { exitReason: validService.toString() }));
124
+ }
125
+ }
126
+ }
127
+ return false;
128
+ }),
129
+ name: types_2.serviceUrlInternalPromptNames.cliIgnoreCertValidate
130
+ };
131
+ }
132
+ /**
133
+ * Prompt for the username.
134
+ *
135
+ * @param connectValidator Connection validator instance
136
+ * @returns the username prompt
137
+ */
138
+ function getUsernamePrompt(connectValidator) {
139
+ return {
140
+ when: () => (connectValidator.validity.reachable ? connectValidator.validity.authRequired === true : false),
141
+ type: 'input',
142
+ name: types_2.serviceUrlInternalPromptNames.username,
143
+ message: (0, i18n_1.t)('prompts.serviceUsername.message'),
144
+ guiOptions: {
145
+ mandatory: true
146
+ },
147
+ validate: (user) => (user === null || user === void 0 ? void 0 : user.length) > 0
148
+ };
149
+ }
150
+ /**
151
+ * Prompt for the password.
152
+ *
153
+ * @param connectValidator Connection validator instance
154
+ * @param requiredVersion The required OData version of the service
155
+ * @returns the password prompt
156
+ */
157
+ function getPasswordPrompt(connectValidator, requiredVersion) {
158
+ return {
159
+ when: () => (connectValidator.validity.reachable ? connectValidator.validity.authRequired === true : false),
160
+ type: 'password',
161
+ guiOptions: {
162
+ applyDefaultWhenDirty: true,
163
+ mandatory: true
164
+ },
165
+ name: types_1.promptNames.serviceUrlPassword,
166
+ message: (0, i18n_1.t)('prompts.servicePassword.message'),
167
+ guiType: 'login',
168
+ mask: '*',
169
+ validate: (password, { username, serviceUrl, ignoreCertError }) => __awaiter(this, void 0, void 0, function* () {
170
+ if (!serviceUrl || !username || !password) {
171
+ return false;
172
+ }
173
+ const validAuth = yield connectValidator.validateAuth(serviceUrl, username, password, ignoreCertError);
174
+ if (validAuth === true) {
175
+ return (0, validators_1.validateService)(serviceUrl, connectValidator, requiredVersion, ignoreCertError);
176
+ }
177
+ return validAuth;
178
+ })
179
+ };
180
+ }
181
+ /**
182
+ * Get the service URL questions.
183
+ *
184
+ * @param promptOptions prompt options that can be passed to the service URL questions to configure behaviour
185
+ * @param promptOptions.serviceUrl see {@link OdataServicePromptOptions}
186
+ * @param promptOptions.serviceUrlPassword see {@link OdataServicePromptOptions}
187
+ * @returns the odata service URL questions
188
+ */
189
+ function getServiceUrlQuestions({ serviceUrl: serviceUrlOpts, serviceUrlPassword: passwordOpts } = {}) {
190
+ // Connection validator maintains connection state and validity across multiple prompts
191
+ const connectValidator = new connectionValidator_1.ConnectionValidator();
192
+ const requiredVersion = serviceUrlOpts === null || serviceUrlOpts === void 0 ? void 0 : serviceUrlOpts.requiredOdataVersion;
193
+ utils_1.PromptState.reset();
194
+ let questions = [
195
+ getServiceUrlPrompt(connectValidator, requiredVersion),
196
+ getIgnoreCertErrorsPrompt(connectValidator, requiredVersion)
197
+ ];
198
+ if ((0, utils_1.getHostEnvironment)() === types_1.hostEnvironment.cli) {
199
+ questions.push(getCliIgnoreCertValidatePrompt(connectValidator, requiredVersion));
200
+ }
201
+ questions.push(getUsernamePrompt(connectValidator), getPasswordPrompt(connectValidator, requiredVersion));
202
+ // Add additional messages to prompts if specified in the prompt options
203
+ let promptsOptToExtend = {};
204
+ if (serviceUrlOpts === null || serviceUrlOpts === void 0 ? void 0 : serviceUrlOpts.additionalMessages) {
205
+ promptsOptToExtend = { serviceUrl: serviceUrlOpts };
206
+ }
207
+ if (passwordOpts === null || passwordOpts === void 0 ? void 0 : passwordOpts.additionalMessages) {
208
+ promptsOptToExtend = Object.assign(Object.assign({}, promptsOptToExtend), { serviceUrlPassword: passwordOpts });
209
+ }
210
+ if (promptsOptToExtend) {
211
+ questions = (0, inquirer_common_1.extendWithOptions)(questions, promptsOptToExtend, utils_1.PromptState.odataService);
212
+ }
213
+ return questions;
214
+ }
215
+ exports.getServiceUrlQuestions = getServiceUrlQuestions;
216
+ //# sourceMappingURL=questions.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Enumeration of internal prompt names used internally and not supported for modification using OdataServiceInquirerPromptOptions
3
+ */
4
+ export declare enum serviceUrlInternalPromptNames {
5
+ ignoreCertError = "ignoreCertError",
6
+ username = "username",
7
+ cliIgnoreCertValidate = "cliIgnoreCertValidate"
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serviceUrlInternalPromptNames = void 0;
4
+ /**
5
+ * Enumeration of internal prompt names used internally and not supported for modification using OdataServiceInquirerPromptOptions
6
+ */
7
+ var serviceUrlInternalPromptNames;
8
+ (function (serviceUrlInternalPromptNames) {
9
+ serviceUrlInternalPromptNames["ignoreCertError"] = "ignoreCertError";
10
+ serviceUrlInternalPromptNames["username"] = "username";
11
+ serviceUrlInternalPromptNames["cliIgnoreCertValidate"] = "cliIgnoreCertValidate";
12
+ })(serviceUrlInternalPromptNames || (exports.serviceUrlInternalPromptNames = serviceUrlInternalPromptNames = {}));
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,19 @@
1
+ import { type AxiosRequestConfig, type ODataService } from '@sap-ux/axios-extension';
2
+ import type { OdataVersion } from '@sap-ux/odata-service-writer';
3
+ /**
4
+ * Validates that a service specified by the odata service is accessible, has the required version and returns valid metadata.
5
+ * Retrieves annotations (from Abap backends) if available and stores them in the PromptState.
6
+ *
7
+ * @param url the full odata service url including query parameters
8
+ * @param connectionConfig the connection configuration to use for the validation, a subset of the ConnectionValidator properties
9
+ * @param connectionConfig.odataService the odata service instance used to retrieve the metadata (as used by ConnectionValidator)
10
+ * @param connectionConfig.axiosConfig the axios config to use for the annotations request (as used by ConnectionValidator)
11
+ * @param requiredVersion if specified and the service odata version does not match this version, an error is returned
12
+ * @param ignoreCertError if true some certificate errors are ignored
13
+ * @returns true if a valid odata service was returned, false or an error message string otherwise
14
+ */
15
+ export declare function validateService(url: string, { odataService, axiosConfig }: {
16
+ odataService: ODataService;
17
+ axiosConfig: AxiosRequestConfig;
18
+ }, requiredVersion?: OdataVersion | undefined, ignoreCertError?: boolean): Promise<boolean | string>;
19
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.validateService = void 0;
16
+ const axios_extension_1 = require("@sap-ux/axios-extension");
17
+ const error_handler_1 = require("../../../error-handler/error-handler");
18
+ const i18n_1 = require("../../../i18n");
19
+ const types_1 = require("../../../types");
20
+ const utils_1 = require("../../../utils");
21
+ const logger_helper_1 = __importDefault(require("../../logger-helper"));
22
+ const prompt_helpers_1 = require("../../prompt-helpers");
23
+ const connectionValidator_1 = require("./connectionValidator");
24
+ /**
25
+ * Validates that a service specified by the odata service is accessible, has the required version and returns valid metadata.
26
+ * Retrieves annotations (from Abap backends) if available and stores them in the PromptState.
27
+ *
28
+ * @param url the full odata service url including query parameters
29
+ * @param connectionConfig the connection configuration to use for the validation, a subset of the ConnectionValidator properties
30
+ * @param connectionConfig.odataService the odata service instance used to retrieve the metadata (as used by ConnectionValidator)
31
+ * @param connectionConfig.axiosConfig the axios config to use for the annotations request (as used by ConnectionValidator)
32
+ * @param requiredVersion if specified and the service odata version does not match this version, an error is returned
33
+ * @param ignoreCertError if true some certificate errors are ignored
34
+ * @returns true if a valid odata service was returned, false or an error message string otherwise
35
+ */
36
+ function validateService(url, { odataService, axiosConfig }, requiredVersion = undefined, ignoreCertError = false) {
37
+ var _a, _b;
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ try {
40
+ if (ignoreCertError === true) {
41
+ connectionValidator_1.ConnectionValidator.setGlobalRejectUnauthorized(!ignoreCertError);
42
+ }
43
+ const metadata = yield odataService.metadata();
44
+ const serviceOdataVersion = (0, utils_1.parseOdataVersion)(metadata);
45
+ if (requiredVersion && requiredVersion !== serviceOdataVersion) {
46
+ return `${(0, i18n_1.t)('errors.odataServiceVersionMismatch', {
47
+ serviceVersion: serviceOdataVersion,
48
+ requiredVersion
49
+ })}`;
50
+ }
51
+ // Remove all occurrences of the origin from the metadata to make backend uris relative
52
+ utils_1.PromptState.odataService.metadata = (0, utils_1.originToRelative)(metadata);
53
+ utils_1.PromptState.odataService.odataVersion = serviceOdataVersion;
54
+ // Extract sap-client and keep the rest of the query params as part of the url
55
+ const fullUrl = new URL(url);
56
+ const sapClient = (_a = fullUrl.searchParams.get(types_1.SAP_CLIENT_KEY)) !== null && _a !== void 0 ? _a : undefined;
57
+ fullUrl.searchParams.delete(types_1.SAP_CLIENT_KEY);
58
+ utils_1.PromptState.odataService.servicePath = `${fullUrl.pathname}${fullUrl.search}`;
59
+ utils_1.PromptState.odataService.origin = fullUrl.origin;
60
+ utils_1.PromptState.odataService.sapClient = sapClient;
61
+ // Best effort attempt to get annotations but dont throw an error if it fails as this may not even be an Abap system
62
+ try {
63
+ // Create an abap provider instance to get the annotations using the same request config
64
+ const abapProvider = (0, axios_extension_1.createForAbap)(axiosConfig);
65
+ const catalogService = abapProvider.catalog(serviceOdataVersion);
66
+ logger_helper_1.default.attachAxiosLogger(catalogService.interceptors);
67
+ logger_helper_1.default.logger.debug('Getting annotations for service');
68
+ const annotations = yield catalogService.getAnnotations({ path: fullUrl.pathname });
69
+ logger_helper_1.default.logger.debug(`Annotations array of length: ${annotations === null || annotations === void 0 ? void 0 : annotations.length} returned`);
70
+ if ((annotations === null || annotations === void 0 ? void 0 : annotations.length) === 0 || !annotations) {
71
+ logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.annotationsNotFound'));
72
+ }
73
+ utils_1.PromptState.odataService.annotations = annotations;
74
+ }
75
+ catch (err) {
76
+ logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.annotationsNotFound'));
77
+ }
78
+ return true;
79
+ }
80
+ catch (error) {
81
+ delete utils_1.PromptState.odataService.metadata;
82
+ // Provide a more specific error message if the metadata service URL is not found
83
+ if (error_handler_1.ErrorHandler.getErrorType(error) === error_handler_1.ERROR_TYPE.NOT_FOUND) {
84
+ // No metadata implies not a valid odata service
85
+ return (_b = error_handler_1.ErrorHandler.getErrorMsgFromType(error_handler_1.ERROR_TYPE.ODATA_URL_NOT_FOUND)) !== null && _b !== void 0 ? _b : false;
86
+ }
87
+ return prompt_helpers_1.errorHandler.logErrorMsgs(error);
88
+ }
89
+ finally {
90
+ connectionValidator_1.ConnectionValidator.setGlobalRejectUnauthorized(true);
91
+ }
92
+ });
93
+ }
94
+ exports.validateService = validateService;
95
+ //# sourceMappingURL=validators.js.map
@@ -1,4 +1,5 @@
1
1
  import { type Logger } from '@sap-ux/logger';
2
+ import type { AxiosInterceptorManager, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
2
3
  /**
3
4
  * Static logger prevents passing of logger references through all functions, as this is a cross-cutting concern.
4
5
  */
@@ -16,5 +17,16 @@ export default class LoggerHelper {
16
17
  * @param value the logger to set
17
18
  */
18
19
  static set logger(value: Logger);
20
+ /**
21
+ * Attach the Axios logger to the request and response interceptors.
22
+ *
23
+ * @param interceptors the axios interceptors
24
+ * @param interceptors.request the axios request interceptor
25
+ * @param interceptors.response the axios response interceptor
26
+ */
27
+ static attachAxiosLogger(interceptors: {
28
+ request: AxiosInterceptorManager<InternalAxiosRequestConfig>;
29
+ response: AxiosInterceptorManager<AxiosResponse>;
30
+ }): void;
19
31
  }
20
32
  //# sourceMappingURL=logger-helper.d.ts.map
@@ -1,6 +1,30 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  const logger_1 = require("@sap-ux/logger");
27
+ const AxiosLogger = __importStar(require("axios-logger"));
4
28
  /**
5
29
  * Static logger prevents passing of logger references through all functions, as this is a cross-cutting concern.
6
30
  */
@@ -21,6 +45,41 @@ class LoggerHelper {
21
45
  static set logger(value) {
22
46
  LoggerHelper._logger = value;
23
47
  }
48
+ /**
49
+ * Attach the Axios logger to the request and response interceptors.
50
+ *
51
+ * @param interceptors the axios interceptors
52
+ * @param interceptors.request the axios request interceptor
53
+ * @param interceptors.response the axios response interceptor
54
+ */
55
+ static attachAxiosLogger(interceptors) {
56
+ interceptors.request.use((request) => {
57
+ return AxiosLogger.requestLogger(request, {
58
+ url: true,
59
+ data: true,
60
+ prefixText: '@sap-ux/odata-service-inquirer',
61
+ headers: true,
62
+ logger: LoggerHelper.logger.debug.bind(this)
63
+ });
64
+ }, (error) => {
65
+ return AxiosLogger.errorLogger(error, {
66
+ logger: LoggerHelper.logger.debug
67
+ });
68
+ });
69
+ interceptors.response.use((response) => {
70
+ return AxiosLogger.responseLogger(response, {
71
+ data: true,
72
+ prefixText: '@sap-ux/odata-service-inquirer',
73
+ status: true,
74
+ headers: true,
75
+ logger: LoggerHelper.logger.debug
76
+ });
77
+ }, (err) => {
78
+ return AxiosLogger.errorLogger(err, {
79
+ logger: LoggerHelper.logger.debug
80
+ });
81
+ });
82
+ }
24
83
  }
25
84
  LoggerHelper._logger = new logger_1.ToolsLogger({ logPrefix: '@sap-ux/odata-service-inquirer' });
26
85
  exports.default = LoggerHelper;
@@ -21,6 +21,7 @@ const metadata_file_1 = require("./datasources/metadata-file");
21
21
  const prompt_helpers_1 = require("./prompt-helpers");
22
22
  const questions_1 = require("./datasources/cap-project/questions");
23
23
  const logger_helper_1 = __importDefault(require("./logger-helper"));
24
+ const questions_2 = require("./datasources/service-url/questions");
24
25
  /**
25
26
  * Get the prompts for the OData service inquirer.
26
27
  *
@@ -91,6 +92,7 @@ function getDatasourceTypeConditionalQuestions(promptOptions) {
91
92
  const conditionalQuestions = [];
92
93
  conditionalQuestions.push(...(0, inquirer_common_1.withCondition)([(0, metadata_file_1.getMetadataFileQuestion)(promptOptions === null || promptOptions === void 0 ? void 0 : promptOptions.metadataFilePath)], (answers) => answers.datasourceType === types_1.DatasourceType.metadataFile));
93
94
  conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((0, questions_1.getLocalCapProjectPrompts)(promptOptions), (answers) => answers.datasourceType === types_1.DatasourceType.capProject));
95
+ conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((0, questions_2.getServiceUrlQuestions)(promptOptions), (answers) => answers.datasourceType === types_1.DatasourceType.odataServiceUrl));
94
96
  //...further data sources to be added here
95
97
  return conditionalQuestions;
96
98
  });
@@ -1,4 +1,4 @@
1
- import { OdataVersion } from '@sap-ux/odata-service-writer';
1
+ import type { OdataVersion } from '@sap-ux/odata-service-writer';
2
2
  /**
3
3
  * Validator function to verify if the specified metadata edmx version matches the specified required odata version.
4
4
  *
@@ -5,9 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.validateODataVersion = void 0;
7
7
  const i18n_1 = require("../i18n");
8
- const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
9
- const wing_service_explorer_1 = require("@sap/wing-service-explorer");
10
8
  const logger_helper_1 = __importDefault(require("./logger-helper"));
9
+ const utils_1 = require("../utils");
11
10
  /**
12
11
  * Validator function to verify if the specified metadata edmx version matches the specified required odata version.
13
12
  *
@@ -16,14 +15,11 @@ const logger_helper_1 = __importDefault(require("./logger-helper"));
16
15
  * @returns version and/or validation error message
17
16
  */
18
17
  function validateODataVersion(edmx, requiredVersion) {
19
- const metadataFactory = wing_service_explorer_1.MetadataFactory.getMetadataFactory();
20
18
  try {
21
- const explorer = metadataFactory.getMetadataExplorer(edmx);
22
- // Wing service explorer does not export the type of the protocol, so we need to check the string
23
- const version = explorer.getProtocolType().indexOf('v4') > 0 ? odata_service_writer_1.OdataVersion.v4 : odata_service_writer_1.OdataVersion.v2;
24
- if (requiredVersion && requiredVersion !== version) {
19
+ const serviceOdataVersion = (0, utils_1.parseOdataVersion)(edmx);
20
+ if (requiredVersion && requiredVersion !== serviceOdataVersion) {
25
21
  const odataErrorMsg = (0, i18n_1.t)('prompts.validationMessages.odataVersionMismatch', {
26
- providedOdataVersion: version,
22
+ providedOdataVersion: serviceOdataVersion,
27
23
  requiredOdataVersion: requiredVersion
28
24
  });
29
25
  logger_helper_1.default.logger.error(odataErrorMsg);
@@ -32,12 +28,12 @@ function validateODataVersion(edmx, requiredVersion) {
32
28
  };
33
29
  }
34
30
  return {
35
- version
31
+ version: serviceOdataVersion
36
32
  };
37
33
  }
38
34
  catch (err) {
39
35
  return {
40
- validationMsg: (0, i18n_1.t)('prompts.validationMessages.metadataInvalid')
36
+ validationMsg: err.message
41
37
  };
42
38
  }
43
39
  }
@@ -40,11 +40,25 @@
40
40
  "breadcrumb": "CAP Service",
41
41
  "enterCapPathChoiceName": "Manually select CAP service folder path"
42
42
  },
43
+ "odataServiceUrl": {
44
+ "message": "OData{{odataVersion, odataVersionFormatter}} service URL"
45
+ },
46
+ "ignoreCertErrors": {
47
+ "message": "Do you want to continue generation with the untrusted certificate?"
48
+ },
49
+ "serviceUsername": {
50
+ "message": "Service username"
51
+ },
52
+ "servicePassword": {
53
+ "message": "Service password"
54
+ },
43
55
  "validationMessages": {
44
56
  "odataVersionMismatch": "The template you have chosen supports V{{requiredOdataVersion}} OData services only. The provided version is V{{providedOdataVersion}}.",
45
57
  "metadataInvalid": "The service metadata is invalid.",
46
58
  "metadataFilePathNotValid": "Metadata file does not exist or is not accessible. Please specify a valid file path.",
47
- "capProjectNotFound": "The folder you have selected does not seem to contain a valid CAP project. Please check and try again."
59
+ "capProjectNotFound": "The folder you have selected does not seem to contain a valid CAP project. Please check and try again.",
60
+ "warningCertificateValidationDisabled": "User has disabled certificate validation",
61
+ "annotationsNotFound": "Annotations not found for specified service"
48
62
  },
49
63
  "nonUIServiceTypeWarningMessage": "Please note that {{serviceTypeDesc}} services are not intended to be used for the generation of SAP Fiori UI applications"
50
64
  },
@@ -65,13 +79,20 @@
65
79
  "internalServerError": "The URL you have provided cannot be accessed and is returning: '{{- error}}'. Please ensure that the URL is accessible externally.",
66
80
  "urlNotFound": "URL not found",
67
81
  "odataServiceUrlNotFound": "The service URL you have provided is not a valid OData Service. Fiori applications require an OData service as the data source.",
82
+ "badGateway": "The server returned an error: bad gateway, please check the URL and try again.",
68
83
  "destinationUnavailable": "The selected destination references an instance that is not available. Please check your destination configuration and try again.",
69
84
  "destinationNotFound": "The destination is mis-configured, HTTP Error 404 returned, the requested resource could not be found.",
70
85
  "destinationMisconfigured": "The destination is mis-configured, HTML5.DynamicDestination property is missing.",
71
86
  "noServicesAvailable": "There are no V{{version}} OData services available from the selected system and the template you have chosen supports V{{version}} OData services only",
72
87
  "redirectError": "A redirect response was received from the server",
73
88
  "abapEnvsUnavailable": "ABAP environments unavailable",
74
- "noSuchHostError": "No such host is known"
89
+ "noSuchHostError": "No such host is known",
90
+ "odataServiceVersionMismatch": "The template you have chosen supports V{{requiredVersion}} OData services only. The provided version is V{{serviceVersion}}.",
91
+ "destinationAuthError": "The selected system is returning an authentication error. Please verify the destination configuration",
92
+ "serviceUrlNotFound": "Please verify the service url: {{- url}}, target system configuration and network connectivity",
93
+ "urlRedirect": "The service URL is redirecting",
94
+ "certValidationRequired": "Certificate validation is required to continue.",
95
+ "exitingGeneration": "Exiting generation. {{exitReason}}"
75
96
  },
76
97
  "texts": {
77
98
  "anExpiredCert": "an expired",
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { IValidationLink } from '@sap-devx/yeoman-ui-types';
2
- import type { YUIQuestion } from '@sap-ux/inquirer-common';
2
+ import type { Annotations } from '@sap-ux/axios-extension';
3
+ import type { CommonPromptOptions, YUIQuestion } from '@sap-ux/inquirer-common';
3
4
  import type { OdataVersion } from '@sap-ux/odata-service-writer';
4
5
  import type { CdsVersionInfo } from '@sap-ux/project-access';
5
6
  import type { ListChoiceOptions } from 'inquirer';
@@ -28,6 +29,10 @@ export interface OdataServiceAnswers {
28
29
  * The odata service metadata (edmx) document.
29
30
  */
30
31
  metadata?: string;
32
+ /**
33
+ * The annotations document for the service.
34
+ */
35
+ annotations?: Annotations[];
31
36
  /**
32
37
  * The selected CAP service.
33
38
  */
@@ -37,9 +42,25 @@ export interface OdataServiceAnswers {
37
42
  */
38
43
  odataVersion?: OdataVersion;
39
44
  /**
40
- * The relative path of the selected service.
45
+ * The url origin (scheme, domain and port) of the service.
46
+ */
47
+ origin?: string;
48
+ /**
49
+ * The relative url path of the selected service. This coupled with the origin forms the full service url.
41
50
  */
42
51
  servicePath?: string;
52
+ /**
53
+ * The 'sap-client' value for the service.
54
+ */
55
+ sapClient?: string;
56
+ /**
57
+ * User name for the service where basic authentication is required.
58
+ */
59
+ username?: string;
60
+ /**
61
+ * Password for the service where basic authentication is required.
62
+ */
63
+ password?: string;
43
64
  /**
44
65
  * Metadata file path
45
66
  */
@@ -64,7 +85,15 @@ export declare enum promptNames {
64
85
  /**
65
86
  * Cap service
66
87
  */
67
- capService = "capService"
88
+ capService = "capService",
89
+ /**
90
+ * Odata service URL
91
+ */
92
+ serviceUrl = "serviceUrl",
93
+ /**
94
+ * password
95
+ */
96
+ serviceUrlPassword = "serviceUrlPassword"
68
97
  }
69
98
  export type CapRuntime = 'Node.js' | 'Java';
70
99
  export interface CapService {
@@ -137,10 +166,17 @@ export type MetadataPromptOptions = {
137
166
  */
138
167
  requiredOdataVersion?: OdataVersion;
139
168
  };
169
+ export type OdataServiceUrlPromptOptions = {
170
+ /**
171
+ * Used to validate the service specified by the url is of the required odata version edmx
172
+ */
173
+ requiredOdataVersion?: OdataVersion;
174
+ } & Pick<CommonPromptOptions, 'additionalMessages'>;
175
+ export type OdataServiceUrlPasswordOptions = Pick<CommonPromptOptions, 'additionalMessages'>;
140
176
  /**
141
- * Provide the correct type checking for object value prompt options
177
+ * Provide the correct type checking for prompt options
142
178
  */
143
- type odataServiceInquirerPromptOptions = Record<promptNames.datasourceType, DatasourceTypePromptOptions> & Record<promptNames.metadataFilePath, MetadataPromptOptions> & Record<promptNames.capProject, CapProjectPromptOptions> & Record<promptNames.capService, CapServicePromptOptions>;
179
+ 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>;
144
180
  export type OdataServiceQuestion = YUIQuestion<OdataServiceAnswers>;
145
181
  export type OdataServicePromptOptions = Partial<odataServiceInquirerPromptOptions>;
146
182
  /**
@@ -177,5 +213,6 @@ export declare const hostEnvironment: {
177
213
  technical: string;
178
214
  };
179
215
  };
216
+ export declare const SAP_CLIENT_KEY = "sap-client";
180
217
  export {};
181
218
  //# sourceMappingURL=types.d.ts.map