@smwb/onreel-git-mcp 0.7.0 → 0.9.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/README.md +42 -8
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +8 -5
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcp.types.d.ts +3 -1
- package/dist/mcp/tools.lib.d.ts +5 -3
- package/dist/tracker/http.lib.d.ts +1 -1
- package/dist/tracker/index.js +202 -109
- package/dist/tracker/index.js.map +1 -1
- package/dist/tracker/tracker.const.d.ts +2 -0
- package/dist/tracker/tracker.types.d.ts +20 -0
- package/package.json +1 -1
package/dist/tracker/index.js
CHANGED
|
@@ -24,6 +24,7 @@ var LEGACY_ISSUE_CAPABILITIES = {
|
|
|
24
24
|
var CI_LOG_DEFAULT_BYTES = 16 * 1024;
|
|
25
25
|
var CI_LOG_MAX_BYTES = 1024 * 1024;
|
|
26
26
|
var CI_LOG_READ_MAX_BYTES = 64 * 1024 * 1024;
|
|
27
|
+
var TRACKER_REDIRECT_MAX = 5;
|
|
27
28
|
var CI_LOG_TIMEOUT_MS = 6e4;
|
|
28
29
|
var CI_LOG_PAGES_MAX = 50;
|
|
29
30
|
var CI_FINISHED_STATUSES = ["success", "failed", "canceled", "skipped"];
|
|
@@ -318,25 +319,93 @@ var SOURCECRAFT_RUN_EVENTS = {
|
|
|
318
319
|
|
|
319
320
|
// src/tracker/http.lib.ts
|
|
320
321
|
async function requestJson(url, request) {
|
|
321
|
-
|
|
322
|
+
const accept = { accept: "application/json" };
|
|
323
|
+
const { response, url: final } = await send(url, request, AbortSignal.timeout(TRACKER_TIMEOUT_MS), accept, {
|
|
324
|
+
method: request.method ?? "GET",
|
|
325
|
+
headers: { ...accept, ...request.body === void 0 ? {} : { "content-type": "application/json" }, ...request.headers },
|
|
326
|
+
body: request.body === void 0 ? void 0 : JSON.stringify(request.body)
|
|
327
|
+
});
|
|
328
|
+
let raw;
|
|
322
329
|
try {
|
|
323
|
-
|
|
324
|
-
method: request.method ?? "GET",
|
|
325
|
-
headers: { accept: "application/json", ...request.body === void 0 ? {} : { "content-type": "application/json" }, ...request.headers },
|
|
326
|
-
...request.body === void 0 ? {} : { body: JSON.stringify(request.body) },
|
|
327
|
-
signal: AbortSignal.timeout(TRACKER_TIMEOUT_MS)
|
|
328
|
-
});
|
|
330
|
+
raw = await response.text();
|
|
329
331
|
} catch (error) {
|
|
330
|
-
throw notAnswered(
|
|
332
|
+
throw notAnswered(final, error);
|
|
331
333
|
}
|
|
332
|
-
|
|
333
|
-
if (!response.ok) throw failureOf(url, response, raw, request);
|
|
334
|
+
if (!response.ok) throw failureOf(final, response, raw, request);
|
|
334
335
|
if (raw === "") return { body: void 0, headers: response.headers };
|
|
335
336
|
try {
|
|
336
337
|
return { body: JSON.parse(raw), headers: response.headers };
|
|
337
338
|
} catch {
|
|
338
|
-
throw new TrackerError("failed", `\u0422\u0440\u0435\u043A\u0435\u0440 ${hostOf(
|
|
339
|
+
throw new TrackerError("failed", `\u0422\u0440\u0435\u043A\u0435\u0440 ${hostOf(final)} \u0432\u0435\u0440\u043D\u0443\u043B \u043D\u0435 JSON.`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
343
|
+
async function send(url, request, signal, anonymous, first) {
|
|
344
|
+
const home = originOf(request.origin ?? url, "Origin \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F");
|
|
345
|
+
if (originOf(url, "\u0410\u0434\u0440\u0435\u0441 \u0437\u0430\u043F\u0440\u043E\u0441\u0430") !== home) throw new TrackerError("invalid_request", `\u0410\u0434\u0440\u0435\u0441 \u0437\u0430\u043F\u0440\u043E\u0441\u0430 ${hostOf(url)} \u0432\u043D\u0435 origin \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F ${hostOf(home)}: \u0437\u0430\u043F\u0440\u043E\u0441 \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D.`);
|
|
346
|
+
let current = url;
|
|
347
|
+
let hop = first;
|
|
348
|
+
let away = false;
|
|
349
|
+
for (let redirects = 0; ; redirects += 1) {
|
|
350
|
+
let response;
|
|
351
|
+
try {
|
|
352
|
+
response = await request.fetch(current, { method: hop.method, headers: hop.headers, ...hop.body === void 0 ? {} : { body: hop.body }, redirect: "manual", signal });
|
|
353
|
+
} catch (error) {
|
|
354
|
+
throw notAnswered(current, error);
|
|
355
|
+
}
|
|
356
|
+
const hidden = followedByFetch(response, current);
|
|
357
|
+
if (hidden !== void 0) {
|
|
358
|
+
await response.body?.cancel().catch(() => void 0);
|
|
359
|
+
throw new TrackerError("failed", `\u0422\u0440\u0435\u043A\u0435\u0440 ${hostOf(current)}: ${hidden}; \u043E\u0442\u0432\u0435\u0442 \u043E\u0442\u0431\u0440\u043E\u0448\u0435\u043D.`);
|
|
360
|
+
}
|
|
361
|
+
const location = REDIRECT_STATUSES.has(response.status) ? response.headers.get("location") : null;
|
|
362
|
+
if (location === null || location === "") return { response, url: current };
|
|
363
|
+
await response.body?.cancel().catch(() => void 0);
|
|
364
|
+
if (redirects >= TRACKER_REDIRECT_MAX) throw new TrackerError("failed", `\u0422\u0440\u0435\u043A\u0435\u0440 ${hostOf(url)}: \u0431\u043E\u043B\u044C\u0448\u0435 ${String(TRACKER_REDIRECT_MAX)} \u0440\u0435\u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0432 \u043F\u043E\u0434\u0440\u044F\u0434.`);
|
|
365
|
+
const next = redirectTarget(location, current);
|
|
366
|
+
if (response.status === 303 && hop.method !== "GET" || (response.status === 301 || response.status === 302) && hop.method === "POST") {
|
|
367
|
+
const { "content-type": _type, ...headers } = hop.headers;
|
|
368
|
+
hop = { method: "GET", headers, body: void 0 };
|
|
369
|
+
}
|
|
370
|
+
away ||= new URL(next).origin !== home;
|
|
371
|
+
if (away) {
|
|
372
|
+
if (hop.method !== "GET") throw new TrackerError("failed", `\u0422\u0440\u0435\u043A\u0435\u0440 ${hostOf(current)} \u043F\u0435\u0440\u0435\u043D\u0430\u043F\u0440\u0430\u0432\u0438\u043B ${hop.method} \u043D\u0430 \u0447\u0443\u0436\u043E\u0439 origin ${hostOf(next)}: \u0437\u0430\u043F\u0440\u043E\u0441 \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D.`);
|
|
373
|
+
hop = { method: "GET", headers: anonymous, body: void 0 };
|
|
374
|
+
}
|
|
375
|
+
current = next;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
function followedByFetch(response, current) {
|
|
379
|
+
if (response.type === "opaqueredirect") return "fetch \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u0441\u043A\u0440\u044B\u043B \u0440\u0435\u0434\u0438\u0440\u0435\u043A\u0442 (opaqueredirect), \u043F\u0440\u043E\u0439\u0442\u0438 \u0435\u0433\u043E \u043D\u0435\u043B\u044C\u0437\u044F";
|
|
380
|
+
let moved = response.redirected;
|
|
381
|
+
if (!moved && response.url !== "") {
|
|
382
|
+
try {
|
|
383
|
+
moved = new URL(response.url).origin !== new URL(current).origin;
|
|
384
|
+
} catch {
|
|
385
|
+
moved = true;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return moved ? "fetch \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u0441\u0430\u043C \u043F\u0440\u043E\u0448\u0451\u043B \u0440\u0435\u0434\u0438\u0440\u0435\u043A\u0442 \u2014 \u043E\u0431\u0451\u0440\u0442\u043A\u0430 fetch \u0434\u043E\u043B\u0436\u043D\u0430 \u043F\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044C init.redirect \u0434\u0430\u043B\u044C\u0448\u0435" : void 0;
|
|
389
|
+
}
|
|
390
|
+
function redirectTarget(location, current) {
|
|
391
|
+
let next;
|
|
392
|
+
try {
|
|
393
|
+
next = new URL(location, current);
|
|
394
|
+
} catch {
|
|
395
|
+
throw new TrackerError("failed", `\u0422\u0440\u0435\u043A\u0435\u0440 ${hostOf(current)} \u0432\u0435\u0440\u043D\u0443\u043B \u0440\u0435\u0434\u0438\u0440\u0435\u043A\u0442 \u043D\u0435 \u043D\u0430 URL.`);
|
|
396
|
+
}
|
|
397
|
+
if (next.protocol !== "http:" && next.protocol !== "https:") throw new TrackerError("failed", `\u0422\u0440\u0435\u043A\u0435\u0440 ${hostOf(current)} \u0432\u0435\u0440\u043D\u0443\u043B \u0440\u0435\u0434\u0438\u0440\u0435\u043A\u0442 \u043D\u0435 \u043D\u0430 http \u0438\u043B\u0438 https.`);
|
|
398
|
+
return next.href;
|
|
399
|
+
}
|
|
400
|
+
function originOf(value, subject) {
|
|
401
|
+
let parsed;
|
|
402
|
+
try {
|
|
403
|
+
parsed = new URL(value);
|
|
404
|
+
} catch {
|
|
405
|
+
throw new TrackerError("invalid_request", `${subject} \u2014 \u043D\u0435 URL.`);
|
|
339
406
|
}
|
|
407
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new TrackerError("invalid_request", `${subject} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C http \u0438\u043B\u0438 https.`);
|
|
408
|
+
return parsed.origin;
|
|
340
409
|
}
|
|
341
410
|
var ERROR_BODY_READ_MAX = 16 * 1024;
|
|
342
411
|
async function requestText(url, request) {
|
|
@@ -346,21 +415,17 @@ async function requestText(url, request) {
|
|
|
346
415
|
if (![skip, bytes, readMax].every((value) => Number.isSafeInteger(value) && value >= 0)) {
|
|
347
416
|
throw new TrackerError("invalid_request", "\u041E\u043A\u043D\u043E \u0447\u0442\u0435\u043D\u0438\u044F \u0442\u0435\u043A\u0441\u0442\u0430 \u2014 \u0446\u0435\u043B\u044B\u0435 \u0447\u0438\u0441\u043B\u0430 \u0431\u0430\u0439\u0442 \u043D\u0435 \u043C\u0435\u043D\u044C\u0448\u0435 0.");
|
|
348
417
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
});
|
|
356
|
-
} catch (error) {
|
|
357
|
-
throw notAnswered(url, error);
|
|
358
|
-
}
|
|
418
|
+
const accept = { accept: request.accept ?? "text/plain" };
|
|
419
|
+
const { response, url: final } = await send(url, request, AbortSignal.timeout(request.timeoutMs ?? CI_LOG_TIMEOUT_MS), accept, {
|
|
420
|
+
method: "GET",
|
|
421
|
+
headers: { ...accept, ...request.headers },
|
|
422
|
+
body: void 0
|
|
423
|
+
});
|
|
359
424
|
if (!response.ok) {
|
|
360
|
-
const head = await readBody(
|
|
361
|
-
throw failureOf(
|
|
425
|
+
const head = await readBody(final, response, { skip: 0, bytes: ERROR_BODY_READ_MAX, from: "head", readMax: ERROR_BODY_READ_MAX });
|
|
426
|
+
throw failureOf(final, response, decodeUtf8(head.window), request);
|
|
362
427
|
}
|
|
363
|
-
const body = await readBody(
|
|
428
|
+
const body = await readBody(final, response, { skip, bytes, from, readMax });
|
|
364
429
|
let start = Math.min(body.start, body.end);
|
|
365
430
|
let end = body.end;
|
|
366
431
|
let window = body.window;
|
|
@@ -743,6 +808,7 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
743
808
|
const target = requireTarget(connection.target, "owner/repo \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F GitHub");
|
|
744
809
|
if (!TARGET.test(target)) throw new TrackerError("invalid_request", "target GitHub \u2014 owner/repo.");
|
|
745
810
|
const api = baseUrl(connection.url, DEFAULT_API);
|
|
811
|
+
const origin = new URL(api).origin;
|
|
746
812
|
const root = `${api}/repos/${target}`;
|
|
747
813
|
const actions = `${root}/actions`;
|
|
748
814
|
const headers = {
|
|
@@ -760,13 +826,13 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
760
826
|
};
|
|
761
827
|
const missingRun = (key) => ({ failure: "not_found", message: `\u0412 GitHub \u043D\u0435\u0442 \u043F\u0440\u043E\u0433\u043E\u043D\u0430 ${key}.` });
|
|
762
828
|
const missingJob = (key) => ({ failure: "not_found", message: `\u0412 GitHub \u043D\u0435\u0442 \u0437\u0430\u0434\u0430\u043D\u0438\u044F ${key}.` });
|
|
763
|
-
const getRun = async (key) => runOf((await requestJson(`${actions}/runs/${runKey(key)}`, { fetch, headers, missing: missingRun(key) })).body);
|
|
829
|
+
const getRun = async (key) => runOf((await requestJson(`${actions}/runs/${runKey(key)}`, { fetch, origin, headers, missing: missingRun(key) })).body);
|
|
764
830
|
const headShaOf = async (query) => {
|
|
765
831
|
if (query.pullRequest === void 0) return query.sha;
|
|
766
832
|
if (query.sha !== void 0) throw new TrackerError("invalid_request", `${RUNS_SUBJECT}: sha \u0438 pullRequest \u0437\u0430\u0434\u0430\u044E\u0442\u0441\u044F \u043F\u043E \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0438 \u2014 \u043F\u0440\u043E\u0433\u043E\u043D\u044B PR \u0431\u0435\u0440\u0443\u0442\u0441\u044F \u043F\u043E \u0435\u0433\u043E \u0433\u043E\u043B\u043E\u0432\u0435.`);
|
|
767
833
|
const pull = query.pullRequest;
|
|
768
834
|
if (!ID.test(pull)) throw new TrackerError("not_found", `\u0412 GitHub \u043D\u0435\u0442 pull request ${pull}.`);
|
|
769
|
-
const { body } = await requestJson(`${root}/pulls/${pull}`, { fetch, headers, missing: { failure: "not_found", message: `\u0412 GitHub \u043D\u0435\u0442 pull request ${pull}.` } });
|
|
835
|
+
const { body } = await requestJson(`${root}/pulls/${pull}`, { fetch, origin, headers, missing: { failure: "not_found", message: `\u0412 GitHub \u043D\u0435\u0442 pull request ${pull}.` } });
|
|
770
836
|
const head = isRecord(body) && isRecord(body.head) ? text(body.head.sha) : void 0;
|
|
771
837
|
if (head === void 0) throw new TrackerError("failed", "GitHub \u043D\u0435 \u0432\u0435\u0440\u043D\u0443\u043B \u0433\u043E\u043B\u043E\u0432\u0443 pull request.");
|
|
772
838
|
return head;
|
|
@@ -776,7 +842,7 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
776
842
|
assertListQuery(WORKFLOWS_SUBJECT, { filters: [], clientSide: [], sorts: [] }, query, []);
|
|
777
843
|
const page = pageOf(query.cursor);
|
|
778
844
|
const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });
|
|
779
|
-
const { body, headers: responseHeaders } = await requestJson(`${actions}/workflows?${params.toString()}`, { fetch, headers });
|
|
845
|
+
const { body, headers: responseHeaders } = await requestJson(`${actions}/workflows?${params.toString()}`, { fetch, origin, headers });
|
|
780
846
|
return { items: rowsOf(body, "workflows").map(workflowOf), ...nextCursorOf(page, responseHeaders.get("link") ?? "") };
|
|
781
847
|
},
|
|
782
848
|
listRuns: async (query) => {
|
|
@@ -794,7 +860,7 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
794
860
|
const created = createdParam(query);
|
|
795
861
|
if (created !== void 0) params.set("created", created);
|
|
796
862
|
const path = query.workflow === void 0 ? `${actions}/runs` : `${actions}/workflows/${encodeURIComponent(query.workflow)}/runs`;
|
|
797
|
-
const { body, headers: responseHeaders } = await requestJson(`${path}?${params.toString()}`, { fetch, headers });
|
|
863
|
+
const { body, headers: responseHeaders } = await requestJson(`${path}?${params.toString()}`, { fetch, origin, headers });
|
|
798
864
|
const items = rowsOf(body, "workflow_runs").map(runOf).filter(
|
|
799
865
|
(run) => (query.status === void 0 || query.status.includes(run.status.category)) && (query.event === void 0 || run.event !== void 0 && query.event.includes(run.event.category)) && inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore)
|
|
800
866
|
);
|
|
@@ -807,22 +873,23 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
807
873
|
assertListQuery(JOBS_SUBJECT, CAPABILITIES.jobs, rest, JOB_FILTERS);
|
|
808
874
|
const page = pageOf(query.cursor);
|
|
809
875
|
const params = new URLSearchParams({ per_page: String(query.limit), page: String(page), filter: allAttempts === true ? "all" : "latest" });
|
|
810
|
-
const { body, headers: responseHeaders } = await requestJson(`${actions}/runs/${run}/jobs?${params.toString()}`, { fetch, headers, missing: missingRun(run) });
|
|
876
|
+
const { body, headers: responseHeaders } = await requestJson(`${actions}/runs/${run}/jobs?${params.toString()}`, { fetch, origin, headers, missing: missingRun(run) });
|
|
811
877
|
const items = rowsOf(body, "jobs").map(jobOf).filter((job) => query.status === void 0 || query.status.includes(job.status.category));
|
|
812
878
|
return { items, ...nextCursorOf(page, responseHeaders.get("link") ?? "") };
|
|
813
879
|
},
|
|
814
880
|
getJob: async (key) => {
|
|
815
881
|
const id = jobKey(key);
|
|
816
|
-
return jobOf((await requestJson(`${actions}/jobs/${id}`, { fetch, headers, missing: missingJob(id) })).body);
|
|
882
|
+
return jobOf((await requestJson(`${actions}/jobs/${id}`, { fetch, origin, headers, missing: missingJob(id) })).body);
|
|
817
883
|
},
|
|
818
884
|
log: async (key, query) => {
|
|
819
885
|
const id = jobKey(key);
|
|
820
886
|
const window = logWindow(query);
|
|
821
|
-
const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, headers, missing: missingJob(id) })).body;
|
|
887
|
+
const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, origin, headers, missing: missingJob(id) })).body;
|
|
822
888
|
const complete = isFinished(statusOf(isRecord(job) ? job : {}).category);
|
|
823
889
|
if (!complete) return { text: "", truncated: false, complete: false, nextCursor: logCursor(0, 0) };
|
|
824
890
|
const response = await requestText(`${actions}/jobs/${id}/logs`, {
|
|
825
891
|
fetch,
|
|
892
|
+
origin,
|
|
826
893
|
headers,
|
|
827
894
|
skip: window.resume?.offset ?? 0,
|
|
828
895
|
keep: { bytes: window.bytes, from: window.from },
|
|
@@ -851,6 +918,7 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
851
918
|
if (count > DISPATCH_INPUTS_MAX) throw new TrackerError("invalid_request", `${TRIGGER_SUBJECT}: workflow_dispatch \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442 \u043D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 ${String(DISPATCH_INPUTS_MAX)} \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043E\u0432.`);
|
|
852
919
|
const { body } = await requestJson(`${actions}/workflows/${encodeURIComponent(workflow)}/dispatches`, {
|
|
853
920
|
fetch,
|
|
921
|
+
origin,
|
|
854
922
|
headers,
|
|
855
923
|
method: "POST",
|
|
856
924
|
body: { ref: input.ref, ...count === 0 ? {} : { inputs }, return_run_details: true }
|
|
@@ -862,6 +930,7 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
862
930
|
const run = runKey(key);
|
|
863
931
|
await requestJson(`${actions}/runs/${run}/${input.failedOnly === true ? "rerun-failed-jobs" : "rerun"}`, {
|
|
864
932
|
fetch,
|
|
933
|
+
origin,
|
|
865
934
|
headers,
|
|
866
935
|
method: "POST",
|
|
867
936
|
body: { enable_debug_logging: input.debug === true },
|
|
@@ -871,15 +940,15 @@ function createGithubCiAdapter({ connection, fetch }) {
|
|
|
871
940
|
},
|
|
872
941
|
rerunJob: async (key, input) => {
|
|
873
942
|
const id = jobKey(key);
|
|
874
|
-
const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, headers, missing: missingJob(id) })).body;
|
|
943
|
+
const job = (await requestJson(`${actions}/jobs/${id}`, { fetch, origin, headers, missing: missingJob(id) })).body;
|
|
875
944
|
const run = runIdOf(isRecord(job) ? job.run_id : void 0);
|
|
876
945
|
if (run === void 0) throw new TrackerError("failed", "GitHub \u043D\u0435 \u0432\u0435\u0440\u043D\u0443\u043B \u043F\u0440\u043E\u0433\u043E\u043D \u0437\u0430\u0434\u0430\u043D\u0438\u044F.");
|
|
877
|
-
await requestJson(`${actions}/jobs/${id}/rerun`, { fetch, headers, method: "POST", body: { enable_debug_logging: input.debug === true }, missing: missingJob(id) });
|
|
946
|
+
await requestJson(`${actions}/jobs/${id}/rerun`, { fetch, origin, headers, method: "POST", body: { enable_debug_logging: input.debug === true }, missing: missingJob(id) });
|
|
878
947
|
return getRun(run);
|
|
879
948
|
},
|
|
880
949
|
cancel: async (key) => {
|
|
881
950
|
const run = runKey(key);
|
|
882
|
-
await requestJson(`${actions}/runs/${run}/cancel`, { fetch, headers, method: "POST", conflictOn: [409], missing: missingRun(run) });
|
|
951
|
+
await requestJson(`${actions}/runs/${run}/cancel`, { fetch, origin, headers, method: "POST", conflictOn: [409], missing: missingRun(run) });
|
|
883
952
|
return getRun(run);
|
|
884
953
|
},
|
|
885
954
|
cancelJob: async () => {
|
|
@@ -1018,7 +1087,9 @@ function gitlabCi() {
|
|
|
1018
1087
|
function createGitlabCiAdapter({ connection, fetch }) {
|
|
1019
1088
|
const target = requireTarget(connection.target, "\u043F\u0443\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442\u0430 GitLab, group/project, \u0438\u043B\u0438 \u0435\u0433\u043E id");
|
|
1020
1089
|
if (!TARGET2.test(target)) throw new TrackerError("invalid_request", "target GitLab \u2014 group/project \u0438\u043B\u0438 \u0447\u0438\u0441\u043B\u043E\u0432\u043E\u0439 id.");
|
|
1021
|
-
const
|
|
1090
|
+
const site = baseUrl(connection.url, DEFAULT_URL);
|
|
1091
|
+
const origin = new URL(site).origin;
|
|
1092
|
+
const api = `${site}/api/v4`;
|
|
1022
1093
|
const project = `${api}/projects/${encodeURIComponent(target)}`;
|
|
1023
1094
|
const headers = connection.token === void 0 || connection.token === "" ? {} : { "private-token": connection.token };
|
|
1024
1095
|
const rawOf = (table, categories) => {
|
|
@@ -1036,7 +1107,7 @@ function createGitlabCiAdapter({ connection, fetch }) {
|
|
|
1036
1107
|
};
|
|
1037
1108
|
const missingPipeline = (key) => ({ failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 \u043F\u0440\u043E\u0433\u043E\u043D\u0430 ${key}.` });
|
|
1038
1109
|
const missingJob = (key) => ({ failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 \u0437\u0430\u0434\u0430\u043D\u0438\u044F ${key}.` });
|
|
1039
|
-
const getPipeline = async (key) => runOf2((await requestJson(`${project}/pipelines/${pipelineKey(key)}`, { fetch, headers, missing: missingPipeline(key) })).body);
|
|
1110
|
+
const getPipeline = async (key) => runOf2((await requestJson(`${project}/pipelines/${pipelineKey(key)}`, { fetch, origin, headers, missing: missingPipeline(key) })).body);
|
|
1040
1111
|
return {
|
|
1041
1112
|
listWorkflows: async () => {
|
|
1042
1113
|
throw new TrackerError("unsupported", "\u041F\u0440\u043E\u0433\u043E\u043D\u044B CI GitLab: \u0441\u043F\u0438\u0441\u043A\u0430 workflow \u0443 GitLab \u043D\u0435\u0442.");
|
|
@@ -1053,7 +1124,7 @@ function createGitlabCiAdapter({ connection, fetch }) {
|
|
|
1053
1124
|
if (query.sort !== void 0) throw new TrackerError("unsupported", "\u041F\u0440\u043E\u0433\u043E\u043D\u044B CI GitLab \u0434\u043B\u044F merge request: \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F.");
|
|
1054
1125
|
if (query.actor !== void 0) throw new TrackerError("unsupported", "\u041F\u0440\u043E\u0433\u043E\u043D\u044B CI GitLab \u0434\u043B\u044F merge request: \u0444\u0438\u043B\u044C\u0442\u0440 actor \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F.");
|
|
1055
1126
|
if (query.workflow !== void 0) throw new TrackerError("unsupported", "\u041F\u0440\u043E\u0433\u043E\u043D\u044B CI GitLab \u0434\u043B\u044F merge request: \u0444\u0438\u043B\u044C\u0442\u0440 workflow \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F.");
|
|
1056
|
-
const result = await requestJson(`${project}/merge_requests/${mr}/pipelines?${params.toString()}`, { fetch, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 merge request ${mr}.` } });
|
|
1127
|
+
const result = await requestJson(`${project}/merge_requests/${mr}/pipelines?${params.toString()}`, { fetch, origin, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 merge request ${mr}.` } });
|
|
1057
1128
|
body = result.body;
|
|
1058
1129
|
responseHeaders = result.headers;
|
|
1059
1130
|
keep = (run) => (query.status === void 0 || query.status.includes(run.status.category)) && (query.event === void 0 || run.event !== void 0 && query.event.includes(run.event.category)) && (query.ref === void 0 || run.ref === query.ref) && (query.sha === void 0 || run.sha === query.sha) && inTimeRange(run.createdAt, query.createdAfter, query.createdBefore) && inTimeRange(run.updatedAt, query.updatedAfter, query.updatedBefore);
|
|
@@ -1075,7 +1146,7 @@ function createGitlabCiAdapter({ connection, fetch }) {
|
|
|
1075
1146
|
if (query.updatedBefore !== void 0) params.set("updated_before", isoTime(query.updatedBefore));
|
|
1076
1147
|
params.set("order_by", query.sort?.field === "updated" ? "updated_at" : "id");
|
|
1077
1148
|
params.set("sort", query.sort?.direction ?? "desc");
|
|
1078
|
-
const result = await requestJson(`${project}/pipelines?${params.toString()}`, { fetch, headers });
|
|
1149
|
+
const result = await requestJson(`${project}/pipelines?${params.toString()}`, { fetch, origin, headers });
|
|
1079
1150
|
body = result.body;
|
|
1080
1151
|
responseHeaders = result.headers;
|
|
1081
1152
|
keep = (run) => (query.status === void 0 || query.status.includes(run.status.category)) && (query.event === void 0 || run.event !== void 0 && query.event.includes(run.event.category));
|
|
@@ -1090,18 +1161,18 @@ function createGitlabCiAdapter({ connection, fetch }) {
|
|
|
1090
1161
|
assertListQuery("\u0417\u0430\u0434\u0430\u043D\u0438\u044F CI GitLab", CAPABILITIES2.jobs, rest, JOB_FILTERS2);
|
|
1091
1162
|
const params = new URLSearchParams({ per_page: String(query.limit), page: String(pageOf2(query.cursor)), include_retried: String(allAttempts ?? false) });
|
|
1092
1163
|
for (const scope of keysFor(GITLAB_CI_STATUSES, query.status ?? [])) params.append("scope[]", scope);
|
|
1093
|
-
const { body, headers: responseHeaders } = await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/jobs?${params.toString()}`, { fetch, headers, missing: missingPipeline(runKey) });
|
|
1164
|
+
const { body, headers: responseHeaders } = await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/jobs?${params.toString()}`, { fetch, origin, headers, missing: missingPipeline(runKey) });
|
|
1094
1165
|
const items = (Array.isArray(body) ? body : []).map(jobOf2);
|
|
1095
1166
|
const next = responseHeaders.get("x-next-page");
|
|
1096
1167
|
return { items, ...next === null || next === "" ? {} : { nextCursor: next } };
|
|
1097
1168
|
},
|
|
1098
|
-
getJob: async (key) => jobOf2((await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, headers, missing: missingJob(key) })).body),
|
|
1169
|
+
getJob: async (key) => jobOf2((await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, origin, headers, missing: missingJob(key) })).body),
|
|
1099
1170
|
log: async (key, query) => {
|
|
1100
1171
|
const window = logWindow(query);
|
|
1101
|
-
const job = (await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, headers, missing: missingJob(key) })).body;
|
|
1172
|
+
const job = (await requestJson(`${project}/jobs/${jobKey(key)}`, { fetch, origin, headers, missing: missingJob(key) })).body;
|
|
1102
1173
|
const rawStatus = isRecord(job) && typeof job.status === "string" ? job.status : "unknown";
|
|
1103
1174
|
const complete = isFinished(lookup(GITLAB_CI_STATUSES, rawStatus, "running"));
|
|
1104
|
-
const response = await requestText(`${project}/jobs/${jobKey(key)}/trace`, { fetch, headers, skip: window.resume?.offset ?? 0, keep: { bytes: window.bytes, from: window.from }, missing: missingJob(key) });
|
|
1175
|
+
const response = await requestText(`${project}/jobs/${jobKey(key)}/trace`, { fetch, origin, headers, skip: window.resume?.offset ?? 0, keep: { bytes: window.bytes, from: window.from }, missing: missingJob(key) });
|
|
1105
1176
|
return logOf({
|
|
1106
1177
|
text: response.text,
|
|
1107
1178
|
truncated: window.from === "tail" ? response.start > 0 : !response.whole,
|
|
@@ -1123,6 +1194,7 @@ function createGitlabCiAdapter({ connection, fetch }) {
|
|
|
1123
1194
|
const variables = Object.entries(input.inputs ?? {}).map(([key, value]) => ({ key, value, variable_type: "env_var" }));
|
|
1124
1195
|
const { body } = await requestJson(`${project}/pipeline`, {
|
|
1125
1196
|
fetch,
|
|
1197
|
+
origin,
|
|
1126
1198
|
headers,
|
|
1127
1199
|
method: "POST",
|
|
1128
1200
|
body: { ref: input.ref, ...variables.length === 0 ? {} : { variables } },
|
|
@@ -1133,17 +1205,17 @@ function createGitlabCiAdapter({ connection, fetch }) {
|
|
|
1133
1205
|
rerun: async (runKey, input) => {
|
|
1134
1206
|
if (input.failedOnly !== true) throw new TrackerError("unsupported", "\u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A CI GitLab \u0443\u043C\u0435\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0443\u043F\u0430\u0432\u0448\u0438\u0435 \u0437\u0430\u0434\u0430\u043D\u0438\u044F: \u0437\u0430\u0434\u0430\u0439\u0442\u0435 failedOnly.");
|
|
1135
1207
|
if (input.debug === true) throw new TrackerError("unsupported", "\u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A CI GitLab \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043E\u0442\u043B\u0430\u0434\u043E\u0447\u043D\u043E\u0435 \u043B\u043E\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435.");
|
|
1136
|
-
return runOf2((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/retry`, { fetch, headers, method: "POST", missing: missingPipeline(runKey) })).body);
|
|
1208
|
+
return runOf2((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/retry`, { fetch, origin, headers, method: "POST", missing: missingPipeline(runKey) })).body);
|
|
1137
1209
|
},
|
|
1138
1210
|
rerunJob: async (jobKeyValue, input) => {
|
|
1139
1211
|
if (input.debug === true) throw new TrackerError("unsupported", "\u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u0437\u0430\u0434\u0430\u043D\u0438\u044F GitLab \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043E\u0442\u043B\u0430\u0434\u043E\u0447\u043D\u043E\u0435 \u043B\u043E\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435.");
|
|
1140
|
-
const body = (await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/retry`, { fetch, headers, method: "POST", missing: missingJob(jobKeyValue) })).body;
|
|
1212
|
+
const body = (await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/retry`, { fetch, origin, headers, method: "POST", missing: missingJob(jobKeyValue) })).body;
|
|
1141
1213
|
const pipeline = isRecord(body) && isRecord(body.pipeline) && typeof body.pipeline.id === "number" ? String(body.pipeline.id) : void 0;
|
|
1142
1214
|
if (pipeline === void 0) throw new TrackerError("failed", "GitLab \u043D\u0435 \u0432\u0435\u0440\u043D\u0443\u043B \u043F\u0430\u0439\u043F\u043B\u0430\u0439\u043D \u043D\u043E\u0432\u043E\u0433\u043E \u0437\u0430\u0434\u0430\u043D\u0438\u044F.");
|
|
1143
1215
|
return getPipeline(pipeline);
|
|
1144
1216
|
},
|
|
1145
|
-
cancel: async (runKey) => runOf2((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/cancel`, { fetch, headers, method: "POST", missing: missingPipeline(runKey) })).body),
|
|
1146
|
-
cancelJob: async (jobKeyValue) => jobOf2((await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/cancel`, { fetch, headers, method: "POST", missing: missingJob(jobKeyValue) })).body)
|
|
1217
|
+
cancel: async (runKey) => runOf2((await requestJson(`${project}/pipelines/${pipelineKey(runKey)}/cancel`, { fetch, origin, headers, method: "POST", missing: missingPipeline(runKey) })).body),
|
|
1218
|
+
cancelJob: async (jobKeyValue) => jobOf2((await requestJson(`${project}/jobs/${jobKey(jobKeyValue)}/cancel`, { fetch, origin, headers, method: "POST", missing: missingJob(jobKeyValue) })).body)
|
|
1147
1219
|
};
|
|
1148
1220
|
}
|
|
1149
1221
|
function pageOf2(cursor) {
|
|
@@ -1228,7 +1300,9 @@ function sourcecraftCi() {
|
|
|
1228
1300
|
function createSourceCraftCiAdapter({ connection, fetch }) {
|
|
1229
1301
|
const target = requireTarget(connection.target, "org/repo \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F SourceCraft");
|
|
1230
1302
|
if (!TARGET3.test(target)) throw new TrackerError("invalid_request", "target SourceCraft \u2014 org/repo.");
|
|
1231
|
-
const
|
|
1303
|
+
const api = baseUrl(connection.url, DEFAULT_API2);
|
|
1304
|
+
const origin = new URL(api).origin;
|
|
1305
|
+
const repo = `${api}/repos/${target}`;
|
|
1232
1306
|
const root = `${repo}/cicd`;
|
|
1233
1307
|
const headers = { authorization: `Bearer ${connection.token ?? ""}` };
|
|
1234
1308
|
const missingRun = (key) => ({ failure: "not_found", message: `\u0412 SourceCraft \u043D\u0435\u0442 \u043F\u0440\u043E\u0433\u043E\u043D\u0430 ${key}.` });
|
|
@@ -1245,14 +1319,14 @@ function createSourceCraftCiAdapter({ connection, fetch }) {
|
|
|
1245
1319
|
runKey(path.run);
|
|
1246
1320
|
return path;
|
|
1247
1321
|
};
|
|
1248
|
-
const getRun = async (key) => runOf3((await requestJson(`${root}/runs/${runKey(key)}`, { fetch, headers, missing: missingRun(key) })).body);
|
|
1322
|
+
const getRun = async (key) => runOf3((await requestJson(`${root}/runs/${runKey(key)}`, { fetch, origin, headers, missing: missingRun(key) })).body);
|
|
1249
1323
|
const getWorkflow = async (run, workflow) => {
|
|
1250
|
-
const { body } = await requestJson(`${root}/runs/${runKey(run)}/${encodeURIComponent(workflow)}`, { fetch, headers, missing: missingWorkflow(run, workflow) });
|
|
1324
|
+
const { body } = await requestJson(`${root}/runs/${runKey(run)}/${encodeURIComponent(workflow)}`, { fetch, origin, headers, missing: missingWorkflow(run, workflow) });
|
|
1251
1325
|
return isRecord(body) ? body : {};
|
|
1252
1326
|
};
|
|
1253
1327
|
const pullIdOf = async (slug) => {
|
|
1254
1328
|
if (!PR_SLUG.test(slug)) throw new TrackerError("invalid_request", `\u041A\u043B\u044E\u0447 pull request SourceCraft \u2014 slug \u0438\u0437 \u0431\u0443\u043A\u0432, \u0446\u0438\u0444\u0440, _ \u0438 - \u0434\u043B\u0438\u043D\u043E\u0439 \u0434\u043E 100.`);
|
|
1255
|
-
const { body } = await requestJson(`${repo}/pulls/${slug}`, { fetch, headers, missing: { failure: "not_found", message: `\u0412 SourceCraft \u043D\u0435\u0442 pull request ${slug}.` } });
|
|
1329
|
+
const { body } = await requestJson(`${repo}/pulls/${slug}`, { fetch, origin, headers, missing: { failure: "not_found", message: `\u0412 SourceCraft \u043D\u0435\u0442 pull request ${slug}.` } });
|
|
1256
1330
|
const id = isRecord(body) ? text(body.id) : void 0;
|
|
1257
1331
|
if (id === void 0) throw new TrackerError("failed", `\u041E\u0442\u0432\u0435\u0442 SourceCraft \u043D\u0430 /pulls/${slug} \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 id.`);
|
|
1258
1332
|
return id;
|
|
@@ -1282,7 +1356,7 @@ function createSourceCraftCiAdapter({ connection, fetch }) {
|
|
|
1282
1356
|
const pullId = query.pullRequest === void 0 ? void 0 : await pullIdOf(query.pullRequest);
|
|
1283
1357
|
const params = new URLSearchParams({ page_size: String(query.limit) });
|
|
1284
1358
|
if (query.cursor !== void 0) params.set("page_token", query.cursor);
|
|
1285
|
-
const { body } = await requestJson(`${root}/runs?${params.toString()}`, { fetch, headers });
|
|
1359
|
+
const { body } = await requestJson(`${root}/runs?${params.toString()}`, { fetch, origin, headers });
|
|
1286
1360
|
const record = isRecord(body) ? body : {};
|
|
1287
1361
|
const items = recordList(record.runs).map((raw) => pullSlugOf(runOf3(raw), raw, pullId, query.pullRequest)).filter((run) => keepsRun(run, query));
|
|
1288
1362
|
const token = text(record.next_page_token);
|
|
@@ -1334,7 +1408,7 @@ function createSourceCraftCiAdapter({ connection, fetch }) {
|
|
|
1334
1408
|
unread = true;
|
|
1335
1409
|
break;
|
|
1336
1410
|
}
|
|
1337
|
-
const { body } = await requestJson(`${root}/logs/${path}?page=${String(page)}`, { fetch, headers, missing: missingJob(key) });
|
|
1411
|
+
const { body } = await requestJson(`${root}/logs/${path}?page=${String(page)}`, { fetch, origin, headers, missing: missingJob(key) });
|
|
1338
1412
|
const record = isRecord(body) ? body : {};
|
|
1339
1413
|
const data = encoder.encode(text(record.logs) ?? "");
|
|
1340
1414
|
const rest = skip >= data.length ? new Uint8Array(0) : data.subarray(skip);
|
|
@@ -1387,7 +1461,7 @@ function createSourceCraftCiAdapter({ connection, fetch }) {
|
|
|
1387
1461
|
if (workflows.length === 0) throw new TrackerError("invalid_request", "\u0417\u0430\u043F\u0443\u0441\u043A CI SourceCraft: \u043D\u0443\u0436\u0435\u043D \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u0438\u043D workflow.");
|
|
1388
1462
|
const values = Object.entries(input.inputs ?? {}).map(([name, value]) => ({ name, value }));
|
|
1389
1463
|
const head = input.refType === "tag" ? { tag: input.ref } : { branch: input.ref };
|
|
1390
|
-
const { body } = await requestJson(`${root}/runs`, { fetch, headers, method: "POST", body: { head, workflows: workflows.map((name) => ({ name, values })) } });
|
|
1464
|
+
const { body } = await requestJson(`${root}/runs`, { fetch, origin, headers, method: "POST", body: { head, workflows: workflows.map((name) => ({ name, values })) } });
|
|
1391
1465
|
return { run: runOf3(body) };
|
|
1392
1466
|
},
|
|
1393
1467
|
// Публичный API SourceCraft не умеет ни перезапускать, ни отменять (§1.3): отказ без запроса (§3.6).
|
|
@@ -1583,6 +1657,7 @@ function createGithubPullAdapter({ connection, fetch }) {
|
|
|
1583
1657
|
const target = requireTarget(connection.target, "owner/repo \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F GitHub");
|
|
1584
1658
|
if (!TARGET4.test(target)) throw new TrackerError("invalid_request", "target GitHub \u2014 owner/repo.");
|
|
1585
1659
|
const api = baseUrl(connection.url, DEFAULT_API3);
|
|
1660
|
+
const origin = new URL(api).origin;
|
|
1586
1661
|
const root = `${api}/repos/${target}/pulls`;
|
|
1587
1662
|
const issues = `${api}/repos/${target}/issues`;
|
|
1588
1663
|
const owner = target.split("/")[0] ?? target;
|
|
@@ -1596,7 +1671,7 @@ function createGithubPullAdapter({ connection, fetch }) {
|
|
|
1596
1671
|
if (!NUMBER.test(key)) throw new TrackerError("not_found", `\u0412 GitHub \u043D\u0435\u0442 PR ${key}.`);
|
|
1597
1672
|
return key;
|
|
1598
1673
|
};
|
|
1599
|
-
const getPull = async (key) => pullOf((await requestJson(`${root}/${number(key)}`, { fetch, headers, missing: missing(key) })).body);
|
|
1674
|
+
const getPull = async (key) => pullOf((await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, missing: missing(key) })).body);
|
|
1600
1675
|
return {
|
|
1601
1676
|
list: async (query) => {
|
|
1602
1677
|
assertListQuery(LIST_SUBJECT, PULL_CAPABILITIES.list, query, pullRequestFilterSchema.options);
|
|
@@ -1609,25 +1684,25 @@ function createGithubPullAdapter({ connection, fetch }) {
|
|
|
1609
1684
|
params.set("sort", query.sort.field);
|
|
1610
1685
|
params.set("direction", query.sort.direction ?? "desc");
|
|
1611
1686
|
}
|
|
1612
|
-
const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });
|
|
1687
|
+
const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });
|
|
1613
1688
|
const items = (Array.isArray(body) ? body : []).map(pullOf).filter((pull) => matchesPage(pull, query, status));
|
|
1614
1689
|
return { items, ...nextOf(responseHeaders.get("link"), page) };
|
|
1615
1690
|
},
|
|
1616
1691
|
get: (key) => getPull(key),
|
|
1617
|
-
create: async (input) => pullOf((await requestJson(root, { fetch, headers, method: "POST", body: createBody(input) })).body),
|
|
1692
|
+
create: async (input) => pullOf((await requestJson(root, { fetch, origin, headers, method: "POST", body: createBody(input) })).body),
|
|
1618
1693
|
update: async (key, patch) => {
|
|
1619
1694
|
if (patch.status === "draft") throw new TrackerError("unsupported", "PR GitHub: \u043F\u0435\u0440\u0435\u0432\u043E\u0434 \u0432 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u0447\u0435\u0440\u0435\u0437 REST.");
|
|
1620
1695
|
const current = patch.status === "open" ? await getPull(key) : void 0;
|
|
1621
1696
|
if (current?.status.category === "draft") throw new TrackerError("unsupported", "PR GitHub: \u0441\u043D\u044F\u0442\u0438\u0435 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0430 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E \u0447\u0435\u0440\u0435\u0437 REST.");
|
|
1622
1697
|
if (current !== void 0 && current.status.category === "open" && patch.title === void 0 && patch.description === void 0 && patch.target === void 0) return current;
|
|
1623
|
-
return pullOf((await requestJson(`${root}/${number(key)}`, { fetch, headers, method: "PATCH", body: patchBody(patch), missing: missing(key) })).body);
|
|
1698
|
+
return pullOf((await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, method: "PATCH", body: patchBody(patch), missing: missing(key) })).body);
|
|
1624
1699
|
},
|
|
1625
1700
|
merge: async (key, input) => {
|
|
1626
1701
|
if (input.deleteSource === true) throw new TrackerError("unsupported", "PR GitHub: \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u0432\u0435\u0442\u043A\u0438-\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430 \u043F\u0440\u0438 \u0441\u043B\u0438\u044F\u043D\u0438\u0438 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E.");
|
|
1627
1702
|
if (input.method !== void 0 && !PULL_CAPABILITIES.merge.includes(input.method)) {
|
|
1628
1703
|
throw new TrackerError("unsupported", `PR GitHub: \u0441\u043B\u0438\u044F\u043D\u0438\u0435 \u0441\u043F\u043E\u0441\u043E\u0431\u043E\u043C ${input.method} \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F.`);
|
|
1629
1704
|
}
|
|
1630
|
-
await requestJson(`${root}/${number(key)}/merge`, { fetch, headers, method: "PUT", body: mergeBody(input), conflictOn: [405, 409], missing: missing(key) });
|
|
1705
|
+
await requestJson(`${root}/${number(key)}/merge`, { fetch, origin, headers, method: "PUT", body: mergeBody(input), conflictOn: [405, 409], missing: missing(key) });
|
|
1631
1706
|
return getPull(key);
|
|
1632
1707
|
},
|
|
1633
1708
|
comments: async (key, query) => {
|
|
@@ -1635,10 +1710,10 @@ function createGithubPullAdapter({ connection, fetch }) {
|
|
|
1635
1710
|
const page = pageOf3(query.cursor);
|
|
1636
1711
|
const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });
|
|
1637
1712
|
if (query.updatedAfter !== void 0) params.set("since", isoTime(query.updatedAfter));
|
|
1638
|
-
const { body, headers: responseHeaders } = await requestJson(`${issues}/${number(key)}/comments?${params.toString()}`, { fetch, headers, missing: missing(key) });
|
|
1713
|
+
const { body, headers: responseHeaders } = await requestJson(`${issues}/${number(key)}/comments?${params.toString()}`, { fetch, origin, headers, missing: missing(key) });
|
|
1639
1714
|
return { items: (Array.isArray(body) ? body : []).map(commentOf), ...nextOf(responseHeaders.get("link"), page) };
|
|
1640
1715
|
},
|
|
1641
|
-
comment: async (key, body) => commentOf((await requestJson(`${issues}/${number(key)}/comments`, { fetch, headers, method: "POST", body: { body }, missing: missing(key) })).body)
|
|
1716
|
+
comment: async (key, body) => commentOf((await requestJson(`${issues}/${number(key)}/comments`, { fetch, origin, headers, method: "POST", body: { body }, missing: missing(key) })).body)
|
|
1642
1717
|
};
|
|
1643
1718
|
}
|
|
1644
1719
|
function pageOf3(cursor) {
|
|
@@ -1765,6 +1840,7 @@ function githubTracker() {
|
|
|
1765
1840
|
features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: true, statuses: ["open", "in_progress", "done", "declined"] }
|
|
1766
1841
|
},
|
|
1767
1842
|
create: (context) => createGithubAdapter(context, issues),
|
|
1843
|
+
origin: (connection) => new URL(baseUrl(connection.url, DEFAULT_API4)).origin,
|
|
1768
1844
|
issues,
|
|
1769
1845
|
pulls: githubPulls(),
|
|
1770
1846
|
ci: githubCi()
|
|
@@ -1774,6 +1850,7 @@ function createGithubAdapter({ connection, fetch }, capabilities) {
|
|
|
1774
1850
|
const target = requireTarget(connection.target, "owner/repo \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F GitHub");
|
|
1775
1851
|
if (!TARGET5.test(target)) throw new TrackerError("invalid_request", "target GitHub \u2014 owner/repo.");
|
|
1776
1852
|
const api = baseUrl(connection.url, DEFAULT_API4);
|
|
1853
|
+
const origin = new URL(api).origin;
|
|
1777
1854
|
const root = `${api}/repos/${target}/issues`;
|
|
1778
1855
|
const headers = {
|
|
1779
1856
|
accept: "application/vnd.github+json",
|
|
@@ -1785,7 +1862,7 @@ function createGithubAdapter({ connection, fetch }, capabilities) {
|
|
|
1785
1862
|
return key;
|
|
1786
1863
|
};
|
|
1787
1864
|
const rawOf = async (key) => {
|
|
1788
|
-
const { body } = await requestJson(`${root}/${number(key)}`, { fetch, headers, missingIsIssue: true });
|
|
1865
|
+
const { body } = await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, missingIsIssue: true });
|
|
1789
1866
|
return isRecord(body) ? body : {};
|
|
1790
1867
|
};
|
|
1791
1868
|
return {
|
|
@@ -1795,7 +1872,7 @@ function createGithubAdapter({ connection, fetch }, capabilities) {
|
|
|
1795
1872
|
const page = pageOf4(query.cursor);
|
|
1796
1873
|
const search = needsSearch(query);
|
|
1797
1874
|
const params = search ? searchParams(target, query, page) : issuesParams(query, page);
|
|
1798
|
-
const { body, headers: responseHeaders } = await requestJson(`${search ? `${api}/search/issues` : root}?${params.toString()}`, { fetch, headers });
|
|
1875
|
+
const { body, headers: responseHeaders } = await requestJson(`${search ? `${api}/search/issues` : root}?${params.toString()}`, { fetch, origin, headers });
|
|
1799
1876
|
return issuePageOf(rowsOf2(body, search), query, responseHeaders.get("link") ?? "", page);
|
|
1800
1877
|
},
|
|
1801
1878
|
get: async (key) => issueOf(await rawOf(key)),
|
|
@@ -1807,11 +1884,11 @@ function createGithubAdapter({ connection, fetch }, capabilities) {
|
|
|
1807
1884
|
...labels.length === 0 ? {} : { labels },
|
|
1808
1885
|
...input.assignee === void 0 ? {} : { assignees: [input.assignee] }
|
|
1809
1886
|
};
|
|
1810
|
-
return issueOf((await requestJson(root, { fetch, headers, method: "POST", body })).body);
|
|
1887
|
+
return issueOf((await requestJson(root, { fetch, origin, headers, method: "POST", body })).body);
|
|
1811
1888
|
},
|
|
1812
1889
|
update: async (key, patch) => {
|
|
1813
1890
|
const current = patch.labels === void 0 && patch.priority === void 0 && patch.status === void 0 ? void 0 : issueOf(await rawOf(key));
|
|
1814
|
-
const response = await requestJson(`${root}/${number(key)}`, { fetch, headers, method: "PATCH", body: patchBody2(patch, current), missingIsIssue: true });
|
|
1891
|
+
const response = await requestJson(`${root}/${number(key)}`, { fetch, origin, headers, method: "PATCH", body: patchBody2(patch, current), missingIsIssue: true });
|
|
1815
1892
|
return issueOf(response.body);
|
|
1816
1893
|
},
|
|
1817
1894
|
comments: async (key, query) => {
|
|
@@ -1819,10 +1896,10 @@ function createGithubAdapter({ connection, fetch }, capabilities) {
|
|
|
1819
1896
|
const page = pageOf4(query.cursor);
|
|
1820
1897
|
const params = new URLSearchParams({ per_page: String(query.limit), page: String(page) });
|
|
1821
1898
|
if (query.updatedAfter !== void 0) params.set("since", isoTime(query.updatedAfter));
|
|
1822
|
-
const { body, headers: responseHeaders } = await requestJson(`${root}/${number(key)}/comments?${params.toString()}`, { fetch, headers, missingIsIssue: true });
|
|
1899
|
+
const { body, headers: responseHeaders } = await requestJson(`${root}/${number(key)}/comments?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });
|
|
1823
1900
|
return { items: (Array.isArray(body) ? body : []).map(commentOf2), .../rel="next"/.test(responseHeaders.get("link") ?? "") ? { nextCursor: String(page + 1) } : {} };
|
|
1824
1901
|
},
|
|
1825
|
-
comment: async (key, body) => commentOf2((await requestJson(`${root}/${number(key)}/comments`, { fetch, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
1902
|
+
comment: async (key, body) => commentOf2((await requestJson(`${root}/${number(key)}/comments`, { fetch, origin, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
1826
1903
|
};
|
|
1827
1904
|
}
|
|
1828
1905
|
function pageOf4(cursor) {
|
|
@@ -1970,13 +2047,15 @@ function gitlabPulls() {
|
|
|
1970
2047
|
function createGitlabPullAdapter({ connection, fetch }) {
|
|
1971
2048
|
const target = requireTarget(connection.target, "\u043F\u0443\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442\u0430 GitLab, group/project, \u0438\u043B\u0438 \u0435\u0433\u043E id");
|
|
1972
2049
|
if (!TARGET6.test(target)) throw new TrackerError("invalid_request", "target GitLab \u2014 group/project \u0438\u043B\u0438 \u0447\u0438\u0441\u043B\u043E\u0432\u043E\u0439 id.");
|
|
1973
|
-
const
|
|
2050
|
+
const site = baseUrl(connection.url, DEFAULT_URL2);
|
|
2051
|
+
const origin = new URL(site).origin;
|
|
2052
|
+
const root = `${site}/api/v4/projects/${encodeURIComponent(target)}/merge_requests`;
|
|
1974
2053
|
const headers = connection.token === void 0 || connection.token === "" ? {} : { "private-token": connection.token };
|
|
1975
2054
|
const iid = (key) => {
|
|
1976
2055
|
if (!IID.test(key)) throw new TrackerError("not_found", `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.`);
|
|
1977
2056
|
return key;
|
|
1978
2057
|
};
|
|
1979
|
-
const currentOf = async (key) => pullOf2((await requestJson(`${root}/${iid(key)}`, { fetch, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
2058
|
+
const currentOf = async (key) => pullOf2((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
1980
2059
|
return {
|
|
1981
2060
|
list: async (query) => {
|
|
1982
2061
|
assertListQuery("PR GitLab", PULL_CAPABILITIES2.list, query, pullRequestFilterSchema.options);
|
|
@@ -2001,7 +2080,7 @@ function createGitlabPullAdapter({ connection, fetch }) {
|
|
|
2001
2080
|
if (query.createdBefore !== void 0) params.set("created_before", isoTime(query.createdBefore));
|
|
2002
2081
|
if (query.updatedAfter !== void 0) params.set("updated_after", isoTime(query.updatedAfter));
|
|
2003
2082
|
if (query.updatedBefore !== void 0) params.set("updated_before", isoTime(query.updatedBefore));
|
|
2004
|
-
const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });
|
|
2083
|
+
const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });
|
|
2005
2084
|
const next = responseHeaders.get("x-next-page");
|
|
2006
2085
|
const items = (Array.isArray(body) ? body : []).map(pullOf2);
|
|
2007
2086
|
return {
|
|
@@ -2017,7 +2096,7 @@ function createGitlabPullAdapter({ connection, fetch }) {
|
|
|
2017
2096
|
title: (input.draft === true ? GITLAB_DRAFT_PREFIX : "") + input.title,
|
|
2018
2097
|
...input.description === void 0 ? {} : { description: input.description }
|
|
2019
2098
|
};
|
|
2020
|
-
return pullOf2((await requestJson(root, { fetch, headers, method: "POST", body, conflictOn: [409] })).body);
|
|
2099
|
+
return pullOf2((await requestJson(root, { fetch, origin, headers, method: "POST", body, conflictOn: [409] })).body);
|
|
2021
2100
|
},
|
|
2022
2101
|
update: async (key, patch) => {
|
|
2023
2102
|
const current = patch.status === void 0 ? void 0 : await currentOf(key);
|
|
@@ -2025,8 +2104,8 @@ function createGitlabPullAdapter({ connection, fetch }) {
|
|
|
2025
2104
|
throw new TrackerError("unsupported", "PR GitLab: \u043F\u0435\u0440\u0435\u0432\u043E\u0434 \u0437\u0430\u043A\u0440\u044B\u0442\u043E\u0433\u043E MR \u0432 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D.");
|
|
2026
2105
|
}
|
|
2027
2106
|
const body = patchBody3(patch, current);
|
|
2028
|
-
if (Object.keys(body).length === 0) return current ?? pullOf2((await requestJson(`${root}/${iid(key)}`, { fetch, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
2029
|
-
return pullOf2((await requestJson(`${root}/${iid(key)}`, { fetch, headers, method: "PUT", body, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
2107
|
+
if (Object.keys(body).length === 0) return current ?? pullOf2((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
2108
|
+
return pullOf2((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, method: "PUT", body, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
2030
2109
|
},
|
|
2031
2110
|
merge: async (key, input) => {
|
|
2032
2111
|
if (input.method !== void 0 && !PULL_CAPABILITIES2.merge.includes(input.method)) {
|
|
@@ -2039,18 +2118,18 @@ function createGitlabPullAdapter({ connection, fetch }) {
|
|
|
2039
2118
|
...input.deleteSource === void 0 ? {} : { should_remove_source_branch: input.deleteSource },
|
|
2040
2119
|
...input.headSha === void 0 ? {} : { sha: input.headSha }
|
|
2041
2120
|
};
|
|
2042
|
-
return pullOf2((await requestJson(`${root}/${iid(key)}/merge`, { fetch, headers, method: "PUT", body, conflictOn: [405, 409, 422], missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
2121
|
+
return pullOf2((await requestJson(`${root}/${iid(key)}/merge`, { fetch, origin, headers, method: "PUT", body, conflictOn: [405, 409, 422], missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body);
|
|
2043
2122
|
},
|
|
2044
2123
|
comments: async (key, query) => {
|
|
2045
2124
|
assertCommentQuery("\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0438 GitLab", PULL_CAPABILITIES2.comments, query);
|
|
2046
2125
|
const page = pageOf5(query.cursor);
|
|
2047
2126
|
const params = new URLSearchParams({ sort: query.order ?? "asc", order_by: "created_at", per_page: String(query.limit), page: String(page) });
|
|
2048
|
-
const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } });
|
|
2127
|
+
const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, origin, headers, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } });
|
|
2049
2128
|
const next = responseHeaders.get("x-next-page");
|
|
2050
2129
|
const items = (Array.isArray(body) ? body : []).filter((note) => isRecord(note) && note.system !== true && inTimeRange(toTimestamp(note.updated_at), query.updatedAfter, void 0)).map(commentOf3);
|
|
2051
2130
|
return { items, ...next === null || next === "" ? {} : { nextCursor: next } };
|
|
2052
2131
|
},
|
|
2053
|
-
comment: async (key, body) => commentOf3((await requestJson(`${root}/${iid(key)}/notes`, { fetch, headers, method: "POST", body: { body }, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body)
|
|
2132
|
+
comment: async (key, body) => commentOf3((await requestJson(`${root}/${iid(key)}/notes`, { fetch, origin, headers, method: "POST", body: { body }, missing: { failure: "not_found", message: `\u0412 GitLab \u043D\u0435\u0442 MR ${key}.` } })).body)
|
|
2054
2133
|
};
|
|
2055
2134
|
}
|
|
2056
2135
|
function pageOf5(cursor) {
|
|
@@ -2165,6 +2244,7 @@ function gitlabTracker() {
|
|
|
2165
2244
|
features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: false, statuses: ["open", "in_progress", "done"] }
|
|
2166
2245
|
},
|
|
2167
2246
|
create: (context) => createGitlabAdapter(context),
|
|
2247
|
+
origin: (connection) => new URL(baseUrl(connection.url, DEFAULT_URL3)).origin,
|
|
2168
2248
|
issues: ISSUE_CAPABILITIES,
|
|
2169
2249
|
pulls: gitlabPulls(),
|
|
2170
2250
|
ci: gitlabCi()
|
|
@@ -2173,13 +2253,15 @@ function gitlabTracker() {
|
|
|
2173
2253
|
function createGitlabAdapter({ connection, fetch }) {
|
|
2174
2254
|
const target = requireTarget(connection.target, "\u043F\u0443\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442\u0430 GitLab, group/project, \u0438\u043B\u0438 \u0435\u0433\u043E id");
|
|
2175
2255
|
if (!TARGET7.test(target)) throw new TrackerError("invalid_request", "target GitLab \u2014 group/project \u0438\u043B\u0438 \u0447\u0438\u0441\u043B\u043E\u0432\u043E\u0439 id.");
|
|
2176
|
-
const
|
|
2256
|
+
const site = baseUrl(connection.url, DEFAULT_URL3);
|
|
2257
|
+
const origin = new URL(site).origin;
|
|
2258
|
+
const root = `${site}/api/v4/projects/${encodeURIComponent(target)}/issues`;
|
|
2177
2259
|
const headers = connection.token === void 0 || connection.token === "" ? {} : { "private-token": connection.token };
|
|
2178
2260
|
const iid = (key) => {
|
|
2179
2261
|
if (!IID2.test(key)) throw new TrackerError("unknown_issue", `\u0412 GitLab \u043D\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 ${key}.`);
|
|
2180
2262
|
return key;
|
|
2181
2263
|
};
|
|
2182
|
-
const currentOf = async (key) => issueOf2((await requestJson(`${root}/${iid(key)}`, { fetch, headers, missingIsIssue: true })).body);
|
|
2264
|
+
const currentOf = async (key) => issueOf2((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, missingIsIssue: true })).body);
|
|
2183
2265
|
return {
|
|
2184
2266
|
list: async (query) => {
|
|
2185
2267
|
assertListQuery("\u0417\u0430\u0434\u0430\u0447\u0438 GitLab", ISSUE_CAPABILITIES.list, query, ISSUE_FILTERS);
|
|
@@ -2202,7 +2284,7 @@ function createGitlabAdapter({ connection, fetch }) {
|
|
|
2202
2284
|
if (query.createdBefore !== void 0) params.set("created_before", isoTime(query.createdBefore));
|
|
2203
2285
|
if (query.updatedAfter !== void 0) params.set("updated_after", isoTime(query.updatedAfter));
|
|
2204
2286
|
if (query.updatedBefore !== void 0) params.set("updated_before", isoTime(query.updatedBefore));
|
|
2205
|
-
const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });
|
|
2287
|
+
const { body, headers: responseHeaders } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });
|
|
2206
2288
|
const items = (Array.isArray(body) ? body : []).map(issueOf2);
|
|
2207
2289
|
const next = responseHeaders.get("x-next-page");
|
|
2208
2290
|
return {
|
|
@@ -2214,22 +2296,22 @@ function createGitlabAdapter({ connection, fetch }) {
|
|
|
2214
2296
|
create: async (input) => {
|
|
2215
2297
|
const labels = composeLabels2(input.labels ?? [], input.priority, void 0);
|
|
2216
2298
|
const body = { title: input.title, ...input.description === void 0 ? {} : { description: input.description }, ...labels.length === 0 ? {} : { labels: labels.join(",") } };
|
|
2217
|
-
return issueOf2((await requestJson(root, { fetch, headers, method: "POST", body })).body);
|
|
2299
|
+
return issueOf2((await requestJson(root, { fetch, origin, headers, method: "POST", body })).body);
|
|
2218
2300
|
},
|
|
2219
2301
|
update: async (key, patch) => {
|
|
2220
2302
|
const current = patch.labels === void 0 && patch.priority === void 0 && patch.status === void 0 ? void 0 : await currentOf(key);
|
|
2221
|
-
return issueOf2((await requestJson(`${root}/${iid(key)}`, { fetch, headers, method: "PUT", body: patchBody4(patch, current), missingIsIssue: true })).body);
|
|
2303
|
+
return issueOf2((await requestJson(`${root}/${iid(key)}`, { fetch, origin, headers, method: "PUT", body: patchBody4(patch, current), missingIsIssue: true })).body);
|
|
2222
2304
|
},
|
|
2223
2305
|
comments: async (key, query) => {
|
|
2224
2306
|
assertCommentQuery("\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0438 GitLab", ISSUE_CAPABILITIES.comments, query);
|
|
2225
2307
|
const page = pageOf6(query.cursor);
|
|
2226
2308
|
const params = new URLSearchParams({ sort: query.order ?? "asc", order_by: "created_at", per_page: String(query.limit), page: String(page) });
|
|
2227
|
-
const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, headers, missingIsIssue: true });
|
|
2309
|
+
const { body, headers: responseHeaders } = await requestJson(`${root}/${iid(key)}/notes?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });
|
|
2228
2310
|
const next = responseHeaders.get("x-next-page");
|
|
2229
2311
|
const items = (Array.isArray(body) ? body : []).filter((note) => isRecord(note) && note.system !== true && inTimeRange(toTimestamp(note.updated_at), query.updatedAfter, void 0)).map(commentOf4);
|
|
2230
2312
|
return { items, ...next === null || next === "" ? {} : { nextCursor: next } };
|
|
2231
2313
|
},
|
|
2232
|
-
comment: async (key, body) => commentOf4((await requestJson(`${root}/${iid(key)}/notes`, { fetch, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
2314
|
+
comment: async (key, body) => commentOf4((await requestJson(`${root}/${iid(key)}/notes`, { fetch, origin, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
2233
2315
|
};
|
|
2234
2316
|
}
|
|
2235
2317
|
function pageOf6(cursor) {
|
|
@@ -2315,14 +2397,19 @@ function jiraTracker() {
|
|
|
2315
2397
|
features: { create: true, update: true, comment: true, priority: true, labels: true, assignee: false, statuses: ["open", "in_progress", "done"] }
|
|
2316
2398
|
},
|
|
2317
2399
|
create: (context) => createJiraAdapter(context),
|
|
2400
|
+
origin: (connection) => new URL(siteOf(connection)).origin,
|
|
2318
2401
|
issues: ISSUE_CAPABILITIES2
|
|
2319
2402
|
};
|
|
2320
2403
|
}
|
|
2321
|
-
function
|
|
2404
|
+
function siteOf(connection) {
|
|
2322
2405
|
if (connection.url === void 0) throw new TrackerError("invalid_request", "\u041D\u0435 \u0437\u0430\u0434\u0430\u043D \u0430\u0434\u0440\u0435\u0441 Jira.");
|
|
2406
|
+
return baseUrl(connection.url, connection.url);
|
|
2407
|
+
}
|
|
2408
|
+
function createJiraAdapter({ connection, fetch }) {
|
|
2409
|
+
const site = siteOf(connection);
|
|
2323
2410
|
const project = requireTarget(connection.target, "\u043A\u043B\u044E\u0447 \u043F\u0440\u043E\u0435\u043A\u0442\u0430 Jira, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 PROJ");
|
|
2324
2411
|
if (!PROJECT_KEY.test(project)) throw new TrackerError("invalid_request", "target Jira \u2014 \u043A\u043B\u044E\u0447 \u043F\u0440\u043E\u0435\u043A\u0442\u0430: \u0437\u0430\u0433\u043B\u0430\u0432\u043D\u044B\u0435 \u0431\u0443\u043A\u0432\u044B \u0438 \u0446\u0438\u0444\u0440\u044B.");
|
|
2325
|
-
const
|
|
2412
|
+
const origin = new URL(site).origin;
|
|
2326
2413
|
const api = `${site}/rest/api/2`;
|
|
2327
2414
|
const token = connection.token ?? "";
|
|
2328
2415
|
const headers = { authorization: connection.user === void 0 ? `Bearer ${token}` : `Basic ${Buffer.from(`${connection.user}:${token}`).toString("base64")}` };
|
|
@@ -2331,7 +2418,7 @@ function createJiraAdapter({ connection, fetch }) {
|
|
|
2331
2418
|
return value;
|
|
2332
2419
|
};
|
|
2333
2420
|
const toIssue2 = (raw) => issueOf3(raw, site);
|
|
2334
|
-
const load = async (value) => toIssue2((await requestJson(`${api}/issue/${key(value)}?fields=${FIELDS}`, { fetch, headers, missingIsIssue: true })).body);
|
|
2421
|
+
const load = async (value) => toIssue2((await requestJson(`${api}/issue/${key(value)}?fields=${FIELDS}`, { fetch, origin, headers, missingIsIssue: true })).body);
|
|
2335
2422
|
return {
|
|
2336
2423
|
list: async (query) => {
|
|
2337
2424
|
assertListQuery("\u0417\u0430\u0434\u0430\u0447\u0438 Jira", ISSUE_CAPABILITIES2.list, query, ISSUE_FILTERS);
|
|
@@ -2341,7 +2428,7 @@ function createJiraAdapter({ connection, fetch }) {
|
|
|
2341
2428
|
const params2 = new URLSearchParams({ jql, fields: FIELDS, maxResults: String(query.limit) });
|
|
2342
2429
|
if (query.cursor !== void 0) params2.set("nextPageToken", query.cursor);
|
|
2343
2430
|
try {
|
|
2344
|
-
const { body: body2 } = await requestJson(`${api}/search/jql?${params2.toString()}`, { fetch, headers });
|
|
2431
|
+
const { body: body2 } = await requestJson(`${api}/search/jql?${params2.toString()}`, { fetch, origin, headers });
|
|
2345
2432
|
const record2 = isRecord(body2) ? body2 : {};
|
|
2346
2433
|
const next = text(record2.nextPageToken);
|
|
2347
2434
|
return { items: (Array.isArray(record2.issues) ? record2.issues : []).map(toIssue2), ...next === void 0 || record2.isLast === true ? {} : { nextCursor: next } };
|
|
@@ -2351,7 +2438,7 @@ function createJiraAdapter({ connection, fetch }) {
|
|
|
2351
2438
|
}
|
|
2352
2439
|
const startAt = query.cursor?.startsWith("s:") === true ? Number(query.cursor.slice(2)) : 0;
|
|
2353
2440
|
const params = new URLSearchParams({ jql, fields: FIELDS, maxResults: String(query.limit), startAt: String(Number.isInteger(startAt) && startAt >= 0 ? startAt : 0) });
|
|
2354
|
-
const { body } = await requestJson(`${api}/search?${params.toString()}`, { fetch, headers });
|
|
2441
|
+
const { body } = await requestJson(`${api}/search?${params.toString()}`, { fetch, origin, headers });
|
|
2355
2442
|
const record = isRecord(body) ? body : {};
|
|
2356
2443
|
const issues = Array.isArray(record.issues) ? record.issues : [];
|
|
2357
2444
|
const total = typeof record.total === "number" ? record.total : 0;
|
|
@@ -2368,22 +2455,22 @@ function createJiraAdapter({ connection, fetch }) {
|
|
|
2368
2455
|
...input.priority === void 0 ? {} : { priority: { name: JIRA_PRIORITY_NAMES[input.priority] } },
|
|
2369
2456
|
...input.labels === void 0 ? {} : { labels: input.labels.map((label) => label.replace(/\s+/g, "-")) }
|
|
2370
2457
|
};
|
|
2371
|
-
const { body } = await requestJson(`${api}/issue`, { fetch, headers, method: "POST", body: { fields } });
|
|
2458
|
+
const { body } = await requestJson(`${api}/issue`, { fetch, origin, headers, method: "POST", body: { fields } });
|
|
2372
2459
|
const created = isRecord(body) ? text(body.key) : void 0;
|
|
2373
2460
|
if (created === void 0) throw new TrackerError("failed", "Jira \u0441\u043E\u0437\u0434\u0430\u043B\u0430 \u0437\u0430\u0434\u0430\u0447\u0443, \u043D\u043E \u043D\u0435 \u0432\u0435\u0440\u043D\u0443\u043B\u0430 \u0435\u0451 \u043A\u043B\u044E\u0447.");
|
|
2374
2461
|
return load(created);
|
|
2375
2462
|
},
|
|
2376
2463
|
update: async (value, patch) => {
|
|
2377
2464
|
const fields = fieldsOf(patch);
|
|
2378
|
-
if (Object.keys(fields).length > 0) await requestJson(`${api}/issue/${key(value)}`, { fetch, headers, method: "PUT", body: { fields }, missingIsIssue: true });
|
|
2379
|
-
if (patch.status !== void 0) await transition(api, key(value), patch.status, fetch, headers);
|
|
2465
|
+
if (Object.keys(fields).length > 0) await requestJson(`${api}/issue/${key(value)}`, { fetch, origin, headers, method: "PUT", body: { fields }, missingIsIssue: true });
|
|
2466
|
+
if (patch.status !== void 0) await transition(api, key(value), patch.status, { fetch, origin, headers });
|
|
2380
2467
|
return load(value);
|
|
2381
2468
|
},
|
|
2382
2469
|
comments: async (value, query) => {
|
|
2383
2470
|
assertCommentQuery("\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0438 Jira", ISSUE_CAPABILITIES2.comments, query);
|
|
2384
2471
|
const startAt = query.cursor === void 0 ? 0 : Number(query.cursor);
|
|
2385
2472
|
const params = new URLSearchParams({ startAt: String(Number.isInteger(startAt) && startAt >= 0 ? startAt : 0), maxResults: String(query.limit), orderBy: query.order === "desc" ? "-created" : "created" });
|
|
2386
|
-
const { body } = await requestJson(`${api}/issue/${key(value)}/comment?${params.toString()}`, { fetch, headers, missingIsIssue: true });
|
|
2473
|
+
const { body } = await requestJson(`${api}/issue/${key(value)}/comment?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });
|
|
2387
2474
|
const record = isRecord(body) ? body : {};
|
|
2388
2475
|
const raw = Array.isArray(record.comments) ? record.comments : [];
|
|
2389
2476
|
const items = raw.filter((item) => inTimeRange(toTimestamp(isRecord(item) ? item.updated : void 0), query.updatedAfter, void 0));
|
|
@@ -2391,7 +2478,7 @@ function createJiraAdapter({ connection, fetch }) {
|
|
|
2391
2478
|
const at = typeof record.startAt === "number" ? record.startAt : 0;
|
|
2392
2479
|
return { items: items.map(commentOf5), ...at + raw.length < total && raw.length > 0 ? { nextCursor: String(at + raw.length) } : {} };
|
|
2393
2480
|
},
|
|
2394
|
-
comment: async (value, body) => commentOf5((await requestJson(`${api}/issue/${key(value)}/comment`, { fetch, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
2481
|
+
comment: async (value, body) => commentOf5((await requestJson(`${api}/issue/${key(value)}/comment`, { fetch, origin, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
2395
2482
|
};
|
|
2396
2483
|
}
|
|
2397
2484
|
function listJql(project, query) {
|
|
@@ -2427,8 +2514,9 @@ function fieldsOf(patch) {
|
|
|
2427
2514
|
...patch.labels === void 0 ? {} : { labels: patch.labels.map((label) => label.replace(/\s+/g, "-")) }
|
|
2428
2515
|
};
|
|
2429
2516
|
}
|
|
2430
|
-
async function transition(api, key, category,
|
|
2431
|
-
const {
|
|
2517
|
+
async function transition(api, key, category, request) {
|
|
2518
|
+
const { fetch, origin, headers } = request;
|
|
2519
|
+
const { body } = await requestJson(`${api}/issue/${key}/transitions`, { fetch, origin, headers, missingIsIssue: true });
|
|
2432
2520
|
const list = isRecord(body) && Array.isArray(body.transitions) ? body.transitions : [];
|
|
2433
2521
|
const match = list.find((item) => {
|
|
2434
2522
|
if (!isRecord(item) || !isRecord(item.to) || !isRecord(item.to.statusCategory)) return false;
|
|
@@ -2436,7 +2524,7 @@ async function transition(api, key, category, fetch, headers) {
|
|
|
2436
2524
|
});
|
|
2437
2525
|
const id = isRecord(match) ? text(match.id) : void 0;
|
|
2438
2526
|
if (id === void 0) throw new TrackerError("invalid_request", `\u0418\u0437 \u0442\u0435\u043A\u0443\u0449\u0435\u0433\u043E \u0441\u0442\u0430\u0442\u0443\u0441\u0430 Jira \u043D\u0435\u0442 \u043F\u0435\u0440\u0435\u0445\u043E\u0434\u0430 \u0432 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044E ${category}.`);
|
|
2439
|
-
await requestJson(`${api}/issue/${key}/transitions`, { fetch, headers, method: "POST", body: { transition: { id } }, missingIsIssue: true });
|
|
2527
|
+
await requestJson(`${api}/issue/${key}/transitions`, { fetch, origin, headers, method: "POST", body: { transition: { id } }, missingIsIssue: true });
|
|
2440
2528
|
}
|
|
2441
2529
|
function issueOf3(raw, site) {
|
|
2442
2530
|
const item = isRecord(raw) ? raw : {};
|
|
@@ -2582,6 +2670,7 @@ function createPullAdapter({ connection, fetch }) {
|
|
|
2582
2670
|
const target = requireTarget(connection.target, "org/repo \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F SourceCraft");
|
|
2583
2671
|
if (!TARGET8.test(target)) throw new TrackerError("invalid_request", "target SourceCraft \u2014 org/repo.");
|
|
2584
2672
|
const api = baseUrl(connection.url, DEFAULT_API5);
|
|
2673
|
+
const origin = new URL(api).origin;
|
|
2585
2674
|
const root = `${api}/repos/${target}/pulls`;
|
|
2586
2675
|
const headers = { authorization: `Bearer ${connection.token ?? ""}` };
|
|
2587
2676
|
const missing = (key) => ({ failure: "not_found", message: `\u0412 SourceCraft \u043D\u0435\u0442 PR ${key}.` });
|
|
@@ -2589,7 +2678,7 @@ function createPullAdapter({ connection, fetch }) {
|
|
|
2589
2678
|
if (!SLUG.test(key)) throw new TrackerError("not_found", `\u0412 SourceCraft \u043D\u0435\u0442 PR ${key}.`);
|
|
2590
2679
|
return key;
|
|
2591
2680
|
};
|
|
2592
|
-
const getPull = async (key) => pullOf3((await requestJson(`${root}/${slug(key)}`, { fetch, headers, missing: missing(key) })).body);
|
|
2681
|
+
const getPull = async (key) => pullOf3((await requestJson(`${root}/${slug(key)}`, { fetch, origin, headers, missing: missing(key) })).body);
|
|
2593
2682
|
return {
|
|
2594
2683
|
list: async (query) => {
|
|
2595
2684
|
assertListQuery("PR SourceCraft", PULL_CAPABILITIES3.list, query, pullRequestFilterSchema.options);
|
|
@@ -2599,13 +2688,13 @@ function createPullAdapter({ connection, fetch }) {
|
|
|
2599
2688
|
const filter = pullFilterOf(query, status);
|
|
2600
2689
|
if (filter !== void 0) params.set("filter", filter);
|
|
2601
2690
|
if (query.sort !== void 0) params.set("sort_by", `${query.sort.direction === "asc" ? "" : "-"}${PULL_SORT_FIELDS_UPSTREAM[query.sort.field]}`);
|
|
2602
|
-
const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });
|
|
2691
|
+
const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });
|
|
2603
2692
|
const record = isRecord(body) ? body : {};
|
|
2604
2693
|
const pulls = (Array.isArray(record.pull_requests) ? record.pull_requests : []).map(pullOf3).filter((pull) => matchesPage2(pull, query));
|
|
2605
2694
|
return { items: pulls, ...nextOf2(record.next_page_token) };
|
|
2606
2695
|
},
|
|
2607
2696
|
get: (key) => getPull(key),
|
|
2608
|
-
create: async (input) => pullOf3((await requestJson(root, { fetch, headers, method: "POST", body: createBody2(input) })).body),
|
|
2697
|
+
create: async (input) => pullOf3((await requestJson(root, { fetch, origin, headers, method: "POST", body: createBody2(input) })).body),
|
|
2609
2698
|
update: async (key, patch) => {
|
|
2610
2699
|
const id = slug(key);
|
|
2611
2700
|
let updated;
|
|
@@ -2615,14 +2704,14 @@ function createPullAdapter({ connection, fetch }) {
|
|
|
2615
2704
|
...patch.description === void 0 ? {} : { description: patch.description },
|
|
2616
2705
|
...patch.target === void 0 ? {} : { target_branch: patch.target }
|
|
2617
2706
|
};
|
|
2618
|
-
updated = (await requestJson(`${root}/${id}`, { fetch, headers, method: "PATCH", body, missing: missing(key) })).body;
|
|
2707
|
+
updated = (await requestJson(`${root}/${id}`, { fetch, origin, headers, method: "PATCH", body, missing: missing(key) })).body;
|
|
2619
2708
|
}
|
|
2620
2709
|
if (patch.status !== void 0) {
|
|
2621
2710
|
const action = statusActionOf(patch.status, (await getPull(key)).status.category);
|
|
2622
|
-
if (action !== void 0) await requestJson(`${root}/${id}/${action}`, { fetch, headers, method: "POST", missing: missing(key) });
|
|
2711
|
+
if (action !== void 0) await requestJson(`${root}/${id}/${action}`, { fetch, origin, headers, method: "POST", missing: missing(key) });
|
|
2623
2712
|
return getPull(key);
|
|
2624
2713
|
}
|
|
2625
|
-
return pullOf3(updated ?? (await requestJson(`${root}/${id}`, { fetch, headers, missing: missing(key) })).body);
|
|
2714
|
+
return pullOf3(updated ?? (await requestJson(`${root}/${id}`, { fetch, origin, headers, missing: missing(key) })).body);
|
|
2626
2715
|
},
|
|
2627
2716
|
merge: async (key, input) => {
|
|
2628
2717
|
const id = slug(key);
|
|
@@ -2638,6 +2727,7 @@ function createPullAdapter({ connection, fetch }) {
|
|
|
2638
2727
|
}
|
|
2639
2728
|
const { body } = await requestJson(`${root}/${id}/merge`, {
|
|
2640
2729
|
fetch,
|
|
2730
|
+
origin,
|
|
2641
2731
|
headers,
|
|
2642
2732
|
method: "POST",
|
|
2643
2733
|
// squash/rebase по умолчанию наследуются из настройки репозитория — без method не шлём явно false.
|
|
@@ -2660,14 +2750,14 @@ function createPullAdapter({ connection, fetch }) {
|
|
|
2660
2750
|
const params = new URLSearchParams({ page_size: String(query.limit) });
|
|
2661
2751
|
if (query.cursor !== void 0) params.set("page_token", query.cursor);
|
|
2662
2752
|
if (query.order !== void 0) params.set("sort_by", query.order === "asc" ? "created_at" : "-created_at");
|
|
2663
|
-
const { body } = await requestJson(`${root}/${id}/comments?${params.toString()}`, { fetch, headers, missing: missing(key) });
|
|
2753
|
+
const { body } = await requestJson(`${root}/${id}/comments?${params.toString()}`, { fetch, origin, headers, missing: missing(key) });
|
|
2664
2754
|
const record = isRecord(body) ? body : {};
|
|
2665
2755
|
const rawComments = Array.isArray(record.pull_request_comments) ? record.pull_request_comments : [];
|
|
2666
2756
|
const visible = rawComments.filter((raw) => !(isRecord(raw) && raw.is_deleted === true));
|
|
2667
2757
|
const filtered = query.updatedAfter === void 0 ? visible : visible.filter((raw) => inTimeRange(toTimestamp(isRecord(raw) ? raw.updated_at : void 0), query.updatedAfter, void 0));
|
|
2668
2758
|
return { items: filtered.map(commentOf6), ...nextOf2(record.next_page_token) };
|
|
2669
2759
|
},
|
|
2670
|
-
comment: async (key, body) => commentOf6((await requestJson(`${root}/${slug(key)}/comments`, { fetch, headers, method: "POST", body: { body }, missing: missing(key) })).body)
|
|
2760
|
+
comment: async (key, body) => commentOf6((await requestJson(`${root}/${slug(key)}/comments`, { fetch, origin, headers, method: "POST", body: { body }, missing: missing(key) })).body)
|
|
2671
2761
|
};
|
|
2672
2762
|
}
|
|
2673
2763
|
function createBody2(input) {
|
|
@@ -2780,6 +2870,7 @@ function sourcecraftTracker() {
|
|
|
2780
2870
|
},
|
|
2781
2871
|
issues: ISSUE_CAPABILITIES4,
|
|
2782
2872
|
create: (context) => createSourceCraftAdapter(context),
|
|
2873
|
+
origin: (connection) => new URL(baseUrl(connection.url, DEFAULT_API6)).origin,
|
|
2783
2874
|
pulls: sourcecraftPulls(),
|
|
2784
2875
|
ci: sourcecraftCi()
|
|
2785
2876
|
};
|
|
@@ -2788,6 +2879,7 @@ function createSourceCraftAdapter({ connection, fetch }) {
|
|
|
2788
2879
|
const target = requireTarget(connection.target, "org/repo \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F SourceCraft");
|
|
2789
2880
|
if (!TARGET9.test(target)) throw new TrackerError("invalid_request", "target SourceCraft \u2014 org/repo.");
|
|
2790
2881
|
const api = baseUrl(connection.url, DEFAULT_API6);
|
|
2882
|
+
const origin = new URL(api).origin;
|
|
2791
2883
|
const root = `${api}/repos/${target}/issues`;
|
|
2792
2884
|
const headers = { authorization: `Bearer ${connection.token ?? ""}` };
|
|
2793
2885
|
const web = connection.url === void 0 ? `${DEFAULT_WEB}/${target}/issues` : void 0;
|
|
@@ -2804,31 +2896,31 @@ function createSourceCraftAdapter({ connection, fetch }) {
|
|
|
2804
2896
|
const filter = issueFilterOf(query);
|
|
2805
2897
|
if (filter !== void 0) params.set("filter", filter);
|
|
2806
2898
|
if (query.sort !== void 0) params.set("sort_by", `${query.sort.direction === "asc" ? "" : "-"}${issueSortFieldOf(query.sort.field)}`);
|
|
2807
|
-
const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, headers });
|
|
2899
|
+
const { body } = await requestJson(`${root}?${params.toString()}`, { fetch, origin, headers });
|
|
2808
2900
|
const record = isRecord(body) ? body : {};
|
|
2809
2901
|
let issues = (Array.isArray(record.issues) ? record.issues : []).map(toIssue2);
|
|
2810
2902
|
if (query.status !== void 0) issues = issues.filter((issue) => query.status?.includes(issue.status.category) === true);
|
|
2811
2903
|
if (query.assignee === null) issues = issues.filter((issue) => issue.assignee === void 0);
|
|
2812
2904
|
return { items: issues, ...nextOf3(record.next_page_token) };
|
|
2813
2905
|
},
|
|
2814
|
-
get: async (key) => toIssue2((await requestJson(`${root}/${slug(key)}`, { fetch, headers, missingIsIssue: true })).body),
|
|
2906
|
+
get: async (key) => toIssue2((await requestJson(`${root}/${slug(key)}`, { fetch, origin, headers, missingIsIssue: true })).body),
|
|
2815
2907
|
create: async (input) => {
|
|
2816
2908
|
const body = { title: input.title, ...input.description === void 0 ? {} : { description: input.description }, ...input.priority === void 0 ? {} : { priority: input.priority } };
|
|
2817
|
-
return toIssue2((await requestJson(root, { fetch, headers, method: "POST", body })).body);
|
|
2909
|
+
return toIssue2((await requestJson(root, { fetch, origin, headers, method: "POST", body })).body);
|
|
2818
2910
|
},
|
|
2819
|
-
update: async (key, patch) => toIssue2((await requestJson(`${root}/${slug(key)}`, { fetch, headers, method: "PATCH", body: patchBody5(patch), missingIsIssue: true })).body),
|
|
2911
|
+
update: async (key, patch) => toIssue2((await requestJson(`${root}/${slug(key)}`, { fetch, origin, headers, method: "PATCH", body: patchBody5(patch), missingIsIssue: true })).body),
|
|
2820
2912
|
comments: async (key, query) => {
|
|
2821
2913
|
assertCommentQuery("\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0438 SourceCraft", ISSUE_CAPABILITIES4.comments, query);
|
|
2822
2914
|
const params = new URLSearchParams({ page_size: String(query.limit) });
|
|
2823
2915
|
if (query.cursor !== void 0) params.set("page_token", query.cursor);
|
|
2824
2916
|
if (query.order !== void 0) params.set("sort_by", query.order === "asc" ? "created_at" : "-created_at");
|
|
2825
|
-
const { body } = await requestJson(`${root}/${slug(key)}/comments?${params.toString()}`, { fetch, headers, missingIsIssue: true });
|
|
2917
|
+
const { body } = await requestJson(`${root}/${slug(key)}/comments?${params.toString()}`, { fetch, origin, headers, missingIsIssue: true });
|
|
2826
2918
|
const record = isRecord(body) ? body : {};
|
|
2827
2919
|
const rawComments = Array.isArray(record.issue_comments) ? record.issue_comments : [];
|
|
2828
2920
|
const filtered = query.updatedAfter === void 0 ? rawComments : rawComments.filter((raw) => inTimeRange(toTimestamp(isRecord(raw) ? raw.updated_at : void 0), query.updatedAfter, void 0));
|
|
2829
2921
|
return { items: filtered.map(commentOf7), ...nextOf3(record.next_page_token) };
|
|
2830
2922
|
},
|
|
2831
|
-
comment: async (key, body) => commentOf7((await requestJson(`${root}/${slug(key)}/comments`, { fetch, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
2923
|
+
comment: async (key, body) => commentOf7((await requestJson(`${root}/${slug(key)}/comments`, { fetch, origin, headers, method: "POST", body: { body }, missingIsIssue: true })).body)
|
|
2832
2924
|
};
|
|
2833
2925
|
}
|
|
2834
2926
|
function patchBody5(patch) {
|
|
@@ -2996,6 +3088,7 @@ export {
|
|
|
2996
3088
|
TRACKER_ERROR_BODY_MAX,
|
|
2997
3089
|
TRACKER_LOCAL_AUTHOR,
|
|
2998
3090
|
TRACKER_PAGE_LIMIT_DEFAULT,
|
|
3091
|
+
TRACKER_REDIRECT_MAX,
|
|
2999
3092
|
TRACKER_SECRETS_FILE,
|
|
3000
3093
|
TRACKER_TIMEOUT_MS,
|
|
3001
3094
|
TrackerError,
|