@sap-ux/odata-service-inquirer 0.5.60 → 0.6.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 +25 -3
- package/dist/error-handler/error-handler.js +154 -52
- package/dist/i18n.js +15 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -3
- package/dist/prompts/connectionValidator.d.ts +63 -12
- package/dist/prompts/connectionValidator.js +196 -38
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.d.ts +2 -1
- package/dist/prompts/datasources/sap-system/abap-on-btp/questions.js +3 -1
- package/dist/prompts/datasources/sap-system/abap-on-prem/questions.d.ts +9 -11
- package/dist/prompts/datasources/sap-system/abap-on-prem/questions.js +21 -55
- package/dist/prompts/datasources/sap-system/credentials/questions.d.ts +21 -0
- package/dist/prompts/datasources/sap-system/credentials/questions.js +123 -0
- package/dist/prompts/datasources/sap-system/new-system/questions.d.ts +4 -26
- package/dist/prompts/datasources/sap-system/new-system/questions.js +18 -168
- package/dist/prompts/datasources/sap-system/new-system/types.d.ts +0 -10
- package/dist/prompts/datasources/sap-system/service-selection/index.d.ts +3 -0
- package/dist/prompts/datasources/sap-system/service-selection/index.js +19 -0
- package/dist/prompts/datasources/sap-system/service-selection/questions.d.ts +15 -0
- package/dist/prompts/datasources/sap-system/service-selection/questions.js +146 -0
- package/dist/prompts/datasources/sap-system/service-selection/service-helper.d.ts +71 -0
- package/dist/prompts/datasources/sap-system/service-selection/service-helper.js +281 -0
- package/dist/prompts/datasources/sap-system/service-selection/types.d.ts +11 -0
- package/dist/prompts/datasources/sap-system/service-selection/types.js +3 -0
- package/dist/prompts/datasources/sap-system/system-selection/index.d.ts +2 -0
- package/dist/prompts/datasources/sap-system/system-selection/index.js +18 -0
- package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.d.ts +44 -0
- package/dist/prompts/datasources/sap-system/system-selection/prompt-helpers.js +190 -0
- package/dist/prompts/datasources/sap-system/system-selection/questions.d.ts +40 -0
- package/dist/prompts/datasources/sap-system/system-selection/questions.js +181 -0
- package/dist/prompts/datasources/sap-system/validators.d.ts +8 -0
- package/dist/prompts/datasources/sap-system/validators.js +17 -0
- package/dist/prompts/datasources/service-url/questions.js +2 -2
- package/dist/prompts/datasources/service-url/validators.js +5 -6
- package/dist/prompts/prompt-helpers.d.ts +1 -2
- package/dist/prompts/prompt-helpers.js +2 -11
- package/dist/prompts/prompts.js +5 -34
- package/dist/prompts/validators.d.ts +1 -1
- package/dist/prompts/validators.js +1 -1
- package/dist/translations/odata-service-inquirer.i18n.json +36 -15
- package/dist/types.d.ts +57 -10
- package/dist/types.js +7 -1
- package/dist/utils/index.d.ts +12 -3
- package/dist/utils/index.js +27 -5
- package/package.json +6 -6
- package/dist/prompts/datasources/sap-system/new-system/service-helper.d.ts +0 -43
- package/dist/prompts/datasources/sap-system/new-system/service-helper.js +0 -175
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Destination } from '@sap-ux/btp-utils';
|
|
1
2
|
import { type Logger } from '@sap-ux/logger';
|
|
2
3
|
import { ValidationLink } from '../types';
|
|
3
4
|
/**
|
|
@@ -17,7 +18,7 @@ export declare enum ERROR_TYPE {
|
|
|
17
18
|
TIMEOUT = "TIMEOUT",
|
|
18
19
|
CONNECTION = "CONNECTION",
|
|
19
20
|
SERVICES_UNAVAILABLE = "SERVICES_UNAVAILABLE",// All services
|
|
20
|
-
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",//
|
|
21
|
+
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",// HTTP 503 Not related to odata services
|
|
21
22
|
NO_ABAP_ENVS = "NO_ABAP_ENVS",
|
|
22
23
|
CATALOG_SERVICE_NOT_ACTIVE = "CATALOG_SERVICE_NOT_ACTIVE",
|
|
23
24
|
NO_SUCH_HOST = "NO_SUCH_HOST",
|
|
@@ -30,7 +31,10 @@ export declare enum ERROR_TYPE {
|
|
|
30
31
|
DESTINATION_NOT_FOUND = "DESTINATION_NOT_FOUND",
|
|
31
32
|
DESTINATION_MISCONFIGURED = "DESTINATION_MISCONFIGURED",
|
|
32
33
|
NO_V2_SERVICES = "NO_V2_SERVICES",
|
|
33
|
-
NO_V4_SERVICES = "NO_V4_SERVICES"
|
|
34
|
+
NO_V4_SERVICES = "NO_V4_SERVICES",
|
|
35
|
+
BAD_REQUEST = "BAD_REQUEST",
|
|
36
|
+
DESTINATION_CONNECTION_ERROR = "DESTINATION_CONNECTION_ERROR",// General destination connection error where a specific root cause cannot be determined e.g. In the case of an internal server error
|
|
37
|
+
SERVER_HTTP_ERROR = "SERVER_HTTP_ERROR"
|
|
34
38
|
}
|
|
35
39
|
export declare const ERROR_MAP: Record<ERROR_TYPE, RegExp[]>;
|
|
36
40
|
type ValidationLinkOrString = string | ValidationLink;
|
|
@@ -45,6 +49,14 @@ export declare class ErrorHandler {
|
|
|
45
49
|
private currentErrorType;
|
|
46
50
|
private static _guidedAnswersEnabled;
|
|
47
51
|
private static _logger;
|
|
52
|
+
private static readonly getMessageFromError;
|
|
53
|
+
private static readonly _errorTypeToMsg;
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param errorType
|
|
57
|
+
* @param error can be any object that will get stringified and passed to the specific error message for the error type entry, e.g. where the error message is parameterized
|
|
58
|
+
* @returns an error message for the specified error type
|
|
59
|
+
*/
|
|
48
60
|
private static readonly _errorMsg;
|
|
49
61
|
/**
|
|
50
62
|
* Get the Guided Answers (help) node for the specified error type.
|
|
@@ -134,12 +146,22 @@ export declare class ErrorHandler {
|
|
|
134
146
|
* Used by validate functions to report in-line user friendly errors messages with help links.
|
|
135
147
|
* If the error type is unknown, this will find a mapped error type and return the help (ValidationLink) if it exists.
|
|
136
148
|
* If an error is not provided the current error state will be used. This does not log the message to the console.
|
|
149
|
+
* If a system is provided, the error type may be refined to provide a more specific error message for the system which generatd the error.
|
|
137
150
|
*
|
|
138
151
|
* @param error optional, if provided get the help link message that it maps to, otherwise get the previously logged error message help link
|
|
139
152
|
* @param reset optional, resets the previous error state if true
|
|
153
|
+
* @param destination optional, if provided the destination may be used to determine a more relevant error message, specific to the system properties
|
|
140
154
|
* @returns An instance of @see {ValidationLink}
|
|
141
155
|
*/
|
|
142
|
-
getValidationErrorHelp(error?: any, reset?: boolean): ValidationLinkOrString | undefined;
|
|
156
|
+
getValidationErrorHelp(error?: any, reset?: boolean, destination?: Destination): ValidationLinkOrString | undefined;
|
|
157
|
+
/**
|
|
158
|
+
* Get a more specific error type for the specified destination.
|
|
159
|
+
*
|
|
160
|
+
* @param errorType
|
|
161
|
+
* @param destination
|
|
162
|
+
* @returns
|
|
163
|
+
*/
|
|
164
|
+
private static getDestinationSpecificError;
|
|
143
165
|
/**
|
|
144
166
|
* Get the error message for the specified error type.
|
|
145
167
|
*
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ErrorHandler = exports.ERROR_MAP = exports.ERROR_TYPE = void 0;
|
|
4
4
|
const btp_utils_1 = require("@sap-ux/btp-utils");
|
|
5
|
+
const guided_answers_helper_1 = require("@sap-ux/guided-answers-helper");
|
|
5
6
|
const logger_1 = require("@sap-ux/logger");
|
|
6
7
|
const i18n_1 = require("../i18n");
|
|
7
8
|
const types_1 = require("../types");
|
|
8
9
|
const utils_1 = require("../utils");
|
|
9
|
-
|
|
10
|
-
const
|
|
10
|
+
// Telemetry event names specific to odata service error handling
|
|
11
|
+
const telemEventGALinkCreated = 'GA_LINK_CREATED';
|
|
12
|
+
const telemBasError = 'SERVICE_INQUIRER_BAS_ERROR';
|
|
11
13
|
/**
|
|
12
14
|
* Constants specific to error handling
|
|
13
15
|
*/
|
|
@@ -40,6 +42,9 @@ var ERROR_TYPE;
|
|
|
40
42
|
ERROR_TYPE["DESTINATION_MISCONFIGURED"] = "DESTINATION_MISCONFIGURED";
|
|
41
43
|
ERROR_TYPE["NO_V2_SERVICES"] = "NO_V2_SERVICES";
|
|
42
44
|
ERROR_TYPE["NO_V4_SERVICES"] = "NO_V4_SERVICES";
|
|
45
|
+
ERROR_TYPE["BAD_REQUEST"] = "BAD_REQUEST";
|
|
46
|
+
ERROR_TYPE["DESTINATION_CONNECTION_ERROR"] = "DESTINATION_CONNECTION_ERROR";
|
|
47
|
+
ERROR_TYPE["SERVER_HTTP_ERROR"] = "SERVER_HTTP_ERROR";
|
|
43
48
|
})(ERROR_TYPE || (exports.ERROR_TYPE = ERROR_TYPE = {}));
|
|
44
49
|
// Used to match regex expressions to error messages, etc. providing a way to return a consistent
|
|
45
50
|
// single error and error msg for multiple errors
|
|
@@ -83,7 +88,10 @@ exports.ERROR_MAP = {
|
|
|
83
88
|
[ERROR_TYPE.DESTINATION_NOT_FOUND]: [],
|
|
84
89
|
[ERROR_TYPE.DESTINATION_MISCONFIGURED]: [],
|
|
85
90
|
[ERROR_TYPE.NO_V2_SERVICES]: [],
|
|
86
|
-
[ERROR_TYPE.NO_V4_SERVICES]: []
|
|
91
|
+
[ERROR_TYPE.NO_V4_SERVICES]: [],
|
|
92
|
+
[ERROR_TYPE.BAD_REQUEST]: [/400/],
|
|
93
|
+
[ERROR_TYPE.DESTINATION_CONNECTION_ERROR]: [],
|
|
94
|
+
[ERROR_TYPE.SERVER_HTTP_ERROR]: [/5\d\d/] // catch all for 5xx server errors
|
|
87
95
|
};
|
|
88
96
|
/**
|
|
89
97
|
* Maps errors to end-user messages using some basic root cause analysis based on regex matching.
|
|
@@ -96,48 +104,87 @@ class ErrorHandler {
|
|
|
96
104
|
currentErrorType;
|
|
97
105
|
static _guidedAnswersEnabled;
|
|
98
106
|
static _logger;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
static getMessageFromError = (error) => {
|
|
108
|
+
return (error?.message ||
|
|
109
|
+
error?.status?.toString() ||
|
|
110
|
+
error?.response?.status?.toString() ||
|
|
111
|
+
(typeof error === 'string' ? error : JSON.stringify(error)));
|
|
112
|
+
};
|
|
113
|
+
// Get the localized parameterized error message for the specified error type
|
|
114
|
+
static _errorTypeToMsg = {
|
|
115
|
+
[ERROR_TYPE.CERT]: (error) => (0, i18n_1.t)('errors.certificateError', { error: typeof error === 'string' ? error : JSON.stringify(error) }),
|
|
116
|
+
[ERROR_TYPE.CERT_EXPIRED]: () => (0, i18n_1.t)('errors.urlCertValidationError', { certErrorReason: (0, i18n_1.t)('texts.anExpiredCert') }),
|
|
117
|
+
[ERROR_TYPE.CERT_SELF_SIGNED]: () => (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
106
118
|
certErrorReason: (0, i18n_1.t)('texts.aSelfSignedCert')
|
|
107
119
|
}),
|
|
108
|
-
[ERROR_TYPE.CERT_UKNOWN_OR_INVALID]: (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
120
|
+
[ERROR_TYPE.CERT_UKNOWN_OR_INVALID]: () => (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
109
121
|
certErrorReason: (0, i18n_1.t)('texts.anUnknownOrInvalidCert')
|
|
110
122
|
}),
|
|
111
|
-
[ERROR_TYPE.CERT_SELF_SIGNED_CERT_IN_CHAIN]: (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
123
|
+
[ERROR_TYPE.CERT_SELF_SIGNED_CERT_IN_CHAIN]: () => (0, i18n_1.t)('errors.urlCertValidationError', {
|
|
112
124
|
certErrorReason: (0, i18n_1.t)('texts.anUntrustedRootCert')
|
|
113
125
|
}),
|
|
114
|
-
[ERROR_TYPE.AUTH]: (0, i18n_1.t)('errors.authenticationFailed', {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
[ERROR_TYPE.
|
|
118
|
-
[ERROR_TYPE.
|
|
119
|
-
|
|
126
|
+
[ERROR_TYPE.AUTH]: (error) => (0, i18n_1.t)('errors.authenticationFailed', {
|
|
127
|
+
error: ErrorHandler.getMessageFromError(error)
|
|
128
|
+
}),
|
|
129
|
+
[ERROR_TYPE.AUTH_TIMEOUT]: () => (0, i18n_1.t)('errors.authenticationTimeout'),
|
|
130
|
+
[ERROR_TYPE.TIMEOUT]: (error) => (0, i18n_1.t)('errors.timeout', { error: typeof error === 'string' ? error : JSON.stringify(error) }),
|
|
131
|
+
[ERROR_TYPE.INVALID_URL]: () => (0, i18n_1.t)('errors.invalidUrl'),
|
|
132
|
+
[ERROR_TYPE.CONNECTION]: (error) => (0, i18n_1.t)('errors.connectionError', {
|
|
133
|
+
error: ErrorHandler.getMessageFromError(error)
|
|
120
134
|
}),
|
|
121
|
-
[ERROR_TYPE.UNKNOWN]: (0, i18n_1.t)('errors.unknownError', {
|
|
122
|
-
error:
|
|
135
|
+
[ERROR_TYPE.UNKNOWN]: (error) => (0, i18n_1.t)('errors.unknownError', {
|
|
136
|
+
error: ErrorHandler.getMessageFromError(error)
|
|
137
|
+
}),
|
|
138
|
+
[ERROR_TYPE.SERVICES_UNAVAILABLE]: () => (0, i18n_1.t)('errors.servicesUnavailable'),
|
|
139
|
+
[ERROR_TYPE.SERVICE_UNAVAILABLE]: (error) => (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
140
|
+
errorMsg: ErrorHandler.getMessageFromError(error)
|
|
141
|
+
}),
|
|
142
|
+
[ERROR_TYPE.CATALOG_SERVICE_NOT_ACTIVE]: () => (0, i18n_1.t)('errors.catalogServiceNotActive'),
|
|
143
|
+
[ERROR_TYPE.INTERNAL_SERVER_ERROR]: (error) => {
|
|
144
|
+
const errorMsg = ErrorHandler.getMessageFromError(error);
|
|
145
|
+
return (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
146
|
+
errorDesc: (0, i18n_1.t)('errors.internalServerError', { errorMsg })
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
[ERROR_TYPE.NOT_FOUND]: () => (0, i18n_1.t)('errors.urlNotFound'),
|
|
150
|
+
[ERROR_TYPE.ODATA_URL_NOT_FOUND]: () => (0, i18n_1.t)('errors.odataServiceUrlNotFound'),
|
|
151
|
+
[ERROR_TYPE.BAD_GATEWAY]: (error) => {
|
|
152
|
+
const errorMsg = ErrorHandler.getMessageFromError(error);
|
|
153
|
+
return (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
154
|
+
errorDesc: (0, i18n_1.t)('errors.badGateway', { errorMsg })
|
|
155
|
+
});
|
|
156
|
+
},
|
|
157
|
+
[ERROR_TYPE.DESTINATION_UNAVAILABLE]: () => (0, i18n_1.t)('errors.destination.unavailable'),
|
|
158
|
+
[ERROR_TYPE.DESTINATION_NOT_FOUND]: () => (0, i18n_1.t)('errors.destination.notFound'),
|
|
159
|
+
[ERROR_TYPE.DESTINATION_MISCONFIGURED]: (error) => (0, i18n_1.t)('errors.destination.misconfigured', {
|
|
160
|
+
destinationProperty: typeof error === 'string' ? error : JSON.stringify(error)
|
|
123
161
|
}),
|
|
124
|
-
[ERROR_TYPE.
|
|
125
|
-
[ERROR_TYPE.
|
|
126
|
-
[ERROR_TYPE.
|
|
127
|
-
[ERROR_TYPE.
|
|
128
|
-
[ERROR_TYPE.
|
|
129
|
-
[ERROR_TYPE.
|
|
130
|
-
[ERROR_TYPE.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
[ERROR_TYPE.
|
|
137
|
-
[ERROR_TYPE.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
162
|
+
[ERROR_TYPE.NO_V2_SERVICES]: () => (0, i18n_1.t)('errors.noServicesAvailable', { version: '2' }),
|
|
163
|
+
[ERROR_TYPE.NO_V4_SERVICES]: () => (0, i18n_1.t)('errors.noServicesAvailable', { version: '4' }),
|
|
164
|
+
[ERROR_TYPE.DESTINATION_BAD_GATEWAY_503]: () => (0, i18n_1.t)('errors.destination.unavailable'),
|
|
165
|
+
[ERROR_TYPE.REDIRECT]: () => (0, i18n_1.t)('errors.redirectError'),
|
|
166
|
+
[ERROR_TYPE.NO_SUCH_HOST]: () => (0, i18n_1.t)('errors.noSuchHostError'),
|
|
167
|
+
[ERROR_TYPE.NO_ABAP_ENVS]: () => (0, i18n_1.t)('errors.abapEnvsUnavailable'),
|
|
168
|
+
[ERROR_TYPE.BAD_REQUEST]: (error) => {
|
|
169
|
+
const errorMsg = ErrorHandler.getMessageFromError(error);
|
|
170
|
+
return (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
171
|
+
errorDesc: (0, i18n_1.t)('errors.badRequest', { errorMsg })
|
|
172
|
+
});
|
|
173
|
+
},
|
|
174
|
+
[ERROR_TYPE.DESTINATION_CONNECTION_ERROR]: () => (0, i18n_1.t)('errors.systemConnectionValidationFailed'),
|
|
175
|
+
[ERROR_TYPE.SERVER_HTTP_ERROR]: (error) => (0, i18n_1.t)('errors.serverReturnedAnError', {
|
|
176
|
+
errorDesc: ErrorHandler.getMessageFromError(error)
|
|
177
|
+
})
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
*
|
|
181
|
+
* @param errorType
|
|
182
|
+
* @param error can be any object that will get stringified and passed to the specific error message for the error type entry, e.g. where the error message is parameterized
|
|
183
|
+
* @returns an error message for the specified error type
|
|
184
|
+
*/
|
|
185
|
+
static _errorMsg = (errorType, error) => {
|
|
186
|
+
return ErrorHandler._errorTypeToMsg[errorType](error);
|
|
187
|
+
};
|
|
141
188
|
/**
|
|
142
189
|
* Get the Guided Answers (help) node for the specified error type.
|
|
143
190
|
*
|
|
@@ -174,7 +221,10 @@ class ErrorHandler {
|
|
|
174
221
|
[ERROR_TYPE.ODATA_URL_NOT_FOUND]: undefined,
|
|
175
222
|
[ERROR_TYPE.INTERNAL_SERVER_ERROR]: undefined,
|
|
176
223
|
[ERROR_TYPE.NO_V2_SERVICES]: undefined,
|
|
177
|
-
[ERROR_TYPE.TIMEOUT]: undefined
|
|
224
|
+
[ERROR_TYPE.TIMEOUT]: undefined,
|
|
225
|
+
[ERROR_TYPE.BAD_REQUEST]: undefined,
|
|
226
|
+
[ERROR_TYPE.DESTINATION_CONNECTION_ERROR]: guided_answers_helper_1.HELP_NODES.DESTINATION_CONNECTION_ERRORS,
|
|
227
|
+
[ERROR_TYPE.SERVER_HTTP_ERROR]: undefined
|
|
178
228
|
};
|
|
179
229
|
return errorToHelp[errorType];
|
|
180
230
|
};
|
|
@@ -310,7 +360,7 @@ class ErrorHandler {
|
|
|
310
360
|
errorType = ErrorHandler.getErrorType(this.findErrorValueForMapping(error)) ?? ERROR_TYPE.UNKNOWN;
|
|
311
361
|
}
|
|
312
362
|
return {
|
|
313
|
-
errorMsg: ErrorHandler._errorMsg(error)
|
|
363
|
+
errorMsg: ErrorHandler._errorMsg(errorType, error),
|
|
314
364
|
errorType
|
|
315
365
|
};
|
|
316
366
|
}
|
|
@@ -342,31 +392,83 @@ class ErrorHandler {
|
|
|
342
392
|
* Used by validate functions to report in-line user friendly errors messages with help links.
|
|
343
393
|
* If the error type is unknown, this will find a mapped error type and return the help (ValidationLink) if it exists.
|
|
344
394
|
* If an error is not provided the current error state will be used. This does not log the message to the console.
|
|
395
|
+
* If a system is provided, the error type may be refined to provide a more specific error message for the system which generatd the error.
|
|
345
396
|
*
|
|
346
397
|
* @param error optional, if provided get the help link message that it maps to, otherwise get the previously logged error message help link
|
|
347
398
|
* @param reset optional, resets the previous error state if true
|
|
399
|
+
* @param destination optional, if provided the destination may be used to determine a more relevant error message, specific to the system properties
|
|
348
400
|
* @returns An instance of @see {ValidationLink}
|
|
349
401
|
*/
|
|
350
|
-
getValidationErrorHelp(error, reset = false) {
|
|
402
|
+
getValidationErrorHelp(error, reset = false, destination) {
|
|
351
403
|
let errorHelp;
|
|
352
|
-
let
|
|
404
|
+
let resolvedErrorMsg;
|
|
405
|
+
let resolvedErrorType;
|
|
353
406
|
if (error) {
|
|
354
|
-
|
|
355
|
-
if (resolvedError.errorType !== ERROR_TYPE.UNKNOWN) {
|
|
356
|
-
errorHelp = ErrorHandler.getHelpForError(resolvedError.errorType, resolvedError.errorMsg);
|
|
357
|
-
}
|
|
407
|
+
({ errorMsg: resolvedErrorMsg, errorType: resolvedErrorType } = ErrorHandler.mapErrorToMsg(error));
|
|
358
408
|
}
|
|
359
|
-
else
|
|
360
|
-
|
|
409
|
+
else {
|
|
410
|
+
// Use the existing error if we have it
|
|
411
|
+
resolvedErrorMsg = this.currentErrorMsg ?? undefined;
|
|
361
412
|
if (this.currentErrorType) {
|
|
362
|
-
|
|
413
|
+
resolvedErrorType = this.currentErrorType;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (resolvedErrorType) {
|
|
417
|
+
// If the destination is provided, we can refine the error type and therefore the generated help message, to be more specific
|
|
418
|
+
if (destination) {
|
|
419
|
+
const { errorType: destErrorType, errorMsg: destErrorMsg } = ErrorHandler.getDestinationSpecificError(resolvedErrorType, destination);
|
|
420
|
+
resolvedErrorMsg = destErrorMsg ?? resolvedErrorMsg;
|
|
421
|
+
resolvedErrorType = destErrorType ?? resolvedErrorType;
|
|
422
|
+
}
|
|
423
|
+
if (resolvedErrorType) {
|
|
424
|
+
errorHelp = ErrorHandler.getHelpForError(resolvedErrorType, resolvedErrorMsg);
|
|
363
425
|
}
|
|
364
426
|
}
|
|
365
427
|
if (reset) {
|
|
366
428
|
this.currentErrorMsg = null;
|
|
367
429
|
this.currentErrorType = null;
|
|
368
430
|
}
|
|
369
|
-
return errorHelp ??
|
|
431
|
+
return errorHelp ?? resolvedErrorMsg; // We mau not have a help link, so return the resolvedend user message
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Get a more specific error type for the specified destination.
|
|
435
|
+
*
|
|
436
|
+
* @param errorType
|
|
437
|
+
* @param destination
|
|
438
|
+
* @returns
|
|
439
|
+
*/
|
|
440
|
+
static getDestinationSpecificError(errorType, destination) {
|
|
441
|
+
let destErrorType;
|
|
442
|
+
let destErrorMsg;
|
|
443
|
+
// Add more specific error types for destinations here
|
|
444
|
+
if (!(0, btp_utils_1.isHTML5DynamicConfigured)(destination)) {
|
|
445
|
+
destErrorType = ERROR_TYPE.DESTINATION_MISCONFIGURED;
|
|
446
|
+
destErrorMsg = this.getErrorMsgFromType(destErrorType, 'HTML5.DynamicDestination');
|
|
447
|
+
}
|
|
448
|
+
else if (errorType === ERROR_TYPE.SERVICE_UNAVAILABLE) {
|
|
449
|
+
if ((0, btp_utils_1.isOnPremiseDestination)(destination)) {
|
|
450
|
+
destErrorType = ERROR_TYPE.DESTINATION_BAD_GATEWAY_503; // Remap to specific gateway to allow GA link to be associated
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
destErrorType = ERROR_TYPE.DESTINATION_CONNECTION_ERROR; // General destination connection error, GA link to connection page
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
else if (errorType === ERROR_TYPE.NOT_FOUND) {
|
|
457
|
+
destErrorType = ERROR_TYPE.DESTINATION_NOT_FOUND;
|
|
458
|
+
}
|
|
459
|
+
else if (ERROR_TYPE.INTERNAL_SERVER_ERROR === errorType || ERROR_TYPE.SERVER_HTTP_ERROR === errorType) {
|
|
460
|
+
// We cannot tell in BAS what this means, so we will just say the connection failed
|
|
461
|
+
destErrorType = ERROR_TYPE.DESTINATION_CONNECTION_ERROR;
|
|
462
|
+
}
|
|
463
|
+
// Always raise a telemetry event for destination related errors
|
|
464
|
+
(0, utils_1.sendTelemetryEvent)(telemBasError, {
|
|
465
|
+
basErrorType: destErrorType ?? errorType,
|
|
466
|
+
destODataType: (0, utils_1.getTelemPropertyDestinationType)(destination)
|
|
467
|
+
});
|
|
468
|
+
return {
|
|
469
|
+
errorType: destErrorType ?? errorType,
|
|
470
|
+
errorMsg: destErrorMsg
|
|
471
|
+
};
|
|
370
472
|
}
|
|
371
473
|
/**
|
|
372
474
|
* Get the error message for the specified error type.
|
|
@@ -377,7 +479,7 @@ class ErrorHandler {
|
|
|
377
479
|
*/
|
|
378
480
|
static getErrorMsgFromType(errorType, error) {
|
|
379
481
|
if (ERROR_TYPE[errorType]) {
|
|
380
|
-
return ErrorHandler._errorMsg(
|
|
482
|
+
return ErrorHandler._errorMsg(ERROR_TYPE[errorType], error);
|
|
381
483
|
}
|
|
382
484
|
return undefined;
|
|
383
485
|
}
|
|
@@ -402,7 +504,7 @@ class ErrorHandler {
|
|
|
402
504
|
* @param error - the original error, if any
|
|
403
505
|
*/
|
|
404
506
|
setCurrentError(errorType, error) {
|
|
405
|
-
this.currentErrorMsg = ErrorHandler._errorMsg(
|
|
507
|
+
this.currentErrorMsg = ErrorHandler._errorMsg(ERROR_TYPE[errorType], error);
|
|
406
508
|
this.currentErrorType = errorType;
|
|
407
509
|
}
|
|
408
510
|
/**
|
|
@@ -451,7 +553,7 @@ class ErrorHandler {
|
|
|
451
553
|
};
|
|
452
554
|
}
|
|
453
555
|
// Report the GA link created event
|
|
454
|
-
(0, utils_1.sendTelemetryEvent)(
|
|
556
|
+
(0, utils_1.sendTelemetryEvent)(telemEventGALinkCreated, {
|
|
455
557
|
errorType,
|
|
456
558
|
isGuidedAnswersEnabled: this.guidedAnswersEnabled,
|
|
457
559
|
nodeIdPath: `${helpNode}`
|
package/dist/i18n.js
CHANGED
|
@@ -14,16 +14,28 @@ exports.defaultProjectNumber = 1;
|
|
|
14
14
|
* Initialize i18next with the translations for this module.
|
|
15
15
|
*/
|
|
16
16
|
async function initI18nOdataServiceInquirer() {
|
|
17
|
+
const t0 = performance.now();
|
|
17
18
|
await i18next_1.default.init({
|
|
18
19
|
lng: 'en',
|
|
19
20
|
fallbackLng: 'en',
|
|
20
21
|
missingInterpolationHandler: () => '',
|
|
21
22
|
interpolation: {
|
|
22
|
-
format: function
|
|
23
|
-
|
|
23
|
+
format: function (value, format) {
|
|
24
|
+
// OData version formatter
|
|
25
|
+
if (format === 'odataVersionFormatter') {
|
|
26
|
+
return value ? ` V${value}` : '';
|
|
27
|
+
}
|
|
28
|
+
// If we have a value add a colon before outputting
|
|
29
|
+
if (format === 'addMsgWithColonFormatter') {
|
|
30
|
+
return value ? `: ${value}` : '';
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
|
-
}
|
|
35
|
+
});
|
|
36
|
+
i18next_1.default.addResourceBundle('en', odataServiceInquirerNamespace, odata_service_inquirer_i18n_json_1.default);
|
|
37
|
+
const t1 = performance.now();
|
|
38
|
+
console.log(`i18n load time: ${Math.round(t1 - t0)} milliseconds`);
|
|
27
39
|
}
|
|
28
40
|
/**
|
|
29
41
|
* Helper function facading the call to i18next. Unless a namespace option is provided the local namespace will be used.
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type Logger } from '@sap-ux/logger';
|
|
|
3
3
|
import { OdataVersion } from '@sap-ux/odata-service-writer';
|
|
4
4
|
import { type ToolsSuiteTelemetryClient } from '@sap-ux/telemetry';
|
|
5
5
|
import { ERROR_TYPE, ErrorHandler } from './error-handler/error-handler';
|
|
6
|
-
import {
|
|
6
|
+
import { SystemSelectionAnswerType } from './prompts/datasources/sap-system/system-selection';
|
|
7
7
|
import { DatasourceType, promptNames, type CapRuntime, type CapService, type OdataServiceAnswers, type OdataServicePromptOptions, type OdataServiceQuestion, type SapSystemType } from './types';
|
|
8
8
|
/**
|
|
9
9
|
* Get the inquirer prompts for odata service.
|
|
@@ -31,5 +31,5 @@ declare function getPrompts(promptOptions?: OdataServicePromptOptions, logger?:
|
|
|
31
31
|
* @returns the prompt answers
|
|
32
32
|
*/
|
|
33
33
|
declare function prompt(adapter: InquirerAdapter, promptOptions?: OdataServicePromptOptions, logger?: Logger, enableGuidedAnswers?: boolean, telemetryClient?: ToolsSuiteTelemetryClient, isYUI?: boolean): Promise<OdataServiceAnswers>;
|
|
34
|
-
export { DatasourceType, ERROR_TYPE, ErrorHandler,
|
|
34
|
+
export { DatasourceType, ERROR_TYPE, ErrorHandler, getPrompts, OdataVersion, prompt, promptNames, SystemSelectionAnswerType, type CapRuntime, type CapService, type InquirerAdapter, type OdataServiceAnswers, type OdataServicePromptOptions, type SapSystemType };
|
|
35
35
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.promptNames = exports.
|
|
6
|
+
exports.promptNames = exports.OdataVersion = exports.ErrorHandler = exports.ERROR_TYPE = exports.DatasourceType = void 0;
|
|
7
7
|
exports.getPrompts = getPrompts;
|
|
8
8
|
exports.prompt = prompt;
|
|
9
9
|
const odata_service_writer_1 = require("@sap-ux/odata-service-writer");
|
|
@@ -14,8 +14,6 @@ Object.defineProperty(exports, "ERROR_TYPE", { enumerable: true, get: function (
|
|
|
14
14
|
Object.defineProperty(exports, "ErrorHandler", { enumerable: true, get: function () { return error_handler_1.ErrorHandler; } });
|
|
15
15
|
const i18n_1 = require("./i18n");
|
|
16
16
|
const prompts_1 = require("./prompts");
|
|
17
|
-
const questions_1 = require("./prompts/datasources/sap-system/new-system/questions");
|
|
18
|
-
Object.defineProperty(exports, "newSystemChoiceValue", { enumerable: true, get: function () { return questions_1.newSystemChoiceValue; } });
|
|
19
17
|
const logger_helper_1 = __importDefault(require("./prompts/logger-helper"));
|
|
20
18
|
const types_1 = require("./types");
|
|
21
19
|
Object.defineProperty(exports, "DatasourceType", { enumerable: true, get: function () { return types_1.DatasourceType; } });
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { IValidationLink } from '@sap-devx/yeoman-ui-types';
|
|
2
2
|
import type { AxiosRequestConfig, CatalogService, ODataService, ServiceInfo, ServiceProvider } from '@sap-ux/axios-extension';
|
|
3
3
|
import { ODataVersion } from '@sap-ux/axios-extension';
|
|
4
|
+
import { type Destination } from '@sap-ux/btp-utils';
|
|
5
|
+
import { ERROR_TYPE } from '../error-handler/error-handler';
|
|
4
6
|
/**
|
|
5
7
|
* Structure to store validity information about url to be validated.
|
|
6
8
|
*/
|
|
@@ -11,7 +13,7 @@ interface Validity {
|
|
|
11
13
|
authenticated?: boolean;
|
|
12
14
|
canSkipCertError?: boolean;
|
|
13
15
|
}
|
|
14
|
-
type ValidationResult = string | boolean | IValidationLink;
|
|
16
|
+
export type ValidationResult = string | boolean | IValidationLink;
|
|
15
17
|
export type SystemAuthType = 'serviceKey' | 'reentranceTicket' | 'basic' | 'unknown';
|
|
16
18
|
/**
|
|
17
19
|
* Class that can be used to determine the connectivity using a service url, system url, or service info (UAA Key details) or reentrance ticket.
|
|
@@ -23,6 +25,8 @@ export type SystemAuthType = 'serviceKey' | 'reentranceTicket' | 'basic' | 'unkn
|
|
|
23
25
|
export declare class ConnectionValidator {
|
|
24
26
|
readonly validity: Validity;
|
|
25
27
|
private _validatedUrl;
|
|
28
|
+
private _destinationUrl;
|
|
29
|
+
private _destination;
|
|
26
30
|
private _validatedClient;
|
|
27
31
|
private _odataService;
|
|
28
32
|
private _serviceProvider;
|
|
@@ -105,6 +109,18 @@ export declare class ConnectionValidator {
|
|
|
105
109
|
* @returns the refresh token
|
|
106
110
|
*/
|
|
107
111
|
get refreshToken(): string | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Get the full expanded destination url as defined in the destination configuration. This should not be used to connect from App Studio (use the .dest form).
|
|
114
|
+
*
|
|
115
|
+
* @returns the connected destination 'URL' attribute value
|
|
116
|
+
*/
|
|
117
|
+
get destinationUrl(): string | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Get the destination.
|
|
120
|
+
*
|
|
121
|
+
* @returns the connected destination 'URL' attribute value
|
|
122
|
+
*/
|
|
123
|
+
get destination(): Destination | undefined;
|
|
108
124
|
/**
|
|
109
125
|
* Get the connected system name. If previously set this will be used, otherwise the name is determined
|
|
110
126
|
* by the system auth type, or the validated url.
|
|
@@ -128,8 +144,9 @@ export declare class ConnectionValidator {
|
|
|
128
144
|
* @param options.isSystem if true, the url will be treated as a system url rather than a service url
|
|
129
145
|
* @param options.odataVersion if specified will restrict catalog requests to only the specified odata version
|
|
130
146
|
* @returns the status code or error returned by the connection attempt
|
|
147
|
+
* @throws an error if the connection attempt fails and the error is a 500 on App Studio or a non-axios error is caught
|
|
131
148
|
*/
|
|
132
|
-
private
|
|
149
|
+
private checkUrl;
|
|
133
150
|
/**
|
|
134
151
|
* Create the axios configuration object for the service or system connection.
|
|
135
152
|
*
|
|
@@ -147,7 +164,11 @@ export declare class ConnectionValidator {
|
|
|
147
164
|
* @param servicePath the service path without the origin
|
|
148
165
|
*/
|
|
149
166
|
private createOdataServiceConnection;
|
|
150
|
-
|
|
167
|
+
/**
|
|
168
|
+
*
|
|
169
|
+
* @param resetValidity
|
|
170
|
+
*/
|
|
171
|
+
resetConnectionState(resetValidity?: boolean): void;
|
|
151
172
|
/**
|
|
152
173
|
* Create the connection for a system url, the specified axios config or the specified service info.
|
|
153
174
|
*
|
|
@@ -156,6 +177,8 @@ export declare class ConnectionValidator {
|
|
|
156
177
|
* @param connectConfig.url the system url
|
|
157
178
|
* @param connectConfig.serviceInfo the service info
|
|
158
179
|
* @param connectConfig.odataVersion the odata version to restrict the catalog requests if only a specific version is required
|
|
180
|
+
* @param connectConfig.destination the destination to connect with
|
|
181
|
+
* @throws an error if the connection attempt fails, callers should handle the error
|
|
159
182
|
*/
|
|
160
183
|
private createSystemConnection;
|
|
161
184
|
/**
|
|
@@ -166,7 +189,7 @@ export declare class ConnectionValidator {
|
|
|
166
189
|
*/
|
|
167
190
|
private shouldAttemptV4Catalog;
|
|
168
191
|
/**
|
|
169
|
-
* Callback for when the refresh token changes.
|
|
192
|
+
* Callback for when the Abap cloud system refresh token changes.
|
|
170
193
|
*
|
|
171
194
|
* @param refreshToken the new refresh token
|
|
172
195
|
*/
|
|
@@ -181,14 +204,38 @@ export declare class ConnectionValidator {
|
|
|
181
204
|
private getAbapOnCloudServiceProvider;
|
|
182
205
|
/**
|
|
183
206
|
* Validate the system connectivity with the specified service info (containing UAA details).
|
|
207
|
+
* This will create a connection to the system, updating the service provider reference.
|
|
208
|
+
* The connected user name will be cached for later use.
|
|
184
209
|
*
|
|
185
210
|
* @param serviceInfo the service info containing the UAA details
|
|
186
211
|
* @param odataVersion the odata version to restrict the catalog requests if only a specific version is required
|
|
187
|
-
* @returns true if the system is reachable, false if not, or an error message string
|
|
212
|
+
* @returns true if the system is reachable and authenticated, if required, false if not, or an error message string
|
|
188
213
|
*/
|
|
189
214
|
validateServiceInfo(serviceInfo: ServiceInfo, odataVersion?: ODataVersion): Promise<ValidationResult>;
|
|
190
215
|
/**
|
|
191
|
-
*
|
|
216
|
+
* Validate the specified destination connectivity, determining if authentication is required or if the destination is misconfigured.
|
|
217
|
+
*
|
|
218
|
+
* @param destination the destination to validate
|
|
219
|
+
* @param odataVersion the odata version to restrict the catalog requests if only a specific version is required
|
|
220
|
+
* @param servicePath the service path to validate, if specified will be appended to the destination URL for validation, if not specified the destination url will be used
|
|
221
|
+
* @returns true if the system is reachable and authenticated, if required, false if not, or an error message string
|
|
222
|
+
*/
|
|
223
|
+
validateDestination(destination: Destination, odataVersion?: ODataVersion, servicePath?: string): Promise<{
|
|
224
|
+
valResult: ValidationResult;
|
|
225
|
+
errorType?: ERROR_TYPE;
|
|
226
|
+
}>;
|
|
227
|
+
/**
|
|
228
|
+
* Validate the connectivity to a destination odata service (for generic odata service destinations), determining, for example, if authentication is required.
|
|
229
|
+
*
|
|
230
|
+
* @param destination a destination that is a generic odata service destination
|
|
231
|
+
* @param servicePath additional service path to append to the destination URL
|
|
232
|
+
* @param requiredOdataVersion the required odata version, if specified will validate the odata service version satisfies the specified version
|
|
233
|
+
* @returns validation result and error type if validation fails
|
|
234
|
+
*/
|
|
235
|
+
private validateOdataServiceDestination;
|
|
236
|
+
/**
|
|
237
|
+
* Validates an odata service url format as well as its reachability. Note if this function returns true, this is only an indication that the system is reachable
|
|
238
|
+
* not that a connection has been established. The connection may require separate authentication or other steps (it may be reachable but a cert error was returned).
|
|
192
239
|
*
|
|
193
240
|
* @param serviceUrl the url to validate, may be a system or service url.
|
|
194
241
|
* Note that if systemAuthType is specified, the url will be treated as a system url (only the origin will be considered)
|
|
@@ -197,17 +244,18 @@ export declare class ConnectionValidator {
|
|
|
197
244
|
* @param options.forceReValidation force re-validation of the url
|
|
198
245
|
* @param options.isSystem if true, the url will be treated as a system url rather than a service url, this value is retained for subsequent calls
|
|
199
246
|
* @param options.odataVersion if specified will restrict catalog requests to only the specified odata version
|
|
247
|
+
* @param options.systemAuthType the system auth type used to create system connections, if not specified or `isSystem` is false or undefined, `basic` is assumed
|
|
200
248
|
* @returns true if the url is reachable, false if not, or an error message string
|
|
201
249
|
*/
|
|
202
|
-
validateUrl(serviceUrl: string, { ignoreCertError, forceReValidation, isSystem, odataVersion }?: {
|
|
250
|
+
validateUrl(serviceUrl: string, { ignoreCertError, forceReValidation, isSystem, odataVersion, systemAuthType }?: {
|
|
203
251
|
ignoreCertError?: boolean;
|
|
204
252
|
forceReValidation?: boolean;
|
|
205
253
|
isSystem?: boolean;
|
|
206
254
|
odataVersion?: ODataVersion;
|
|
255
|
+
systemAuthType?: SystemAuthType;
|
|
207
256
|
}): Promise<ValidationResult>;
|
|
208
257
|
/**
|
|
209
|
-
*
|
|
210
|
-
* Sets the instance validity state based on the status code.
|
|
258
|
+
* Sets the instance validity state based on the status code and returns true if the status code indicates that the URL was reachable.
|
|
211
259
|
*
|
|
212
260
|
* @param status a http request status code used to determine the validation result
|
|
213
261
|
* @returns true, if the status code indicates the url is reachable, false if not, or an error message string
|
|
@@ -229,7 +277,7 @@ export declare class ConnectionValidator {
|
|
|
229
277
|
private isUrlValidated;
|
|
230
278
|
/**
|
|
231
279
|
* Check whether basic auth is required for the given url, or for the previously validated url if none specified.
|
|
232
|
-
* This will also set the validity state for the url.
|
|
280
|
+
* This will also set the validity state for the url.
|
|
233
281
|
*
|
|
234
282
|
* @param urlString the url to validate, if not provided the previously validated url will be used
|
|
235
283
|
* @param client optional, sap client code, if not provided the previously validated client will be used
|
|
@@ -250,12 +298,15 @@ export declare class ConnectionValidator {
|
|
|
250
298
|
* @param options.odataVersion if specified will restrict catalog requests to only the specified odata version
|
|
251
299
|
* @returns true if the authentication is successful, false if not, or an error message string
|
|
252
300
|
*/
|
|
253
|
-
validateAuth(url: string, username
|
|
301
|
+
validateAuth(url: string, username?: string, password?: string, { ignoreCertError, sapClient, odataVersion, isSystem }?: {
|
|
254
302
|
ignoreCertError?: boolean;
|
|
255
303
|
odataVersion?: ODataVersion;
|
|
256
304
|
sapClient?: string;
|
|
257
305
|
isSystem?: boolean;
|
|
258
|
-
}): Promise<
|
|
306
|
+
}): Promise<{
|
|
307
|
+
valResult: ValidationResult;
|
|
308
|
+
errorType?: ERROR_TYPE;
|
|
309
|
+
}>;
|
|
259
310
|
/**
|
|
260
311
|
* Reset the validity state.
|
|
261
312
|
*/
|