@sap-ux/odata-service-inquirer 0.3.11 → 0.4.2
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/error-handler/error-handler.js +108 -109
- package/dist/i18n.js +12 -23
- package/dist/index.js +20 -33
- package/dist/prompts/datasources/cap-project/cap-helpers.js +87 -127
- package/dist/prompts/datasources/cap-project/questions.js +29 -42
- package/dist/prompts/datasources/cap-project/validators.js +9 -20
- package/dist/prompts/datasources/metadata-file/index.js +3 -12
- package/dist/prompts/datasources/metadata-file/validators.js +4 -13
- package/dist/prompts/datasources/service-url/connectionValidator.js +93 -111
- package/dist/prompts/datasources/service-url/questions.js +18 -27
- package/dist/prompts/datasources/service-url/validators.js +48 -60
- package/dist/prompts/logger-helper.js +1 -1
- package/dist/prompts/prompts.js +14 -29
- package/dist/types.js +3 -0
- package/dist/utils/prompt-state.js +2 -2
- package/package.json +9 -9
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -29,9 +20,10 @@ const ignorableCertErrors = [error_handler_1.ERROR_TYPE.CERT_SELF_SIGNED, error_
|
|
|
29
20
|
*
|
|
30
21
|
*/
|
|
31
22
|
class ConnectionValidator {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
validity = {};
|
|
24
|
+
_validatedUrl;
|
|
25
|
+
_odataService;
|
|
26
|
+
_axiosConfig;
|
|
35
27
|
/**
|
|
36
28
|
* Getter for the axios configuration.
|
|
37
29
|
*
|
|
@@ -57,58 +49,55 @@ class ConnectionValidator {
|
|
|
57
49
|
* @param [ignoreCertError] optional, ignore some certificate errors
|
|
58
50
|
* @returns the status code or error returned by the connection attempt
|
|
59
51
|
*/
|
|
60
|
-
checkSapService(url, username, password, ignoreCertError = false) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (isBAS) {
|
|
73
|
-
url.searchParams.append('saml2', 'disabled');
|
|
74
|
-
}
|
|
75
|
-
let axiosConfig = {
|
|
76
|
-
params: url.searchParams,
|
|
77
|
-
ignoreCertErrors: ignoreCertError,
|
|
78
|
-
cookies: ''
|
|
79
|
-
};
|
|
80
|
-
if (username && password) {
|
|
81
|
-
axiosConfig = Object.assign(axiosConfig, {
|
|
82
|
-
auth: {
|
|
83
|
-
username,
|
|
84
|
-
password
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
this._axiosConfig = axiosConfig;
|
|
89
|
-
this._odataService = (0, axios_extension_1.createServiceForUrl)(url.origin + url.pathname, this._axiosConfig);
|
|
90
|
-
logger_helper_1.default.attachAxiosLogger(this._odataService.interceptors);
|
|
91
|
-
yield this._odataService.get('');
|
|
92
|
-
return 200;
|
|
52
|
+
async checkSapService(url, username, password, ignoreCertError = false) {
|
|
53
|
+
const isBAS = (0, btp_utils_1.isAppStudio)();
|
|
54
|
+
try {
|
|
55
|
+
// Auto add trailing '/' to path
|
|
56
|
+
url.pathname = !url.pathname?.endsWith('/') ? `${url.pathname}/` : url.pathname;
|
|
57
|
+
// VSCode default extension proxy setting does not allow bypassing cert errors using httpsAgent (as used by Axios)
|
|
58
|
+
// so we must use globalAgent to bypass cert validation
|
|
59
|
+
if (ignoreCertError === true) {
|
|
60
|
+
ConnectionValidator.setGlobalRejectUnauthorized(!ignoreCertError);
|
|
61
|
+
}
|
|
62
|
+
if (isBAS) {
|
|
63
|
+
url.searchParams.append('saml2', 'disabled');
|
|
93
64
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
65
|
+
let axiosConfig = {
|
|
66
|
+
params: url.searchParams,
|
|
67
|
+
ignoreCertErrors: ignoreCertError,
|
|
68
|
+
cookies: ''
|
|
69
|
+
};
|
|
70
|
+
if (username && password) {
|
|
71
|
+
axiosConfig = Object.assign(axiosConfig, {
|
|
72
|
+
auth: {
|
|
73
|
+
username,
|
|
74
|
+
password
|
|
100
75
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
this._axiosConfig = axiosConfig;
|
|
79
|
+
this._odataService = (0, axios_extension_1.createServiceForUrl)(url.origin + url.pathname, this._axiosConfig);
|
|
80
|
+
logger_helper_1.default.attachAxiosLogger(this._odataService.interceptors);
|
|
81
|
+
await this._odataService.get('');
|
|
82
|
+
return 200;
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
logger_helper_1.default.logger.debug(`ConnectionValidator.checkSapService() - error: ${e.message}`);
|
|
86
|
+
if (e?.isAxiosError) {
|
|
87
|
+
// Only throw for 500 on App Studio
|
|
88
|
+
if (e?.response?.status === 500 && isBAS) {
|
|
104
89
|
throw e;
|
|
105
90
|
}
|
|
91
|
+
return e?.response?.status || e?.code;
|
|
106
92
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
ConnectionValidator.setGlobalRejectUnauthorized(true);
|
|
93
|
+
else {
|
|
94
|
+
throw e;
|
|
110
95
|
}
|
|
111
|
-
}
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
// Reset global cert validation
|
|
99
|
+
ConnectionValidator.setGlobalRejectUnauthorized(true);
|
|
100
|
+
}
|
|
112
101
|
}
|
|
113
102
|
/**
|
|
114
103
|
* Validates the service url format as well as its reachability.
|
|
@@ -118,39 +107,36 @@ class ConnectionValidator {
|
|
|
118
107
|
* @param forceReValidation force re-validation of the url
|
|
119
108
|
* @returns true if the url is reachable, false if not, or an error message string
|
|
120
109
|
*/
|
|
121
|
-
validateUrl(serviceUrl, ignoreCertError = false, forceReValidation = false) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
110
|
+
async validateUrl(serviceUrl, ignoreCertError = false, forceReValidation = false) {
|
|
111
|
+
if (this.isEmptyString(serviceUrl)) {
|
|
112
|
+
this.resetValidity();
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const url = new URL(serviceUrl);
|
|
117
|
+
if (!forceReValidation && this.isUrlValidated(serviceUrl)) {
|
|
118
|
+
return this.validity.reachable ?? false;
|
|
127
119
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (!forceReValidation && this.isUrlValidated(serviceUrl)) {
|
|
131
|
-
return (_a = this.validity.reachable) !== null && _a !== void 0 ? _a : false;
|
|
132
|
-
}
|
|
133
|
-
if (url.origin === 'null') {
|
|
134
|
-
return (0, i18n_1.t)('errors.invalidUrl');
|
|
135
|
-
}
|
|
136
|
-
// Ignore path if a system url
|
|
137
|
-
const status = yield this.checkSapService(url, undefined, undefined, ignoreCertError);
|
|
138
|
-
logger_helper_1.default.logger.debug(`ConnectionValidator.validateUrl() - status: ${status}; url: ${serviceUrl}`);
|
|
139
|
-
this.validity.urlFormat = true;
|
|
140
|
-
this._validatedUrl = serviceUrl;
|
|
141
|
-
return this.getValidationResultFromStatusCode(status);
|
|
120
|
+
if (url.origin === 'null') {
|
|
121
|
+
return (0, i18n_1.t)('errors.invalidUrl');
|
|
142
122
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
123
|
+
// Ignore path if a system url
|
|
124
|
+
const status = await this.checkSapService(url, undefined, undefined, ignoreCertError);
|
|
125
|
+
logger_helper_1.default.logger.debug(`ConnectionValidator.validateUrl() - status: ${status}; url: ${serviceUrl}`);
|
|
126
|
+
this.validity.urlFormat = true;
|
|
127
|
+
this._validatedUrl = serviceUrl;
|
|
128
|
+
return this.getValidationResultFromStatusCode(status);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
// More helpful context specific error
|
|
132
|
+
if (error_handler_1.ErrorHandler.getErrorType(error) === error_handler_1.ERROR_TYPE.CONNECTION) {
|
|
133
|
+
this.validity.reachable = false;
|
|
134
|
+
return prompt_helpers_1.errorHandler.logErrorMsgs((0, i18n_1.t)('errors.serviceUrlNotFound', { url: serviceUrl }));
|
|
152
135
|
}
|
|
153
|
-
|
|
136
|
+
this.resetValidity();
|
|
137
|
+
const errorMsg = prompt_helpers_1.errorHandler.getErrorMsg(error);
|
|
138
|
+
return errorMsg ?? (0, i18n_1.t)('errors.invalidUrl');
|
|
139
|
+
}
|
|
154
140
|
}
|
|
155
141
|
/**
|
|
156
142
|
* Translate the status code into a validation result.
|
|
@@ -160,19 +146,18 @@ class ConnectionValidator {
|
|
|
160
146
|
* @returns
|
|
161
147
|
*/
|
|
162
148
|
getValidationResultFromStatusCode(status) {
|
|
163
|
-
var _a, _b, _c;
|
|
164
149
|
if (status === 200) {
|
|
165
150
|
this.validity.authenticated = true;
|
|
166
151
|
this.validity.authRequired = false;
|
|
167
152
|
}
|
|
168
153
|
else if (status === 404) {
|
|
169
154
|
this.validity.reachable = false;
|
|
170
|
-
return
|
|
155
|
+
return error_handler_1.ErrorHandler.getErrorMsgFromType(error_handler_1.ERROR_TYPE.NOT_FOUND) ?? false;
|
|
171
156
|
}
|
|
172
157
|
else if (error_handler_1.ErrorHandler.isCertError(status)) {
|
|
173
158
|
this.validity.reachable = true;
|
|
174
159
|
this.validity.canSkipCertError = ignorableCertErrors.includes(error_handler_1.ErrorHandler.getErrorType(status));
|
|
175
|
-
return
|
|
160
|
+
return prompt_helpers_1.errorHandler.getValidationErrorHelp(status, false) ?? false;
|
|
176
161
|
}
|
|
177
162
|
else if (error_handler_1.ErrorHandler.getErrorType(status) === error_handler_1.ERROR_TYPE.AUTH) {
|
|
178
163
|
this.validity.reachable = true;
|
|
@@ -184,7 +169,7 @@ class ConnectionValidator {
|
|
|
184
169
|
}
|
|
185
170
|
else if (status !== 404) {
|
|
186
171
|
this.validity.reachable = false;
|
|
187
|
-
return
|
|
172
|
+
return error_handler_1.ErrorHandler.getErrorMsgFromType(error_handler_1.ERROR_TYPE.CONNECTION, `http code: ${status}`) ?? false;
|
|
188
173
|
}
|
|
189
174
|
this.validity.reachable = true;
|
|
190
175
|
return true;
|
|
@@ -220,25 +205,22 @@ class ConnectionValidator {
|
|
|
220
205
|
* @param ignoreCertError optional, ignore some certificate errors
|
|
221
206
|
* @returns true if the authentication is successful, false if not, or an error message string
|
|
222
207
|
*/
|
|
223
|
-
validateAuth(serviceUrl, username, password, ignoreCertError = false) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return (_a = prompt_helpers_1.errorHandler.getErrorMsg(error)) !== null && _a !== void 0 ? _a : false;
|
|
240
|
-
}
|
|
241
|
-
});
|
|
208
|
+
async validateAuth(serviceUrl, username, password, ignoreCertError = false) {
|
|
209
|
+
if (!serviceUrl) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (!this.validity.reachable) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
const url = new URL(serviceUrl);
|
|
217
|
+
this.validity.authenticated =
|
|
218
|
+
(await this.checkSapService(url, username, password, ignoreCertError)) === 200;
|
|
219
|
+
return this.validity.authenticated === true ? true : (0, i18n_1.t)('errors.authenticationFailed');
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
return prompt_helpers_1.errorHandler.getErrorMsg(error) ?? false;
|
|
223
|
+
}
|
|
242
224
|
}
|
|
243
225
|
/**
|
|
244
226
|
* Reset the validity state.
|
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -38,8 +29,8 @@ function getServiceUrlPrompt(connectValidator, requiredVersion) {
|
|
|
38
29
|
breadcrumb: true
|
|
39
30
|
},
|
|
40
31
|
message: (0, i18n_1.t)('prompts.odataServiceUrl.message', { odataVersion: requiredVersion }),
|
|
41
|
-
validate: (url) =>
|
|
42
|
-
const urlValidationState =
|
|
32
|
+
validate: async (url) => {
|
|
33
|
+
const urlValidationState = await connectValidator.validateUrl(url);
|
|
43
34
|
// Check if we have a cert error, the user will be prompted to ignore it later
|
|
44
35
|
if (connectValidator.validity.canSkipCertError) {
|
|
45
36
|
return true;
|
|
@@ -51,7 +42,7 @@ function getServiceUrlPrompt(connectValidator, requiredVersion) {
|
|
|
51
42
|
return true;
|
|
52
43
|
}
|
|
53
44
|
return urlValidationState;
|
|
54
|
-
}
|
|
45
|
+
}
|
|
55
46
|
};
|
|
56
47
|
}
|
|
57
48
|
/**
|
|
@@ -73,14 +64,14 @@ function getIgnoreCertErrorsPrompt(connectValidator, requiredVersion) {
|
|
|
73
64
|
name: types_2.serviceUrlInternalPromptNames.ignoreCertError,
|
|
74
65
|
message: (0, i18n_1.t)('prompts.ignoreCertErrors.message'),
|
|
75
66
|
default: false,
|
|
76
|
-
validate: (ignoreCertError, { serviceUrl }) =>
|
|
67
|
+
validate: async (ignoreCertError, { serviceUrl }) => {
|
|
77
68
|
if (!serviceUrl) {
|
|
78
69
|
return false;
|
|
79
70
|
}
|
|
80
71
|
if (ignoreCertError) {
|
|
81
72
|
logger_helper_1.default.logger.warn((0, i18n_1.t)('prompts.validationMessages.warningCertificateValidationDisabled'));
|
|
82
73
|
}
|
|
83
|
-
const validUrl =
|
|
74
|
+
const validUrl = await connectValidator.validateUrl(serviceUrl, ignoreCertError, true);
|
|
84
75
|
if (validUrl === true) {
|
|
85
76
|
if (!connectValidator.validity.authRequired) {
|
|
86
77
|
return (0, validators_1.validateService)(serviceUrl, connectValidator, requiredVersion, ignoreCertError);
|
|
@@ -88,7 +79,7 @@ function getIgnoreCertErrorsPrompt(connectValidator, requiredVersion) {
|
|
|
88
79
|
return true;
|
|
89
80
|
}
|
|
90
81
|
return validUrl;
|
|
91
|
-
}
|
|
82
|
+
}
|
|
92
83
|
};
|
|
93
84
|
}
|
|
94
85
|
/**
|
|
@@ -103,7 +94,7 @@ function getCliIgnoreCertValidatePrompt(connectValidator, requiredVersion) {
|
|
|
103
94
|
// Add dummy prompt for CLI to revalidate since "confirm" prompt validators don't run on CLI
|
|
104
95
|
// 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
96
|
// if the user chooses to not ignore cert errors or if the odata service is not valid
|
|
106
|
-
when: ({ serviceUrl, ignoreCertError }) =>
|
|
97
|
+
when: async ({ serviceUrl, ignoreCertError }) => {
|
|
107
98
|
if (serviceUrl && connectValidator.validity.canSkipCertError) {
|
|
108
99
|
// If the user choose to not ignore cert errors, we cannot continue
|
|
109
100
|
if (!ignoreCertError) {
|
|
@@ -112,20 +103,20 @@ function getCliIgnoreCertValidatePrompt(connectValidator, requiredVersion) {
|
|
|
112
103
|
// If the user choose to ignore cert errors, we need to re-validate
|
|
113
104
|
logger_helper_1.default.logger.warn((0, i18n_1.t)('prompts.validationMessages.warningCertificateValidationDisabled'));
|
|
114
105
|
// Re-check if auth required as the cert error would have prevented this check earlier
|
|
115
|
-
const validUrl =
|
|
106
|
+
const validUrl = await connectValidator.validateUrl(serviceUrl, ignoreCertError, true);
|
|
116
107
|
if (validUrl !== true) {
|
|
117
108
|
throw new Error(validUrl.toString()); // exit
|
|
118
109
|
}
|
|
119
110
|
if (!connectValidator.validity.authRequired) {
|
|
120
111
|
// Will log on CLI
|
|
121
|
-
const validService =
|
|
112
|
+
const validService = await (0, validators_1.validateService)(serviceUrl, connectValidator, requiredVersion, true);
|
|
122
113
|
if (validService !== true) {
|
|
123
114
|
throw new Error((0, i18n_1.t)('errors.exitingGeneration', { exitReason: validService.toString() }));
|
|
124
115
|
}
|
|
125
116
|
}
|
|
126
117
|
}
|
|
127
118
|
return false;
|
|
128
|
-
}
|
|
119
|
+
},
|
|
129
120
|
name: types_2.serviceUrlInternalPromptNames.cliIgnoreCertValidate
|
|
130
121
|
};
|
|
131
122
|
}
|
|
@@ -144,7 +135,7 @@ function getUsernamePrompt(connectValidator) {
|
|
|
144
135
|
guiOptions: {
|
|
145
136
|
mandatory: true
|
|
146
137
|
},
|
|
147
|
-
validate: (user) =>
|
|
138
|
+
validate: (user) => user?.length > 0
|
|
148
139
|
};
|
|
149
140
|
}
|
|
150
141
|
/**
|
|
@@ -166,16 +157,16 @@ function getPasswordPrompt(connectValidator, requiredVersion) {
|
|
|
166
157
|
message: (0, i18n_1.t)('prompts.servicePassword.message'),
|
|
167
158
|
guiType: 'login',
|
|
168
159
|
mask: '*',
|
|
169
|
-
validate: (password, { username, serviceUrl, ignoreCertError }) =>
|
|
160
|
+
validate: async (password, { username, serviceUrl, ignoreCertError }) => {
|
|
170
161
|
if (!serviceUrl || !username || !password) {
|
|
171
162
|
return false;
|
|
172
163
|
}
|
|
173
|
-
const validAuth =
|
|
164
|
+
const validAuth = await connectValidator.validateAuth(serviceUrl, username, password, ignoreCertError);
|
|
174
165
|
if (validAuth === true) {
|
|
175
166
|
return (0, validators_1.validateService)(serviceUrl, connectValidator, requiredVersion, ignoreCertError);
|
|
176
167
|
}
|
|
177
168
|
return validAuth;
|
|
178
|
-
}
|
|
169
|
+
}
|
|
179
170
|
};
|
|
180
171
|
}
|
|
181
172
|
/**
|
|
@@ -189,7 +180,7 @@ function getPasswordPrompt(connectValidator, requiredVersion) {
|
|
|
189
180
|
function getServiceUrlQuestions({ serviceUrl: serviceUrlOpts, serviceUrlPassword: passwordOpts } = {}) {
|
|
190
181
|
// Connection validator maintains connection state and validity across multiple prompts
|
|
191
182
|
const connectValidator = new connectionValidator_1.ConnectionValidator();
|
|
192
|
-
const requiredVersion = serviceUrlOpts
|
|
183
|
+
const requiredVersion = serviceUrlOpts?.requiredOdataVersion;
|
|
193
184
|
utils_1.PromptState.reset();
|
|
194
185
|
let questions = [
|
|
195
186
|
getServiceUrlPrompt(connectValidator, requiredVersion),
|
|
@@ -201,11 +192,11 @@ function getServiceUrlQuestions({ serviceUrl: serviceUrlOpts, serviceUrlPassword
|
|
|
201
192
|
questions.push(getUsernamePrompt(connectValidator), getPasswordPrompt(connectValidator, requiredVersion));
|
|
202
193
|
// Add additional messages to prompts if specified in the prompt options
|
|
203
194
|
let promptsOptToExtend = {};
|
|
204
|
-
if (serviceUrlOpts
|
|
195
|
+
if (serviceUrlOpts?.additionalMessages) {
|
|
205
196
|
promptsOptToExtend = { serviceUrl: serviceUrlOpts };
|
|
206
197
|
}
|
|
207
|
-
if (passwordOpts
|
|
208
|
-
promptsOptToExtend =
|
|
198
|
+
if (passwordOpts?.additionalMessages) {
|
|
199
|
+
promptsOptToExtend = { ...promptsOptToExtend, serviceUrlPassword: passwordOpts };
|
|
209
200
|
}
|
|
210
201
|
if (promptsOptToExtend) {
|
|
211
202
|
questions = (0, inquirer_common_1.extendWithOptions)(questions, promptsOptToExtend, utils_1.PromptState.odataService);
|
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -33,63 +24,60 @@ const connectionValidator_1 = require("./connectionValidator");
|
|
|
33
24
|
* @param ignoreCertError if true some certificate errors are ignored
|
|
34
25
|
* @returns true if a valid odata service was returned, false or an error message string otherwise
|
|
35
26
|
*/
|
|
36
|
-
function validateService(url, { odataService, axiosConfig }, requiredVersion = undefined, ignoreCertError = false) {
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
async function validateService(url, { odataService, axiosConfig }, requiredVersion = undefined, ignoreCertError = false) {
|
|
28
|
+
try {
|
|
29
|
+
if (ignoreCertError === true) {
|
|
30
|
+
connectionValidator_1.ConnectionValidator.setGlobalRejectUnauthorized(!ignoreCertError);
|
|
31
|
+
}
|
|
32
|
+
const metadata = await odataService.metadata();
|
|
33
|
+
const serviceOdataVersion = (0, utils_1.parseOdataVersion)(metadata);
|
|
34
|
+
if (requiredVersion && requiredVersion !== serviceOdataVersion) {
|
|
35
|
+
return `${(0, i18n_1.t)('errors.odataServiceVersionMismatch', {
|
|
36
|
+
serviceVersion: serviceOdataVersion,
|
|
37
|
+
requiredVersion
|
|
38
|
+
})}`;
|
|
39
|
+
}
|
|
40
|
+
// Remove all occurrences of the origin from the metadata to make backend uris relative
|
|
41
|
+
utils_1.PromptState.odataService.metadata = (0, utils_1.originToRelative)(metadata);
|
|
42
|
+
utils_1.PromptState.odataService.odataVersion = serviceOdataVersion;
|
|
43
|
+
// Extract sap-client and keep the rest of the query params as part of the url
|
|
44
|
+
const fullUrl = new URL(url);
|
|
45
|
+
const sapClient = fullUrl.searchParams.get(types_1.SAP_CLIENT_KEY) ?? undefined;
|
|
46
|
+
fullUrl.searchParams.delete(types_1.SAP_CLIENT_KEY);
|
|
47
|
+
utils_1.PromptState.odataService.servicePath = `${fullUrl.pathname}${fullUrl.search}`;
|
|
48
|
+
utils_1.PromptState.odataService.origin = fullUrl.origin;
|
|
49
|
+
utils_1.PromptState.odataService.sapClient = sapClient;
|
|
50
|
+
// Best effort attempt to get annotations but dont throw an error if it fails as this may not even be an Abap system
|
|
39
51
|
try {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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) {
|
|
52
|
+
// Create an abap provider instance to get the annotations using the same request config
|
|
53
|
+
const abapProvider = (0, axios_extension_1.createForAbap)(axiosConfig);
|
|
54
|
+
const catalogService = abapProvider.catalog(serviceOdataVersion);
|
|
55
|
+
logger_helper_1.default.attachAxiosLogger(catalogService.interceptors);
|
|
56
|
+
logger_helper_1.default.logger.debug('Getting annotations for service');
|
|
57
|
+
const annotations = await catalogService.getAnnotations({ path: fullUrl.pathname });
|
|
58
|
+
logger_helper_1.default.logger.debug(`Annotations array of length: ${annotations?.length} returned`);
|
|
59
|
+
if (annotations?.length === 0 || !annotations) {
|
|
76
60
|
logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.annotationsNotFound'));
|
|
77
61
|
}
|
|
78
|
-
|
|
62
|
+
utils_1.PromptState.odataService.annotations = annotations;
|
|
79
63
|
}
|
|
80
|
-
catch (
|
|
81
|
-
|
|
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);
|
|
64
|
+
catch (err) {
|
|
65
|
+
logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.annotationsNotFound'));
|
|
88
66
|
}
|
|
89
|
-
|
|
90
|
-
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
delete utils_1.PromptState.odataService.metadata;
|
|
71
|
+
// Provide a more specific error message if the metadata service URL is not found
|
|
72
|
+
if (error_handler_1.ErrorHandler.getErrorType(error) === error_handler_1.ERROR_TYPE.NOT_FOUND) {
|
|
73
|
+
// No metadata implies not a valid odata service
|
|
74
|
+
return error_handler_1.ErrorHandler.getErrorMsgFromType(error_handler_1.ERROR_TYPE.ODATA_URL_NOT_FOUND) ?? false;
|
|
91
75
|
}
|
|
92
|
-
|
|
76
|
+
return prompt_helpers_1.errorHandler.logErrorMsgs(error);
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
connectionValidator_1.ConnectionValidator.setGlobalRejectUnauthorized(true);
|
|
80
|
+
}
|
|
93
81
|
}
|
|
94
82
|
exports.validateService = validateService;
|
|
95
83
|
//# sourceMappingURL=validators.js.map
|
|
@@ -29,6 +29,7 @@ const AxiosLogger = __importStar(require("axios-logger"));
|
|
|
29
29
|
* Static logger prevents passing of logger references through all functions, as this is a cross-cutting concern.
|
|
30
30
|
*/
|
|
31
31
|
class LoggerHelper {
|
|
32
|
+
static _logger = new logger_1.ToolsLogger({ logPrefix: '@sap-ux/odata-service-inquirer' });
|
|
32
33
|
/**
|
|
33
34
|
* Get the logger.
|
|
34
35
|
*
|
|
@@ -81,6 +82,5 @@ class LoggerHelper {
|
|
|
81
82
|
});
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
|
-
LoggerHelper._logger = new logger_1.ToolsLogger({ logPrefix: '@sap-ux/odata-service-inquirer' });
|
|
85
85
|
exports.default = LoggerHelper;
|
|
86
86
|
//# sourceMappingURL=logger-helper.js.map
|
package/dist/prompts/prompts.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -28,13 +19,11 @@ const questions_2 = require("./datasources/service-url/questions");
|
|
|
28
19
|
* @param promptOptions - options that can control some of the prompt behavior. See {@link OdataServicePromptOptions} for details
|
|
29
20
|
* @returns the prompts used to provide input for OData service generation
|
|
30
21
|
*/
|
|
31
|
-
function getQuestions(promptOptions) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return questions;
|
|
37
|
-
});
|
|
22
|
+
async function getQuestions(promptOptions) {
|
|
23
|
+
const questions = [getDatasourceTypeQuestion(promptOptions?.datasourceType)];
|
|
24
|
+
// Add conditional questions depending on the selected source
|
|
25
|
+
questions.push(...(await getDatasourceTypeConditionalQuestions(promptOptions)));
|
|
26
|
+
return questions;
|
|
38
27
|
}
|
|
39
28
|
exports.getQuestions = getQuestions;
|
|
40
29
|
/**
|
|
@@ -44,7 +33,6 @@ exports.getQuestions = getQuestions;
|
|
|
44
33
|
* @returns the datasource type question
|
|
45
34
|
*/
|
|
46
35
|
function getDatasourceTypeQuestion(options) {
|
|
47
|
-
var _a;
|
|
48
36
|
const choices = (0, prompt_helpers_1.getDatasourceTypeChoices)(options);
|
|
49
37
|
return {
|
|
50
38
|
type: 'list',
|
|
@@ -52,18 +40,17 @@ function getDatasourceTypeQuestion(options) {
|
|
|
52
40
|
guiOptions: {
|
|
53
41
|
breadcrumb: true
|
|
54
42
|
},
|
|
55
|
-
default:
|
|
43
|
+
default: options?.default ?? -1,
|
|
56
44
|
message: (0, i18n_1.t)('prompts.datasourceType.message'),
|
|
57
45
|
choices,
|
|
58
46
|
additionalMessages: (source) => {
|
|
59
|
-
var _a;
|
|
60
47
|
if ([
|
|
61
48
|
types_1.DatasourceType.businessHub,
|
|
62
49
|
types_1.DatasourceType.none,
|
|
63
50
|
types_1.DatasourceType.projectSpecificDestination,
|
|
64
51
|
types_1.DatasourceType.sapSystem
|
|
65
52
|
].includes(source)) {
|
|
66
|
-
|
|
53
|
+
logger_helper_1.default.logger?.warn((0, i18n_1.t)('prompts.datasourceType.notYetImplementedWarningMessage', { datasourceType: source }));
|
|
67
54
|
return {
|
|
68
55
|
message: (0, i18n_1.t)('prompts.datasourceType.notYetImplementedWarningMessage', { datasourceType: source }),
|
|
69
56
|
severity: yeoman_ui_types_1.Severity.warning
|
|
@@ -86,14 +73,12 @@ function getDatasourceTypeQuestion(options) {
|
|
|
86
73
|
* @param promptOptions - options that can control some of the prompt behavior. See {@link OdataServicePromptOptions} for details
|
|
87
74
|
* @returns the conditional questions based on the datasource type answer
|
|
88
75
|
*/
|
|
89
|
-
function getDatasourceTypeConditionalQuestions(promptOptions) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return conditionalQuestions;
|
|
97
|
-
});
|
|
76
|
+
async function getDatasourceTypeConditionalQuestions(promptOptions) {
|
|
77
|
+
const conditionalQuestions = [];
|
|
78
|
+
conditionalQuestions.push(...(0, inquirer_common_1.withCondition)([(0, metadata_file_1.getMetadataFileQuestion)(promptOptions?.metadataFilePath)], (answers) => answers.datasourceType === types_1.DatasourceType.metadataFile));
|
|
79
|
+
conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((0, questions_1.getLocalCapProjectPrompts)(promptOptions), (answers) => answers.datasourceType === types_1.DatasourceType.capProject));
|
|
80
|
+
conditionalQuestions.push(...(0, inquirer_common_1.withCondition)((0, questions_2.getServiceUrlQuestions)(promptOptions), (answers) => answers.datasourceType === types_1.DatasourceType.odataServiceUrl));
|
|
81
|
+
//...further data sources to be added here
|
|
82
|
+
return conditionalQuestions;
|
|
98
83
|
}
|
|
99
84
|
//# sourceMappingURL=prompts.js.map
|