@sap-ux/odata-service-inquirer 0.4.8 → 0.5.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/index.d.ts +14 -3
- package/dist/index.js +30 -5
- package/dist/prompts/connectionValidator.d.ts +160 -0
- package/dist/prompts/{datasources/service-url/connectionValidator.js → connectionValidator.js} +145 -41
- package/dist/prompts/datasources/sap-system/abap-on-prem/questions.d.ts +44 -0
- package/dist/prompts/datasources/sap-system/abap-on-prem/questions.js +253 -0
- package/dist/prompts/datasources/sap-system/abap-on-prem/service-helper.d.ts +33 -0
- package/dist/prompts/datasources/sap-system/abap-on-prem/service-helper.js +122 -0
- package/dist/prompts/datasources/sap-system/new-system/questions.d.ts +35 -0
- package/dist/prompts/datasources/sap-system/new-system/questions.js +107 -0
- package/dist/prompts/datasources/sap-system/prompt-helpers.d.ts +9 -0
- package/dist/prompts/datasources/sap-system/prompt-helpers.js +37 -0
- package/dist/prompts/datasources/sap-system/validators.d.ts +8 -0
- package/dist/prompts/datasources/sap-system/validators.js +36 -0
- package/dist/prompts/datasources/service-url/questions.js +14 -5
- package/dist/prompts/datasources/service-url/validators.d.ts +1 -1
- package/dist/prompts/datasources/service-url/validators.js +2 -2
- package/dist/prompts/logger-helper.js +5 -4
- package/dist/prompts/prompts.js +10 -4
- package/dist/translations/odata-service-inquirer.i18n.json +48 -3
- package/dist/types.d.ts +45 -11
- package/dist/types.js +8 -0
- package/package.json +7 -4
- package/dist/prompts/datasources/service-url/connectionValidator.d.ts +0 -99
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getAbapOnPremSystemQuestions = exports.getAbapOnPremQuestions = exports.abapOnPremInternalPromptNames = void 0;
|
|
7
|
+
const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
|
|
8
|
+
const axios_extension_1 = require("@sap-ux/axios-extension");
|
|
9
|
+
const inquirer_common_1 = require("@sap-ux/inquirer-common");
|
|
10
|
+
const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
|
|
11
|
+
const project_input_validator_1 = require("@sap-ux/project-input-validator");
|
|
12
|
+
const i18n_1 = require("../../../../i18n");
|
|
13
|
+
const types_1 = require("../../../../types");
|
|
14
|
+
const utils_1 = require("../../../../utils");
|
|
15
|
+
const connectionValidator_1 = require("../../../connectionValidator");
|
|
16
|
+
const logger_helper_1 = __importDefault(require("../../../logger-helper"));
|
|
17
|
+
const questions_1 = require("../new-system/questions");
|
|
18
|
+
const service_helper_1 = require("./service-helper");
|
|
19
|
+
var abapOnPremInternalPromptNames;
|
|
20
|
+
(function (abapOnPremInternalPromptNames) {
|
|
21
|
+
abapOnPremInternalPromptNames["systemUrl"] = "systemUrl";
|
|
22
|
+
abapOnPremInternalPromptNames["sapClient"] = "sapClient";
|
|
23
|
+
abapOnPremInternalPromptNames["systemUsername"] = "abapSystemUsername";
|
|
24
|
+
abapOnPremInternalPromptNames["systemPassword"] = "abapSystemPassword";
|
|
25
|
+
})(abapOnPremInternalPromptNames || (exports.abapOnPremInternalPromptNames = abapOnPremInternalPromptNames = {}));
|
|
26
|
+
const cliServicePromptName = 'cliServicePromptName';
|
|
27
|
+
/**
|
|
28
|
+
* Convert the odata version type from the prompt (odata-service-writer) type to the axios-extension type.
|
|
29
|
+
*
|
|
30
|
+
* @param odataVersion The odata version to convert
|
|
31
|
+
* @returns The converted odata version
|
|
32
|
+
*/
|
|
33
|
+
function convertODataVersionType(odataVersion) {
|
|
34
|
+
if (!odataVersion) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return odataVersion === odata_service_writer_1.OdataVersion.v2 ? axios_extension_1.ODataVersion.v2 : axios_extension_1.ODataVersion.v4;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the Abap on-premise datasource questions.
|
|
41
|
+
*
|
|
42
|
+
* @param promptOptions options for prompts. Applicable options are: {@link ServiceSelectionPromptOptions}, {@link SystemNamePromptOptions}
|
|
43
|
+
* @returns property questions for the Abap on-premise datasource
|
|
44
|
+
*/
|
|
45
|
+
function getAbapOnPremQuestions(promptOptions) {
|
|
46
|
+
utils_1.PromptState.reset();
|
|
47
|
+
const connectValidator = new connectionValidator_1.ConnectionValidator();
|
|
48
|
+
let serviceChoices;
|
|
49
|
+
// Prevent re-requesting services repeatedly by only requesting them once and when the system is changed
|
|
50
|
+
let previousSystemUrl;
|
|
51
|
+
let previousService;
|
|
52
|
+
// Prompt options
|
|
53
|
+
const requiredOdataVersion = promptOptions?.serviceSelection?.requiredOdataVersion;
|
|
54
|
+
const questions = getAbapOnPremSystemQuestions(promptOptions?.userSystemName, connectValidator, requiredOdataVersion);
|
|
55
|
+
questions.push({
|
|
56
|
+
when: () => connectValidator.validity.authenticated || connectValidator.validity.authRequired === false,
|
|
57
|
+
name: types_1.promptNames.serviceSelection,
|
|
58
|
+
type: promptOptions?.serviceSelection?.useAutoComplete ? 'autocomplete' : 'list',
|
|
59
|
+
message: (0, i18n_1.t)('prompts.systemService.message'),
|
|
60
|
+
guiOptions: {
|
|
61
|
+
breadcrumb: (0, i18n_1.t)('prompts.systemService.breadcrumb'),
|
|
62
|
+
mandatory: true,
|
|
63
|
+
applyDefaultWhenDirty: true
|
|
64
|
+
},
|
|
65
|
+
source: (prevAnswers, input) => (0, inquirer_common_1.searchChoices)(input, serviceChoices),
|
|
66
|
+
choices: async (answers) => {
|
|
67
|
+
if (!serviceChoices || previousSystemUrl !== answers.systemUrl) {
|
|
68
|
+
let catalogs = [];
|
|
69
|
+
if (requiredOdataVersion) {
|
|
70
|
+
catalogs.push(connectValidator.catalogs[requiredOdataVersion]);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
catalogs = Object.values(connectValidator.catalogs);
|
|
74
|
+
}
|
|
75
|
+
previousSystemUrl = answers.systemUrl;
|
|
76
|
+
serviceChoices = await (0, service_helper_1.getServiceChoices)(catalogs);
|
|
77
|
+
}
|
|
78
|
+
return serviceChoices;
|
|
79
|
+
},
|
|
80
|
+
additionalMessages: async (selectedService) => {
|
|
81
|
+
if (serviceChoices?.length === 0) {
|
|
82
|
+
if (requiredOdataVersion) {
|
|
83
|
+
return {
|
|
84
|
+
message: (0, i18n_1.t)('prompts.warnings.noServicesAvailableForOdataVersion', {
|
|
85
|
+
odataVersion: requiredOdataVersion
|
|
86
|
+
}),
|
|
87
|
+
severity: yeoman_ui_types_1.Severity.warning
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return {
|
|
92
|
+
message: (0, i18n_1.t)('prompts.warnings.noServicesAvailable'),
|
|
93
|
+
severity: yeoman_ui_types_1.Severity.warning
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (selectedService) {
|
|
98
|
+
let serviceType = selectedService.serviceType;
|
|
99
|
+
if (selectedService.serviceODataVersion === axios_extension_1.ODataVersion.v2) {
|
|
100
|
+
serviceType = await (0, service_helper_1.getServiceType)(selectedService.servicePath, selectedService.serviceType, connectValidator.catalogs[axios_extension_1.ODataVersion.v2]);
|
|
101
|
+
}
|
|
102
|
+
if (serviceType && serviceType !== axios_extension_1.ServiceType.UI) {
|
|
103
|
+
return {
|
|
104
|
+
message: (0, i18n_1.t)('prompts.warnings.nonUIServiceTypeWarningMessage', { serviceType: 'A2X' }),
|
|
105
|
+
severity: yeoman_ui_types_1.Severity.warning
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
default: () => (serviceChoices?.length > 1 ? undefined : 0),
|
|
111
|
+
// Warning: only executes in YUI not cli
|
|
112
|
+
validate: async (service, { systemUrl } = {}) => {
|
|
113
|
+
if (!systemUrl) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
// Dont re-request the same service details
|
|
117
|
+
if (service && previousService?.servicePath !== service.servicePath) {
|
|
118
|
+
previousService = service;
|
|
119
|
+
return getServiceDetails(service, systemUrl, connectValidator);
|
|
120
|
+
}
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// Only for CLI use as `list` prompt validation does not run on CLI
|
|
125
|
+
if ((0, utils_1.getHostEnvironment)() === types_1.hostEnvironment.cli) {
|
|
126
|
+
questions.push({
|
|
127
|
+
when: async (answers) => {
|
|
128
|
+
if (answers.serviceSelection && answers.systemUrl) {
|
|
129
|
+
const result = await getServiceDetails(answers.serviceSelection, answers.systemUrl, connectValidator);
|
|
130
|
+
if (typeof result === 'string') {
|
|
131
|
+
logger_helper_1.default.logger.error(result);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
135
|
+
},
|
|
136
|
+
name: cliServicePromptName
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return questions;
|
|
140
|
+
}
|
|
141
|
+
exports.getAbapOnPremQuestions = getAbapOnPremQuestions;
|
|
142
|
+
/**
|
|
143
|
+
* Gets the Abap on-premise system questions.
|
|
144
|
+
*
|
|
145
|
+
* @param systemNamePromptOptions options for the system name prompt see {@link SystemNamePromptOptions}
|
|
146
|
+
* @param connectionValidator reference to the existing connection validator, a new one will be created otherwise
|
|
147
|
+
* @param requiredOdataVersion the required OData version for the service, this will be used to narrow the catalog service connections
|
|
148
|
+
* @returns the Abap on-premise system questions
|
|
149
|
+
*/
|
|
150
|
+
function getAbapOnPremSystemQuestions(systemNamePromptOptions, connectionValidator, requiredOdataVersion) {
|
|
151
|
+
const connectValidator = connectionValidator ?? new connectionValidator_1.ConnectionValidator();
|
|
152
|
+
const questions = [
|
|
153
|
+
{
|
|
154
|
+
type: 'input',
|
|
155
|
+
name: abapOnPremInternalPromptNames.systemUrl,
|
|
156
|
+
message: (0, i18n_1.t)('prompts.systemUrl.message'),
|
|
157
|
+
guiOptions: {
|
|
158
|
+
hint: (0, i18n_1.t)('prompts.systemUrl.description'),
|
|
159
|
+
mandatory: true,
|
|
160
|
+
breadcrumb: true
|
|
161
|
+
},
|
|
162
|
+
validate: async (url) => {
|
|
163
|
+
const valResult = await connectValidator.validateUrl(url, {
|
|
164
|
+
isSystem: true,
|
|
165
|
+
odataVersion: convertODataVersionType(requiredOdataVersion)
|
|
166
|
+
});
|
|
167
|
+
if (valResult === true) {
|
|
168
|
+
utils_1.PromptState.odataService.connectedSystem = {
|
|
169
|
+
serviceProvider: connectValidator.serviceProvider
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return valResult;
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
type: 'input',
|
|
177
|
+
name: abapOnPremInternalPromptNames.sapClient,
|
|
178
|
+
message: (0, i18n_1.t)('prompts.sapClient.message'),
|
|
179
|
+
guiOptions: {
|
|
180
|
+
breadcrumb: (0, i18n_1.t)('prompts.sapClient.breadcrumb')
|
|
181
|
+
},
|
|
182
|
+
validate: project_input_validator_1.validateClient
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
when: () => (connectValidator.validity.reachable ? connectValidator.validity.authRequired === true : false),
|
|
186
|
+
type: 'input',
|
|
187
|
+
name: abapOnPremInternalPromptNames.systemUsername,
|
|
188
|
+
message: (0, i18n_1.t)('prompts.systemUsername.message'),
|
|
189
|
+
guiOptions: {
|
|
190
|
+
mandatory: true
|
|
191
|
+
},
|
|
192
|
+
validate: (user) => user?.length > 0
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
when: () => (connectValidator.validity.reachable ? connectValidator.validity.authRequired === true : false),
|
|
196
|
+
type: 'password',
|
|
197
|
+
guiOptions: {
|
|
198
|
+
mandatory: true
|
|
199
|
+
},
|
|
200
|
+
name: abapOnPremInternalPromptNames.systemPassword,
|
|
201
|
+
message: (0, i18n_1.t)('prompts.systemPassword.message'),
|
|
202
|
+
guiType: 'login',
|
|
203
|
+
mask: '*',
|
|
204
|
+
validate: async (password, { systemUrl, abapSystemUsername, sapClient }) => {
|
|
205
|
+
if (!(systemUrl && abapSystemUsername && password)) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
const valResult = await connectValidator.validateAuth(systemUrl, abapSystemUsername, password, {
|
|
209
|
+
isSystem: true,
|
|
210
|
+
sapClient
|
|
211
|
+
});
|
|
212
|
+
if (valResult === true) {
|
|
213
|
+
utils_1.PromptState.odataService.connectedSystem = {
|
|
214
|
+
serviceProvider: connectValidator.serviceProvider
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return valResult;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
];
|
|
221
|
+
if (systemNamePromptOptions?.exclude !== true) {
|
|
222
|
+
// New system question will allow user to give the system a user friendly name
|
|
223
|
+
questions.push((0, inquirer_common_1.withCondition)([(0, questions_1.getUserSystemNameQuestion)()], (answers) => !!answers.systemUrl &&
|
|
224
|
+
connectValidator.validity.reachable === true &&
|
|
225
|
+
(connectValidator.validity.authenticated || connectValidator.validity.authRequired !== true))[0]);
|
|
226
|
+
}
|
|
227
|
+
return questions;
|
|
228
|
+
}
|
|
229
|
+
exports.getAbapOnPremSystemQuestions = getAbapOnPremSystemQuestions;
|
|
230
|
+
/**
|
|
231
|
+
* Requests and sets the service details to the PromptState.odataService properties.
|
|
232
|
+
* If an error occurs, the error message is returned for use in validators.
|
|
233
|
+
*
|
|
234
|
+
* @param service the specific service to get details for
|
|
235
|
+
* @param systemUrl the system origin where the service is hosted
|
|
236
|
+
* @param connectionValidator a reference to the connection validator
|
|
237
|
+
* @returns true if successful, setting the PromptState.odataService properties, or an error message indicating why the service details could not be retrieved.
|
|
238
|
+
*/
|
|
239
|
+
async function getServiceDetails(service, systemUrl, connectionValidator) {
|
|
240
|
+
const serviceCatalog = connectionValidator.catalogs[service.serviceODataVersion];
|
|
241
|
+
const serviceResult = await (0, service_helper_1.getServiceMetadata)(service.servicePath, serviceCatalog, connectionValidator.serviceProvider);
|
|
242
|
+
if (typeof serviceResult === 'string') {
|
|
243
|
+
return serviceResult;
|
|
244
|
+
}
|
|
245
|
+
utils_1.PromptState.odataService.annotations = serviceResult?.annotations;
|
|
246
|
+
utils_1.PromptState.odataService.metadata = serviceResult?.metadata;
|
|
247
|
+
utils_1.PromptState.odataService.odataVersion =
|
|
248
|
+
service.serviceODataVersion === axios_extension_1.ODataVersion.v2 ? odata_service_writer_1.OdataVersion.v2 : odata_service_writer_1.OdataVersion.v4;
|
|
249
|
+
utils_1.PromptState.odataService.servicePath = service.servicePath;
|
|
250
|
+
utils_1.PromptState.odataService.origin = systemUrl;
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=questions.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ServiceType, type Annotations, type CatalogService, type V2CatalogService, type ServiceProvider } from '@sap-ux/axios-extension';
|
|
2
|
+
import type { ListChoiceOptions } from 'inquirer';
|
|
3
|
+
import type { ServiceAnswer } from './questions';
|
|
4
|
+
/**
|
|
5
|
+
* Get the service choices from the specified catalogs.
|
|
6
|
+
*
|
|
7
|
+
* @param catalogs catalogs to get the services from. There should be one per odata version required.
|
|
8
|
+
* @returns service choices based on the provided catalogs
|
|
9
|
+
*/
|
|
10
|
+
export declare function getServiceChoices(catalogs: CatalogService[]): Promise<ListChoiceOptions<ServiceAnswer>[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Gets the service metadata and annotations for the specified service path.
|
|
13
|
+
*
|
|
14
|
+
* @param servicePath service path
|
|
15
|
+
* @param catalog the catalog service used to get the annotations for the specified service path
|
|
16
|
+
* @param serviceProvider the service provider for the connected system
|
|
17
|
+
* @returns Promise<string | boolean>, string error message or true if successful
|
|
18
|
+
*/
|
|
19
|
+
export declare function getServiceMetadata(servicePath: string, catalog: CatalogService, serviceProvider: ServiceProvider): Promise<{
|
|
20
|
+
annotations: Annotations[];
|
|
21
|
+
metadata: string;
|
|
22
|
+
serviceProvider: ServiceProvider;
|
|
23
|
+
} | string>;
|
|
24
|
+
/**
|
|
25
|
+
* Get service type for 'Not Determined' services from `ServiceTypeForHUBServices()`
|
|
26
|
+
*
|
|
27
|
+
* @param servicePath service path
|
|
28
|
+
* @param serviceType service type
|
|
29
|
+
* @param catalog the catalog service used to get the service type for the specified service path
|
|
30
|
+
* @returns service type
|
|
31
|
+
*/
|
|
32
|
+
export declare function getServiceType(servicePath: string, serviceType: string | undefined, catalog: V2CatalogService): Promise<ServiceType | undefined>;
|
|
33
|
+
//# sourceMappingURL=service-helper.d.ts.map
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getServiceType = exports.getServiceMetadata = exports.getServiceChoices = void 0;
|
|
7
|
+
const axios_extension_1 = require("@sap-ux/axios-extension");
|
|
8
|
+
const i18n_1 = require("../../../../i18n");
|
|
9
|
+
const logger_helper_1 = __importDefault(require("../../../logger-helper"));
|
|
10
|
+
// Service ids continaining these paths should not be offered as UI compatible services
|
|
11
|
+
const nonUIServicePaths = ['/IWBEP/COMMON/'];
|
|
12
|
+
/**
|
|
13
|
+
* Builds and formats the service choices list.
|
|
14
|
+
*
|
|
15
|
+
* @param serviceInfos service information to build the choices from. Services with a service id containing '/IWBEP/COMMON' are ignored.
|
|
16
|
+
* @returns service choices list
|
|
17
|
+
*/
|
|
18
|
+
const createServiceChoices = (serviceInfos) => {
|
|
19
|
+
const choices = [];
|
|
20
|
+
// Provide additional service information in trace mode (YUI only)
|
|
21
|
+
let isLogTrace = false;
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Only specific loggers have this method
|
|
23
|
+
if (typeof logger_helper_1.default.logger.getLogLevel === 'function') {
|
|
24
|
+
isLogTrace = logger_helper_1.default.logger.getLogLevel() === 'trace';
|
|
25
|
+
}
|
|
26
|
+
serviceInfos
|
|
27
|
+
// Exclude non-UI compatible services
|
|
28
|
+
?.filter((service) => !nonUIServicePaths.some((path) => service.path.includes(path)))
|
|
29
|
+
.forEach((service) => {
|
|
30
|
+
let serviceName = service.name;
|
|
31
|
+
const servicePath = service.path;
|
|
32
|
+
serviceName = `${serviceName} (${service.serviceVersion}) - OData V${service.odataVersion}`;
|
|
33
|
+
if (isLogTrace) {
|
|
34
|
+
serviceName = `${serviceName} Service Type: ${service.serviceType}`;
|
|
35
|
+
}
|
|
36
|
+
choices.push({
|
|
37
|
+
name: serviceName,
|
|
38
|
+
value: {
|
|
39
|
+
servicePath,
|
|
40
|
+
serviceODataVersion: service.odataVersion,
|
|
41
|
+
toString: () => serviceName,
|
|
42
|
+
serviceType: service.serviceType
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
return choices.sort((a, b) => (a.name ? a.name.localeCompare(b.name ?? '') : 0));
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Get the service choices from the specified catalogs.
|
|
50
|
+
*
|
|
51
|
+
* @param catalogs catalogs to get the services from. There should be one per odata version required.
|
|
52
|
+
* @returns service choices based on the provided catalogs
|
|
53
|
+
*/
|
|
54
|
+
async function getServiceChoices(catalogs) {
|
|
55
|
+
const listServicesRequests = catalogs.map(async (catalog) => {
|
|
56
|
+
try {
|
|
57
|
+
return await catalog.listServices();
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
logger_helper_1.default.logger.error(`An error occurred requesting services from: ${catalog.entitySet}. Some services may not be listed.`);
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const serviceInfos = await Promise.all(listServicesRequests);
|
|
65
|
+
const flatServices = serviceInfos?.flat() ?? [];
|
|
66
|
+
logger_helper_1.default.logger.debug(`Number of services available: ${flatServices.length}`);
|
|
67
|
+
return createServiceChoices(flatServices);
|
|
68
|
+
}
|
|
69
|
+
exports.getServiceChoices = getServiceChoices;
|
|
70
|
+
/**
|
|
71
|
+
* Gets the service metadata and annotations for the specified service path.
|
|
72
|
+
*
|
|
73
|
+
* @param servicePath service path
|
|
74
|
+
* @param catalog the catalog service used to get the annotations for the specified service path
|
|
75
|
+
* @param serviceProvider the service provider for the connected system
|
|
76
|
+
* @returns Promise<string | boolean>, string error message or true if successful
|
|
77
|
+
*/
|
|
78
|
+
async function getServiceMetadata(servicePath, catalog, serviceProvider) {
|
|
79
|
+
let annotations = [];
|
|
80
|
+
try {
|
|
81
|
+
try {
|
|
82
|
+
annotations = await catalog.getAnnotations({ path: servicePath });
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
logger_helper_1.default.logger.info((0, i18n_1.t)('prompts.validationMessages.noAnnotations'));
|
|
86
|
+
}
|
|
87
|
+
const odataService = serviceProvider.service(servicePath);
|
|
88
|
+
const metadata = await odataService.metadata();
|
|
89
|
+
return {
|
|
90
|
+
annotations,
|
|
91
|
+
metadata,
|
|
92
|
+
serviceProvider
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
logger_helper_1.default.logger.error((0, i18n_1.t)('errors.serviceMetadataErrorLog', { servicePath, error }));
|
|
97
|
+
return (0, i18n_1.t)('errors.serviceMetadataErrorUI', { servicePath });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.getServiceMetadata = getServiceMetadata;
|
|
101
|
+
/**
|
|
102
|
+
* Get service type for 'Not Determined' services from `ServiceTypeForHUBServices()`
|
|
103
|
+
*
|
|
104
|
+
* @param servicePath service path
|
|
105
|
+
* @param serviceType service type
|
|
106
|
+
* @param catalog the catalog service used to get the service type for the specified service path
|
|
107
|
+
* @returns service type
|
|
108
|
+
*/
|
|
109
|
+
async function getServiceType(servicePath, serviceType, catalog) {
|
|
110
|
+
let resolvedServiceType;
|
|
111
|
+
if (serviceType === axios_extension_1.ServiceType.NotDetermined) {
|
|
112
|
+
try {
|
|
113
|
+
resolvedServiceType = (await catalog.getServiceType(servicePath)) ?? axios_extension_1.ServiceType.NotDetermined;
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
logger_helper_1.default.logger.error((0, i18n_1.t)('errors.serviceTypeRequestError', { error: e.message }));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return resolvedServiceType ?? serviceType;
|
|
120
|
+
}
|
|
121
|
+
exports.getServiceType = getServiceType;
|
|
122
|
+
//# sourceMappingURL=service-helper.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { InputQuestion, Question } from 'inquirer';
|
|
2
|
+
import type { OdataServiceAnswers, OdataServicePromptOptions, SapSystemType } from '../../../../types';
|
|
3
|
+
import { promptNames } from '../../../../types';
|
|
4
|
+
export declare const newSystemChoiceValue = "!@\u00A3*&937newSystem*X~qy^";
|
|
5
|
+
declare const newSystemPromptNames: {
|
|
6
|
+
readonly newSystemType: "newSystemType";
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Internal only answers to service URL prompting not returned with OdataServiceAnswers.
|
|
10
|
+
*/
|
|
11
|
+
export interface NewSystemAnswers {
|
|
12
|
+
[newSystemPromptNames.newSystemType]?: SapSystemType;
|
|
13
|
+
[promptNames.userSystemName]?: string;
|
|
14
|
+
}
|
|
15
|
+
declare const systemSelectionPromptNames: {
|
|
16
|
+
readonly system: "system";
|
|
17
|
+
};
|
|
18
|
+
export interface SystemSelectionAnswer extends OdataServiceAnswers {
|
|
19
|
+
[systemSelectionPromptNames.system]?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Provides prompts that allow the creation of a new system connection.
|
|
23
|
+
*
|
|
24
|
+
* @param promptOptions options for the new system prompts see {@link OdataServicePromptOptions}
|
|
25
|
+
* @returns questions for creating a new system connection
|
|
26
|
+
*/
|
|
27
|
+
export declare function getNewSystemQuestions(promptOptions?: OdataServicePromptOptions): Question<NewSystemAnswers>[];
|
|
28
|
+
/**
|
|
29
|
+
* Get a prompt for new system name.
|
|
30
|
+
*
|
|
31
|
+
* @returns the new system name prompt
|
|
32
|
+
*/
|
|
33
|
+
export declare function getUserSystemNameQuestion(): InputQuestion<NewSystemAnswers>;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=questions.d.ts.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getUserSystemNameQuestion = exports.getNewSystemQuestions = exports.newSystemChoiceValue = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* New system prompting questions for re-use in multiple sap-system datasource prompt sets.
|
|
9
|
+
*/
|
|
10
|
+
const yeoman_ui_types_1 = require("@sap-devx/yeoman-ui-types");
|
|
11
|
+
const inquirer_common_1 = require("@sap-ux/inquirer-common");
|
|
12
|
+
const store_1 = require("@sap-ux/store");
|
|
13
|
+
const i18n_1 = require("../../../../i18n");
|
|
14
|
+
const types_1 = require("../../../../types");
|
|
15
|
+
const utils_1 = require("../../../../utils");
|
|
16
|
+
const logger_helper_1 = __importDefault(require("../../../logger-helper"));
|
|
17
|
+
const questions_1 = require("../abap-on-prem/questions");
|
|
18
|
+
const prompt_helpers_1 = require("../prompt-helpers");
|
|
19
|
+
const validators_1 = require("../validators");
|
|
20
|
+
// New system choice value is a hard to guess string to avoid conflicts with existing system names or user named systems
|
|
21
|
+
// since it will be used as a new system value in the system selection prompt.
|
|
22
|
+
exports.newSystemChoiceValue = '!@£*&937newSystem*X~qy^';
|
|
23
|
+
const newSystemPromptNames = {
|
|
24
|
+
newSystemType: 'newSystemType'
|
|
25
|
+
};
|
|
26
|
+
const systemSelectionPromptNames = {
|
|
27
|
+
system: 'system'
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Provides prompts that allow the creation of a new system connection.
|
|
31
|
+
*
|
|
32
|
+
* @param promptOptions options for the new system prompts see {@link OdataServicePromptOptions}
|
|
33
|
+
* @returns questions for creating a new system connection
|
|
34
|
+
*/
|
|
35
|
+
function getNewSystemQuestions(promptOptions) {
|
|
36
|
+
const questions = [
|
|
37
|
+
{
|
|
38
|
+
type: 'list',
|
|
39
|
+
name: newSystemPromptNames.newSystemType,
|
|
40
|
+
choices: [
|
|
41
|
+
{ name: (0, i18n_1.t)('prompts.newSystemType.choiceAbapOnBtp'), value: 'abapOnBtp' },
|
|
42
|
+
{ name: (0, i18n_1.t)('prompts.newSystemType.choiceAbapOnPrem'), value: 'abapOnPrem' }
|
|
43
|
+
],
|
|
44
|
+
message: (0, i18n_1.t)('prompts.newSystemType.message'),
|
|
45
|
+
additionalMessages: (systemType) => {
|
|
46
|
+
if (['abapOnBtp'].includes(systemType)) {
|
|
47
|
+
logger_helper_1.default.logger?.warn((0, i18n_1.t)('prompts.systemType.notYetImplementedWarningMessage', { systemType }));
|
|
48
|
+
return {
|
|
49
|
+
message: (0, i18n_1.t)('prompts.systemType.notYetImplementedWarningMessage', { systemType }),
|
|
50
|
+
severity: yeoman_ui_types_1.Severity.warning
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
];
|
|
56
|
+
questions.push(...(0, inquirer_common_1.withCondition)((0, questions_1.getAbapOnPremQuestions)(promptOptions), (answers) => answers.newSystemType === 'abapOnPrem'));
|
|
57
|
+
return questions;
|
|
58
|
+
}
|
|
59
|
+
exports.getNewSystemQuestions = getNewSystemQuestions;
|
|
60
|
+
/**
|
|
61
|
+
* Get a prompt for new system name.
|
|
62
|
+
*
|
|
63
|
+
* @returns the new system name prompt
|
|
64
|
+
*/
|
|
65
|
+
function getUserSystemNameQuestion() {
|
|
66
|
+
let defaultSystemName;
|
|
67
|
+
const newSystemNamePrompt = {
|
|
68
|
+
type: 'input',
|
|
69
|
+
guiOptions: {
|
|
70
|
+
hint: (0, i18n_1.t)('prompts.systemName.hint'),
|
|
71
|
+
applyDefaultWhenDirty: true,
|
|
72
|
+
breadcrumb: true
|
|
73
|
+
},
|
|
74
|
+
name: types_1.promptNames.userSystemName,
|
|
75
|
+
message: (0, i18n_1.t)('prompts.systemName.message'),
|
|
76
|
+
default: async (answers) => {
|
|
77
|
+
if (answers.newSystemType === 'abapOnPrem' && answers.systemUrl) {
|
|
78
|
+
defaultSystemName = await (0, prompt_helpers_1.suggestSystemName)(answers.systemUrl, answers.sapClient);
|
|
79
|
+
}
|
|
80
|
+
return defaultSystemName;
|
|
81
|
+
},
|
|
82
|
+
validate: async (systemName, answers) => {
|
|
83
|
+
let validationResult = false;
|
|
84
|
+
// Dont validate the suggested default system name
|
|
85
|
+
if (systemName === defaultSystemName) {
|
|
86
|
+
validationResult = true;
|
|
87
|
+
}
|
|
88
|
+
validationResult = await (0, validators_1.validateSystemName)(systemName);
|
|
89
|
+
if (validationResult === true) {
|
|
90
|
+
const backendSystem = new store_1.BackendSystem({
|
|
91
|
+
name: systemName,
|
|
92
|
+
url: answers.systemUrl,
|
|
93
|
+
client: answers.sapClient,
|
|
94
|
+
username: answers.abapSystemUsername,
|
|
95
|
+
password: answers.abapSystemPassword
|
|
96
|
+
});
|
|
97
|
+
if (utils_1.PromptState.odataService.connectedSystem) {
|
|
98
|
+
utils_1.PromptState.odataService.connectedSystem.backendSystem = backendSystem;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return validationResult;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
return newSystemNamePrompt;
|
|
105
|
+
}
|
|
106
|
+
exports.getUserSystemNameQuestion = getUserSystemNameQuestion;
|
|
107
|
+
//# sourceMappingURL=questions.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides a system name suggestion based on the system URL, system ID, and client, validating the name is unique against the secure store.
|
|
3
|
+
*
|
|
4
|
+
* @param systemUrl the system URL origin
|
|
5
|
+
* @param client the sap client to use for the system
|
|
6
|
+
* @returns a unique system name suggestion
|
|
7
|
+
*/
|
|
8
|
+
export declare function suggestSystemName(systemUrl: string, client?: string): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=prompt-helpers.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.suggestSystemName = void 0;
|
|
4
|
+
const i18n_1 = require("../../../i18n");
|
|
5
|
+
const validators_1 = require("./validators");
|
|
6
|
+
/**
|
|
7
|
+
* Provides a system name suggestion based on the system URL, system ID, and client, validating the name is unique against the secure store.
|
|
8
|
+
*
|
|
9
|
+
* @param systemUrl the system URL origin
|
|
10
|
+
* @param client the sap client to use for the system
|
|
11
|
+
* @returns a unique system name suggestion
|
|
12
|
+
*/
|
|
13
|
+
async function suggestSystemName(systemUrl, client) {
|
|
14
|
+
const initialSystemName = systemUrl + (client ? (0, i18n_1.t)('texts.suggestedSystemNameClient', { client }) : '');
|
|
15
|
+
if ((await (0, validators_1.validateSystemName)(initialSystemName)) === true) {
|
|
16
|
+
return initialSystemName;
|
|
17
|
+
}
|
|
18
|
+
// If initial suggested name is taken, append a suffix
|
|
19
|
+
return appendSuffix(initialSystemName);
|
|
20
|
+
}
|
|
21
|
+
exports.suggestSystemName = suggestSystemName;
|
|
22
|
+
/**
|
|
23
|
+
* Appends a suffix to the system name to make it unique.
|
|
24
|
+
*
|
|
25
|
+
* @param systemName system name to use as a base name for finding a unique name
|
|
26
|
+
* @returns suffixed system name
|
|
27
|
+
*/
|
|
28
|
+
async function appendSuffix(systemName) {
|
|
29
|
+
let suffixNumber = 1;
|
|
30
|
+
let suffixedSystemName = `${systemName} (${suffixNumber})`;
|
|
31
|
+
while ((await (0, validators_1.validateSystemName)(suffixedSystemName)) !== true) {
|
|
32
|
+
suffixedSystemName = `${systemName} (${suffixNumber})`;
|
|
33
|
+
suffixNumber++;
|
|
34
|
+
}
|
|
35
|
+
return suffixedSystemName;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=prompt-helpers.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates that the system name does not exist yet.
|
|
3
|
+
*
|
|
4
|
+
* @param systemName a system name to validate
|
|
5
|
+
* @returns true if the name is valid, otherwise an error message
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateSystemName(systemName: string): Promise<boolean | string>;
|
|
8
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateSystemName = void 0;
|
|
7
|
+
const i18n_1 = require("../../../i18n");
|
|
8
|
+
const store_1 = require("@sap-ux/store");
|
|
9
|
+
const logger_helper_1 = __importDefault(require("../../logger-helper"));
|
|
10
|
+
/**
|
|
11
|
+
* Check if the system name is already in use.
|
|
12
|
+
*
|
|
13
|
+
* @param systemName a system name to check
|
|
14
|
+
* @returns true if the system name is already in use, otherwise false
|
|
15
|
+
*/
|
|
16
|
+
async function isSystemNameInUse(systemName) {
|
|
17
|
+
const backendSystems = await new store_1.SystemService(logger_helper_1.default.logger).getAll();
|
|
18
|
+
return !!backendSystems.find((system) => system.name === systemName);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validates that the system name does not exist yet.
|
|
22
|
+
*
|
|
23
|
+
* @param systemName a system name to validate
|
|
24
|
+
* @returns true if the name is valid, otherwise an error message
|
|
25
|
+
*/
|
|
26
|
+
async function validateSystemName(systemName) {
|
|
27
|
+
const systemExists = await isSystemNameInUse(systemName);
|
|
28
|
+
if (systemExists) {
|
|
29
|
+
return (0, i18n_1.t)('prompts.systemName.systemNameExistsWarning');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.validateSystemName = validateSystemName;
|
|
36
|
+
//# sourceMappingURL=validators.js.map
|