UNPKG

abap-adt-api

Version:

Interface to Abap Developer Tools webservice

293 lines (292 loc) 13.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTransportConfiguration = exports.transportConfigurations = exports.transportReference = exports.systemUsers = exports.transportAddUser = exports.transportSetOwner = exports.transportRelease = exports.transportDelete = exports.setTransportsConfig = exports.createTransportsConfig = exports.transportsByConfig = exports.userTransports = exports.createTransport = exports.transportInfo = exports.TransportDateFilter = void 0; const AdtException_1 = require("../AdtException"); const utilities_1 = require("../utilities"); var TransportDateFilter; (function (TransportDateFilter) { TransportDateFilter[TransportDateFilter["SinceYesterday"] = 0] = "SinceYesterday"; TransportDateFilter[TransportDateFilter["SincleTwoWeeks"] = 1] = "SincleTwoWeeks"; TransportDateFilter[TransportDateFilter["SinceFourWeeks"] = 2] = "SinceFourWeeks"; TransportDateFilter[TransportDateFilter["DateRange"] = 3] = "DateRange"; })(TransportDateFilter = exports.TransportDateFilter || (exports.TransportDateFilter = {})); function extractLocks(raw) { const lock = raw && raw.CTS_OBJECT_LOCK; if (!lock) return; try { const holder = lock.LOCK_HOLDER; const TASKS = (0, utilities_1.xmlArray)(holder, "TASK_HEADERS").map((x) => x.CTS_TASK_HEADER); return { HEADER: holder.REQ_HEADER, OBJECT_KEY: (0, utilities_1.xmlNode)(lock, "OBJECT_KEY"), TASKS }; } catch (_a) { return; } } function extractTransports(raw) { return (0, utilities_1.xmlArray)(raw, "CTS_REQUEST").map((x) => x.REQ_HEADER); } async function transportInfo(h, URI, DEVCLASS = "", OPERATION = "I") { (0, AdtException_1.ValidateObjectUrl)(URI); const body = (0, utilities_1.JSON2AbapXML)({ DEVCLASS, OPERATION, URI }); const headers = { Accept: "application/vnd.sap.as+xml;charset=UTF-8;dataname=com.sap.adt.transport.service.checkData", "Content-Type": "application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.transport.service.checkData" }; const response = await h.request("/sap/bc/adt/cts/transportchecks", { body, method: "POST", headers }); // return parsePackageResponse(response.body) // tslint:disable-next-line: prefer-const let { REQUESTS, LOCKS, MESSAGES, ...header } = (0, utilities_1.parse)(response.body)["asx:abap"]["asx:values"].DATA; if (MESSAGES) { MESSAGES = (0, utilities_1.xmlArray)(MESSAGES, "CTS_MESSAGE").map((m) => { // tslint:disable-next-line: prefer-const let { VARIABLES, ...rest } = m; VARIABLES = (VARIABLES && (0, utilities_1.xmlArray)(m, "VARIABLES", "CTS_VARIABLE")).map((v) => v.VARIABLE) || []; return { VARIABLES, ...rest }; }); MESSAGES.filter((m) => m.SEVERITY.match(/[EAX]/)).some((e) => { throw (0, AdtException_1.adtException)(e.TEXT); }); } const TRANSPORTS = extractTransports(REQUESTS); return { ...header, LOCKS: extractLocks(LOCKS), TRANSPORTS }; } exports.transportInfo = transportInfo; async function createTransport(h, REF, REQUEST_TEXT, DEVCLASS, OPERATION = "I", transportLayer = "") { var _a; (0, AdtException_1.ValidateObjectUrl)(REF); const body = (0, utilities_1.JSON2AbapXML)({ DEVCLASS, REQUEST_TEXT, REF, OPERATION }); const qs = transportLayer ? { transportLayer } : {}; const response = await h.request("/sap/bc/adt/cts/transports", { body, qs, headers: { Accept: "text/plain", "Content-Type": "application/vnd.sap.as+xml; charset=UTF-8; dataname=com.sap.adt.CreateCorrectionRequest" }, method: "POST" }); const transport = (_a = response.body) === null || _a === void 0 ? void 0 : _a.split("/").pop(); return transport || ""; } exports.createTransport = createTransport; const parseTask = (t) => { const task = { ...(0, utilities_1.xmlNodeAttr)(t), links: (0, utilities_1.xmlArray)(t, "atom:link").map(utilities_1.xmlNodeAttr), objects: (0, utilities_1.xmlArray)(t, "tm:abap_object").map(utilities_1.xmlNodeAttr) }; if (task["tm:desc"]) task["tm:desc"] = task["tm:desc"]; return task; }; const parseRequest = (r) => { const request = { ...parseTask(r), tasks: (0, utilities_1.xmlArray)(r, "tm:task").map(parseTask) }; return request; }; const parseTargets = (s) => ({ ...(0, utilities_1.xmlNodeAttr)(s), modifiable: (0, utilities_1.xmlArray)(s, "tm:modifiable", "tm:request").map(parseRequest), released: (0, utilities_1.xmlArray)(s, "tm:released", "tm:request").map(parseRequest) }); async function userTransports(h, user, targets = true) { const response = await h.request("/sap/bc/adt/cts/transportrequests", { qs: { user, targets } }); const raw = (0, utilities_1.fullParse)(response.body); const workbench = (0, utilities_1.xmlArray)(raw, "tm:root", "tm:workbench", "tm:target").map(parseTargets); const customizing = (0, utilities_1.xmlArray)(raw, "tm:root", "tm:customizing", "tm:target").map(parseTargets); const retval = { workbench, customizing }; return retval; } exports.userTransports = userTransports; async function transportsByConfig(h, configUri, targets = true) { const response = await h.request("/sap/bc/adt/cts/transportrequests", { qs: { configUri, targets } }); const raw = (0, utilities_1.fullParse)(response.body); const workbench = (0, utilities_1.xmlArray)(raw, "tm:root", "tm:workbench", "tm:target").map(parseTargets); const customizing = (0, utilities_1.xmlArray)(raw, "tm:root", "tm:customizing", "tm:target").map(parseTargets); const retval = { workbench, customizing }; return retval; } exports.transportsByConfig = transportsByConfig; const serializeTransportConfig = (cfg) => { const w = (k, v) => `<configuration:property key="${k}">${v}</configuration:property>`; const p = (v, k) => w(k, v[k]); const td = (d) => `${(0, utilities_1.toSapDate)(new Date(d))}`; const datelimit = cfg.DateFilter === TransportDateFilter.DateRange ? `${w("FromDate", td(cfg.FromDate))}${w("ToDate", td(cfg.ToDate))}` : ""; return "".concat(`<configuration:configuration xmlns:configuration="http://www.sap.com/adt/configuration"> <configuration:properties>`, p(cfg, "WorkbenchRequests"), p(cfg, "CustomizingRequests"), p(cfg, "TransportOfCopies"), p(cfg, "DateFilter"), p(cfg, "Modifiable"), p(cfg, "Released"), p(cfg, "User"), datelimit, `</configuration:properties> </configuration:configuration>`); }; async function createTransportsConfig(h) { const headers = { Accept: "application/vnd.sap.adt.configuration.v1+xml" }; const uri = "/sap/bc/adt/cts/transportrequests/searchconfiguration/configurations"; const response = await h.request(uri, { method: "POST", headers }); return parseTransportConfig(response.body); } exports.createTransportsConfig = createTransportsConfig; async function setTransportsConfig(h, uri, etag, config) { const body = serializeTransportConfig(config); const headers = { Accept: "application/vnd.sap.adt.configuration.v1+xml", "Content-Type": "application/vnd.sap.adt.configuration.v1+xml", "If-Match": etag }; const response = await h.request(uri, { method: "PUT", headers, body }); return parseTransportConfig(response.body); } exports.setTransportsConfig = setTransportsConfig; function validateTransport(transportNumber) { if (transportNumber.length !== 10 || !transportNumber.match(/^[a-z]\w\wk/i)) (0, AdtException_1.adtException)("Invalid transport number:" + transportNumber); } async function transportDelete(h, transportNumber) { validateTransport(transportNumber); await h.request("/sap/bc/adt/cts/transportrequests/" + transportNumber, { method: "DELETE", headers: { Accept: "application/*" } }); } exports.transportDelete = transportDelete; async function transportRelease(h, transportNumber, ignoreLocks = false, IgnoreATC = false) { validateTransport(transportNumber); const action = IgnoreATC ? "relObjigchkatc" : ignoreLocks ? "relwithignlock" : "newreleasejobs"; const response = await h.request(`/sap/bc/adt/cts/transportrequests/${transportNumber}/${action}`, { method: "POST", headers: { Accept: "application/*" } }); const raw = (0, utilities_1.fullParse)(response.body); const reports = (0, utilities_1.xmlArray)(raw, "tm:root", "tm:releasereports", "chkrun:checkReport").map((r) => { return { ...(0, utilities_1.xmlNodeAttr)(r), messages: (0, utilities_1.xmlArray)(r, "chkrun:checkMessageList", "chkrun:checkMessage").map(utilities_1.xmlNodeAttr) }; }); return reports; } exports.transportRelease = transportRelease; async function transportSetOwner(h, transportNumber, targetuser) { validateTransport(transportNumber); const body = `<?xml version="1.0" encoding="ASCII"?><tm:root xmlns:tm="http://www.sap.com/cts/adt/tm" tm:number="${transportNumber}" tm:targetuser="${targetuser}" tm:useraction="changeowner"/>`; const response = await h.request("/sap/bc/adt/cts/transportrequests/" + transportNumber, { method: "PUT", headers: { Accept: "application/*" }, qs: { targetuser }, body }); const raw = (0, utilities_1.fullParse)(response.body); return (0, utilities_1.xmlNodeAttr)((0, utilities_1.xmlNode)(raw, "tm:root")); } exports.transportSetOwner = transportSetOwner; async function transportAddUser(h, transportNumber, user) { validateTransport(transportNumber); const body = `<?xml version="1.0" encoding="ASCII"?> <tm:root xmlns:tm="http://www.sap.com/cts/adt/tm" tm:number="${transportNumber}" tm:targetuser="${user}" tm:useraction="newtask"/>`; const response = await h.request("/sap/bc/adt/cts/transportrequests/" + transportNumber + "/tasks", { method: "POST", body, headers: { Accept: "application/*", "Content-Type": "text/plain" } }); const raw = (0, utilities_1.fullParse)(response.body); return (0, utilities_1.xmlNodeAttr)((0, utilities_1.xmlNode)(raw, "tm:root")); } exports.transportAddUser = transportAddUser; async function systemUsers(h) { const response = await h.request("/sap/bc/adt/system/users", { headers: { Accept: "application/atom+xml;type=feed" } }); const raw = (0, utilities_1.parse)(response.body); return (0, utilities_1.xmlArray)(raw, "atom:feed", "atom:entry").map((r) => ({ id: r["atom:id"], title: r["atom:title"] })); } exports.systemUsers = systemUsers; // tslint:disable: variable-name async function transportReference(h, pgmid, obj_wbtype, obj_name, tr_number = "") { const response = await h.request("/sap/bc/adt/cts/transportrequests/reference", { headers: { Accept: "application/*" }, qs: { obj_name, obj_wbtype, pgmid, tr_number } }); const raw = (0, utilities_1.fullParse)(response.body); const link = (0, utilities_1.xmlNodeAttr)((0, utilities_1.xmlNode)(raw, "tm:root", "atom:link")); return link.href; } exports.transportReference = transportReference; const parseTransportConfigItemList = (body) => { const raw = (0, utilities_1.fullParse)(body, { parseAttributeValue: false }); return (0, utilities_1.xmlArray)(raw, "configurations:configurations", "configuration:configuration").map((conf) => { const { "atom:link": { "@_href": link, "@_etag": etag }, ...rest } = conf; const { createdAt, changedAt, ...attrs } = (0, utilities_1.xmlNodeAttr)(rest); const item = { ...attrs, link, etag, createdAt: Date.parse(createdAt), changedAt: Date.parse(changedAt) }; return item; }); }; async function transportConfigurations(h) { const headers = { Accept: "application/vnd.sap.adt.configurations.v1+xml" }; const url = "/sap/bc/adt/cts/transportrequests/searchconfiguration/configurations"; const response = await h.request(url, { headers }); return parseTransportConfigItemList(response.body); } exports.transportConfigurations = transportConfigurations; const parseTransportConfig = (r) => { const raw = (0, utilities_1.fullParse)(r, { parseAttributeValue: false }); const props = (0, utilities_1.xmlArray)(raw, "configuration:configuration", "configuration:properties", "configuration:property").map((p) => { return { key: p["@_key"], value: p["#text"] }; }); const cfg = {}; for (const { key, value } of props) cfg[key] = value; const WorkbenchRequests = cfg.WorkbenchRequests; const TransportOfCopies = cfg.TransportOfCopies; const Released = cfg.Released; const User = cfg.User; const CustomizingRequests = cfg.CustomizingRequests; const FromDate = cfg.FromDate && (0, utilities_1.parseSapDate)(`${cfg.FromDate}`); const ToDate = cfg.ToDate && (0, utilities_1.parseSapDate)(`${cfg.ToDate}`); const DateFilter = cfg.DateFilter; const Modifiable = cfg.Modifiable; return { WorkbenchRequests, TransportOfCopies, Released, User, CustomizingRequests, FromDate, ToDate, DateFilter, Modifiable }; }; async function getTransportConfiguration(h, url) { const headers = { Accept: "application/vnd.sap.adt.configuration.v1+xml" }; const response = await h.request(url, { headers }); return parseTransportConfig(response.body); } exports.getTransportConfiguration = getTransportConfiguration;