@sap-ux/odata-service-inquirer 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/error-handler/error-handler.d.ts +7 -0
- package/dist/error-handler/error-handler.js +24 -11
- package/dist/i18n.js +6 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.js +1 -1
- package/dist/prompts/datasources/cap-project/questions.js +1 -1
- package/dist/prompts/datasources/service-url/connectionValidator.d.ts +99 -0
- package/dist/prompts/datasources/service-url/connectionValidator.js +271 -0
- package/dist/prompts/datasources/service-url/questions.d.ts +12 -0
- package/dist/prompts/datasources/service-url/questions.js +216 -0
- package/dist/prompts/datasources/service-url/types.d.ts +9 -0
- package/dist/prompts/datasources/service-url/types.js +13 -0
- package/dist/prompts/datasources/service-url/validators.d.ts +19 -0
- package/dist/prompts/datasources/service-url/validators.js +95 -0
- package/dist/prompts/logger-helper.d.ts +12 -0
- package/dist/prompts/logger-helper.js +59 -0
- package/dist/prompts/prompts.js +2 -0
- package/dist/prompts/validators.d.ts +1 -1
- package/dist/prompts/validators.js +6 -10
- package/dist/translations/odata-service-inquirer.i18n.json +23 -2
- package/dist/types.d.ts +42 -5
- package/dist/types.js +10 -1
- package/dist/utils/index.d.ts +18 -1
- package/dist/utils/index.js +54 -4
- package/dist/utils/prompt-state.js +4 -1
- package/package.json +6 -3
|
@@ -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 metdata 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;
|
package/dist/prompts/prompts.js
CHANGED
|
@@ -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
|
});
|
|
@@ -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
|
|
22
|
-
|
|
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:
|
|
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:
|
|
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 {
|
|
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
|
|
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
|
|
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
|