abap-adt-api
Version:
Interface to Abap Developer Tools webservice
301 lines (300 loc) • 13.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.switchRepoBranch = exports.remoteRepoInfo = exports.stageRepo = exports.pushRepo = exports.checkRepo = exports.unlinkRepo = exports.pullRepo = exports.createRepo = exports.externalRepoInfo = exports.gitRepos = void 0;
const utilities_1 = require("../utilities");
const AdtException_1 = require("../AdtException");
const parseDate = (d) => {
const match = d.match(/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/);
if (!match)
return new Date(); // wrong but valid
const [Y, M, D, h, m, s] = match.slice(1);
return new Date(Date.UTC((0, utilities_1.toInt)(Y), (0, utilities_1.toInt)(M) - 1, (0, utilities_1.toInt)(D), (0, utilities_1.toInt)(h), (0, utilities_1.toInt)(m), (0, utilities_1.toInt)(s)));
};
async function gitRepos(h) {
const headers = { Accept: "application/abapgit.adt.repos.v2+xml" };
const response = await h.request(`/sap/bc/adt/abapgit/repos`, { headers });
const raw = (0, utilities_1.parse)(response.body, {
ignoreAttributes: false,
parseAttributeValue: false,
parseTagValue: false,
removeNSPrefix: true
});
return (0, utilities_1.xmlArray)(raw, "repositories", "repository").map((x) => {
const { key, package: sapPackage, url, status, status_text, } = x;
// tslint:disable: variable-name
const branch_name = x.branch_name || x.branchName || "";
const created_by = x.created_by || x.createdBy || "";
const created_at = x.created_at || x.createdAt || "";
const created_email = x.created_email || x.createdEmail || "";
const deserialized_by = x.deserialized_by || x.deserializedBy || "";
const deserialized_email = x.deserialized_email || x.deserializedEmail || "";
const deserialized_at = x.deserialized_at || x.deserializedAt || "";
const links = (0, utilities_1.xmlArray)(x, "link").map(utilities_1.xmlNodeAttr);
const repo = {
key,
sapPackage,
url,
branch_name,
created_by,
created_at: parseDate(created_at),
created_email,
deserialized_by,
deserialized_email,
deserialized_at: deserialized_at && parseDate(deserialized_at),
status,
status_text,
links,
};
return repo;
});
}
exports.gitRepos = gitRepos;
async function externalRepoInfo(h, repourl, user = "", password = "") {
const headers = {
"Content-Type": "application/abapgit.adt.repo.info.ext.request.v2+xml",
Accept: "application/abapgit.adt.repo.info.ext.response.v2+xml",
};
const body = `<?xml version="1.0" ?>
<abapgitexternalrepo:externalRepoInfoRequest xmlns:abapgitexternalrepo="http://www.sap.com/adt/abapgit/externalRepo">
<abapgitexternalrepo:url>${repourl}</abapgitexternalrepo:url>
<abapgitexternalrepo:user>${user}</abapgitexternalrepo:user>
<abapgitexternalrepo:password>${password}</abapgitexternalrepo:password>
</abapgitexternalrepo:externalRepoInfoRequest>`;
const response = await h.request(`/sap/bc/adt/abapgit/externalrepoinfo`, {
method: "POST",
body,
headers,
});
const raw = (0, utilities_1.fullParse)(response.body, { removeNSPrefix: true });
// tslint:disable-next-line: variable-name
const access_mode = (0, utilities_1.xmlNode)(raw, "externalRepoInfo", "accessMode");
const branches = (0, utilities_1.xmlArray)(raw, "externalRepoInfo", "branch").map((branch) => ({
name: branch.name,
type: branch.type,
sha1: branch.sha1,
display_name: branch.displayName,
is_head: (0, utilities_1.boolFromAbap)(branch && branch.is_head),
}));
return { access_mode, branches };
}
exports.externalRepoInfo = externalRepoInfo;
const parseObjects = (body) => {
const raw = (0, utilities_1.fullParse)(body);
return (0, utilities_1.xmlArray)(raw, "objects", "object").map((r) => {
const { type, name, package: pkg, status, msgType, msgText, } = r;
const obj = {
obj_type: type,
obj_name: name,
package: pkg,
obj_status: status,
msg_type: msgType,
msg_text: msgText,
};
});
};
async function createRepo(h, packageName, repourl, branch = "refs/heads/master", transport = "", user = "", password = "") {
const headers = {
"Content-Type": "application/abapgit.adt.repo.v3+xml",
};
const body = `<?xml version="1.0" ?>
<abapgitrepo:repository xmlns:abapgitrepo="http://www.sap.com/adt/abapgit/repositories">
<abapgitrepo:package>${packageName}</abapgitrepo:package>
<abapgitrepo:url>${repourl}</abapgitrepo:url>
<abapgitrepo:branchName>${branch}</abapgitrepo:branchName>
<abapgitrepo:transportRequest>${transport}</abapgitrepo:transportRequest>
<abapgitrepo:remoteUser>${user}</abapgitrepo:remoteUser>
<abapgitrepo:remotePassword>${password}</abapgitrepo:remotePassword>
</abapgitrepo:repository>`;
const response = await h.request(`/sap/bc/adt/abapgit/repos`, {
method: "POST",
body,
headers, // encodeEntity?
});
return parseObjects(response.body);
}
exports.createRepo = createRepo;
async function pullRepo(h, repoId, branch = "refs/heads/master", transport = "", user = "", password = "") {
const headers = {
"Content-Type": "application/abapgit.adt.repo.v3+xml",
};
branch = `<abapgitrepo:branchName>${branch}</abapgitrepo:branchName>`;
transport = transport
? `<abapgitrepo:transportRequest>${transport}</abapgitrepo:transportRequest>`
: "";
user = user ? `<abapgitrepo:remoteUser>${user}</abapgitrepo:remoteUser>` : "";
password = password ? `<abapgitrepo:remotePassword>${password}</abapgitrepo:remotePassword>` : "";
const body = `<?xml version="1.0" ?><abapgitrepo:repository xmlns:abapgitrepo="http://www.sap.com/adt/abapgit/repositories">
${branch}${transport}${user}${password}</abapgitrepo:repository>`;
const response = await h.request(`/sap/bc/adt/abapgit/repos/${repoId}/pull`, {
method: "POST",
body,
headers,
});
return parseObjects(response.body);
}
exports.pullRepo = pullRepo;
async function unlinkRepo(h, repoId) {
const headers = {
"Content-Type": "application/abapgit.adt.repo.v3+xml",
};
await h.request(`/sap/bc/adt/abapgit/repos/${repoId}`, {
method: "DELETE",
headers,
});
}
exports.unlinkRepo = unlinkRepo;
const deserializeStaging = (body) => {
const raw = (0, utilities_1.xmlNode)((0, utilities_1.fullParse)(body), "abapgitstaging:abapgitstaging");
const parsefile = (x) => ({
...(0, utilities_1.stripNs)((0, utilities_1.xmlNodeAttr)(x)),
links: (0, utilities_1.xmlArray)(x, "atom:link")
.map(utilities_1.xmlNodeAttr)
.map(utilities_1.stripNs)
.map((l) => ({ ...l, href: l.href })),
});
const parseObject = (x) => {
const attrs = (0, utilities_1.stripNs)((0, utilities_1.xmlNodeAttr)(x));
const abapGitFiles = (0, utilities_1.xmlArray)(x, "abapgitstaging:abapgitfile").map(parsefile);
return { ...attrs, abapGitFiles };
};
const unstaged = (0, utilities_1.xmlArray)(raw, "abapgitstaging:unstaged_objects", "abapgitstaging:abapgitobject").map(parseObject);
const staged = (0, utilities_1.xmlArray)(raw, "abapgitstaging:staged_objects", "abapgitstaging:abapgitobject").map(parseObject);
const ignored = (0, utilities_1.xmlArray)(raw, "abapgitstaging:ignored_objects", "abapgitstaging:abapgitobject").map(parseObject);
const commentNode = (0, utilities_1.xmlNode)(raw, "abapgitstaging:abapgit_comment");
const extractUser = (p) => (0, utilities_1.stripNs)((0, utilities_1.xmlNodeAttr)((0, utilities_1.xmlNode)(commentNode, p)));
const comment = commentNode["@_abapgitstaging:comment"] || "";
const author = extractUser("abapgitstaging:author");
const committer = extractUser("abapgitstaging:author");
const result = {
staged,
unstaged,
ignored,
comment,
author,
committer,
};
return result;
};
const serializeStaging = (s) => {
const formatFile = (f) => {
const { links, ...rest } = f;
return ` <abapgitstaging:abapgitfile ${(0, utilities_1.toXmlAttributes)(rest, "abapgitstaging")}>${links
.map((l) => ({ ...l, href: (0, utilities_1.encodeEntity)(l.href) }))
.map((l) => `<atom:link ${(0, utilities_1.toXmlAttributes)(l, "")}/>`)
.join("")}
</abapgitstaging:abapgitfile>`;
};
const formatObject = (obj) => {
const { abapGitFiles, wbkey, ...rest } = obj;
return `<abapgitstaging:abapgitobject ${(0, utilities_1.toXmlAttributes)(rest, "adtcore")} abapgitstaging:wbkey="${obj.wbkey}">
${obj.abapGitFiles.map(formatFile).join("")}
</abapgitstaging:abapgitobject>`;
};
const formatObjects = (objects, root) => {
if (!objects.length)
return `<${root}/>`;
return `<${root}>${objects.map(formatObject).join("")}</${root}>`;
};
const unstaged = formatObjects(s.unstaged, "abapgitstaging:unstaged_objects");
const staged = formatObjects(s.staged, "abapgitstaging:staged_objects");
const ignored = formatObjects(s.ignored, "abapgitstaging:ignored_objects");
const comment = `<abapgitstaging:abapgit_comment abapgitstaging:comment="${s.comment}">
<abapgitstaging:author abapgitstaging:name="${s.author.name}" abapgitstaging:email="${s.author.email}"/>
<abapgitstaging:committer abapgitstaging:name="${s.committer.name}" abapgitstaging:email="${s.committer.email}"/>
</abapgitstaging:abapgit_comment>
`;
return `<?xml version="1.0" encoding="UTF-8"?>
<abapgitstaging:abapgitstaging xmlns:abapgitstaging="http://www.sap.com/adt/abapgit/staging"
xmlns:adtcore="http://www.sap.com/adt/core"
xmlns:atom="http://www.w3.org/2005/Atom">
${unstaged}
${staged}
${ignored}
${comment}
</abapgitstaging:abapgitstaging>`;
};
async function checkRepo(h, repo, user = "", password = "") {
const clink = repo.links.find((l) => l.type === "check_link");
if (!(clink === null || clink === void 0 ? void 0 : clink.href))
throw (0, AdtException_1.adtException)("Check link not found");
const headers = {
Accept: "text/plain",
};
if (user)
headers.Username = user;
if (password)
headers.Password = (0, utilities_1.btoa)(password);
await h.request(clink.href, { method: "POST", headers });
}
exports.checkRepo = checkRepo;
async function pushRepo(h, repo, staging, user = "", password = "") {
const link = repo.links.find((l) => l.type === "push_link");
if (!(link === null || link === void 0 ? void 0 : link.href))
throw (0, AdtException_1.adtException)("Push link not found");
const headers = {
Accept: "application/abapgit.adt.repo.stage.v1+xml",
};
headers["Content-Type"] = headers.Accept;
if (user)
headers.Username = user;
if (password)
headers.Password = (0, utilities_1.btoa)(password);
const body = serializeStaging(staging);
await h.request(link.href, { method: "POST", headers, body });
}
exports.pushRepo = pushRepo;
async function stageRepo(h, repo, user = "", password = "") {
const link = repo.links.find((l) => l.type === "stage_link");
if (!(link === null || link === void 0 ? void 0 : link.href))
throw (0, AdtException_1.adtException)("Stage link not found");
const headers = {
"Content-Type": "application/abapgit.adt.repo.stage.v1+xml",
};
if (user)
headers.Username = user;
if (password)
headers.Password = (0, utilities_1.btoa)(password);
const resp = await h.request(link.href, { headers });
return deserializeStaging(resp.body);
}
exports.stageRepo = stageRepo;
/**
* @deprecated since 1.2.1, duplicate of externalRepoInfo
*/
async function remoteRepoInfo(h, repo, user = "", password = "") {
var _a;
const headers = {
"Content-Type": "application/abapgit.adt.repo.info.ext.request.v1+xml",
Accept: "application/abapgit.adt.repo.info.ext.response.v1+xml",
};
const body = `<?xml version="1.0" encoding="UTF-8"?>
<repository_ext>
<url>${repo.url}</url>
<user>${user}</user>
<password>${password}</password>
</repository_ext>`;
const resp = await h.request("/sap/bc/adt/abapgit/externalrepoinfo", {
headers,
body,
method: "POST",
});
const raw = (_a = (0, utilities_1.parse)(resp.body)) === null || _a === void 0 ? void 0 : _a.repository_external;
const { access_mode, branches } = raw;
return {
access_mode,
branches: (0, utilities_1.xmlArray)(branches, "branch"),
};
}
exports.remoteRepoInfo = remoteRepoInfo;
async function switchRepoBranch(h, repo, branch, create = false, user = "", password = "") {
const headers = {};
if (user)
headers.Username = user;
if (password)
headers.Password = (0, utilities_1.btoa)(password);
await h.request(`/sap/bc/adt/abapgit/repos/${repo.key}/branches/${encodeURIComponent(branch)}?create=${create}`, {
headers,
method: "POST",
});
}
exports.switchRepoBranch = switchRepoBranch;