UNPKG

abap-adt-api

Version:

Interface to Abap Developer Tools webservice

185 lines (184 loc) 7.42 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isErrorMessageType = exports.validateParseResult = exports.fromError = exports.fromResponse = exports.isLoginError = exports.AdtErrorException = exports.SAPRC = void 0; exports.isAdtError = isAdtError; exports.isCsrfError = isCsrfError; exports.isHttpError = isHttpError; exports.isAdtException = isAdtException; exports.fromException = fromException; exports.adtException = adtException; exports.ValidateObjectUrl = ValidateObjectUrl; exports.ValidateStateful = ValidateStateful; const AdtHTTP_1 = require("./AdtHTTP"); const utilities_1 = require("./utilities"); const These_1 = require("fp-ts/lib/These"); const io_ts_reporters_1 = __importDefault(require("io-ts-reporters")); const ADTEXTYPEID = Symbol.for("ADT EXCEPTION"); const CSRFEXTYPEID = Symbol.for("BAD CSRF"); const HTTPEXTYPEID = Symbol.for("HTTP EXCEPTION"); var SAPRC; (function (SAPRC) { SAPRC["Success"] = "S"; SAPRC["Info"] = "I"; SAPRC["Warning"] = "W"; SAPRC["Error"] = "E"; SAPRC["CriticalError"] = "A"; SAPRC["Exception"] = "X"; })(SAPRC || (exports.SAPRC = SAPRC = {})); const isResponse = (r) => (0, utilities_1.isObject)(r) && !!(r === null || r === void 0 ? void 0 : r.status) && (0, utilities_1.isString)(r === null || r === void 0 ? void 0 : r.statusText); class AdtErrorException extends Error { get typeID() { return ADTEXTYPEID; } static create(errOrResponse, properties, type, message, parent, namespace, localizedMessage, response) { if (!(0, utilities_1.isNumber)(errOrResponse)) { return this.create(errOrResponse.status, properties, "", errOrResponse.statusText || "Unknown error in adt client", undefined, undefined, undefined, errOrResponse); } else { return new AdtErrorException(errOrResponse, properties, type, message, parent, namespace, localizedMessage, response); } } constructor(err, properties, type, message, parent, namespace, localizedMessage, response) { super(); this.err = err; this.properties = properties; this.type = type; this.message = message; this.parent = parent; this.namespace = namespace; this.localizedMessage = localizedMessage; this.response = response; } } exports.AdtErrorException = AdtErrorException; // tslint:disable-next-line:max-classes-per-file class AdtCsrfException extends Error { get typeID() { return CSRFEXTYPEID; } constructor(message, parent) { super(); this.message = message; this.parent = parent; } } // tslint:disable-next-line:max-classes-per-file class AdtHttpException extends Error { get typeID() { return HTTPEXTYPEID; } get code() { const p = this.parent; return (p.response && p.response.status) || 0; } get message() { return this.parent.message; } get name() { return this.parent.name; } constructor(parent) { super(); this.parent = parent; } } function isAdtError(e) { return (e === null || e === void 0 ? void 0 : e.typeID) === ADTEXTYPEID; } function isCsrfError(e) { return (e === null || e === void 0 ? void 0 : e.typeID) === CSRFEXTYPEID; } function isHttpError(e) { return (e === null || e === void 0 ? void 0 : e.typeID) === HTTPEXTYPEID; } function isAdtException(e) { return isAdtError(e) || isCsrfError(e) || isHttpError(e); } const isLoginError = (adtErr) => (isHttpError(adtErr) && adtErr.code === 401) || isCsrfError(adtErr); exports.isLoginError = isLoginError; const simpleError = (response) => adtException(`Error ${response.status}:${response.statusText}`, response.status); const isCsrfException = (r) => (r.status === 403 && r.headers["x-csrf-token"] === "Required") || (r.status === 400 && r.statusText === "Session timed out"); // hack to get login refresh to work on expired sessions const fromResponse = (data, response) => { if (!data) return simpleError(response); if (data.match(/CSRF/)) return new AdtCsrfException(data); const raw = (0, utilities_1.fullParse)(data); const root = raw["exc:exception"]; if (!root && response.status === 401) return simpleError(response); const getf = (base, idx) => (base ? base[idx] : ""); const properties = {}; (0, utilities_1.xmlArray)(root, "properties", "entry").forEach((p) => { properties[p["@_key"]] = `${p["#text"]}` .replace(/^\s+/, "") .replace(/\s+$/, ""); }); return new AdtErrorException(response.status, properties, root.type["@_id"], root.message["#text"], undefined, getf(root.namespace, "@_id"), getf(root.localizedMessage, "#text")); }; exports.fromResponse = fromResponse; const fromError = (error) => { try { if (isAdtError(error)) return error; if ((0, AdtHTTP_1.isHttpClientException)(error) && error.response) { if (error.status === 401) return new AdtHttpException(error); return (0, exports.fromResponse)(error.response.body, error.response); } if ((0, utilities_1.hasMessage)(error)) return new AdtErrorException(500, {}, "", error.message); } catch (error) { } return AdtErrorException.create(500, {}, "Unknown error", `${error}`); // hopefully will never happen }; exports.fromError = fromError; function fromExceptionOrResponse_int(errOrResp, config) { try { if (isResponse(errOrResp)) return (0, exports.fromResponse)(errOrResp.body, errOrResp); else return (0, exports.fromError)(errOrResp); } catch (e) { return isResponse(errOrResp) ? AdtErrorException.create(errOrResp, {}) : (0, exports.fromError)(e); } } function fromException(errOrResp, config) { if (isAdtException(errOrResp)) return errOrResp; if (!isResponse(errOrResp) && (!(0, utilities_1.isNativeError)(errOrResp) || ((0, utilities_1.isNativeError)(errOrResp) && !(0, AdtHTTP_1.isHttpClientException)(errOrResp)))) return AdtErrorException.create(500, {}, "Unknown error", `${errOrResp}`); // hopefully will never happen return fromExceptionOrResponse_int(errOrResp, config); } function adtException(message, number = 0) { return new AdtErrorException(number, {}, "", message); } function ValidateObjectUrl(url) { if (url.match(/^\/sap\/bc\/adt\/[a-z]+\/[a-zA-Z%\$]?[\w%]+/)) return; // valid throw new AdtErrorException(0, {}, "BADOBJECTURL", "Invalid Object URL:" + url); } function ValidateStateful(h) { if (h.isStateful) return; throw new AdtErrorException(0, {}, "STATELESS", "This operation can only be performed in stateful mode"); } const validateParseResult = (parseResult) => { if ((0, These_1.isLeft)(parseResult)) { const messages = io_ts_reporters_1.default.report(parseResult); throw adtException(messages.slice(0, 3).join("\n")); } return parseResult.right; }; exports.validateParseResult = validateParseResult; const isErrorMessageType = (x) => !!`${x}`.match(/^[EAX]$/i); exports.isErrorMessageType = isErrorMessageType;