pipe-kan 0.13.0 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pipe-kan.js +67 -27
- package/package.json +1 -1
package/dist/pipe-kan.js
CHANGED
|
@@ -27,15 +27,27 @@ function issueType(fields) {
|
|
|
27
27
|
const name = fields?.issuetype?.name ?? fields?.issueType?.name;
|
|
28
28
|
return typeof name === "string" ? name : undefined;
|
|
29
29
|
}
|
|
30
|
+
function asIssueKey(value) {
|
|
31
|
+
if (typeof value === "string") {
|
|
32
|
+
const key = value.trim();
|
|
33
|
+
return /^[A-Za-z][A-Za-z0-9_]*-\d+$/.test(key) ? key : undefined;
|
|
34
|
+
}
|
|
35
|
+
if (value && typeof value === "object" && "key" in value) {
|
|
36
|
+
return asIssueKey(value.key);
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
30
40
|
function epicKey(fields) {
|
|
31
|
-
if (
|
|
32
|
-
return
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
if (!fields)
|
|
42
|
+
return;
|
|
43
|
+
const named = asIssueKey(fields.parent) ?? asIssueKey(fields.parentEpic) ?? asIssueKey(fields["Epic Link"]);
|
|
44
|
+
if (named)
|
|
45
|
+
return named;
|
|
46
|
+
for (const [name, value] of Object.entries(fields)) {
|
|
47
|
+
if (!name.startsWith("customfield_"))
|
|
48
|
+
continue;
|
|
49
|
+
const key = asIssueKey(value);
|
|
50
|
+
if (key)
|
|
39
51
|
return key;
|
|
40
52
|
}
|
|
41
53
|
return;
|
|
@@ -345,7 +357,7 @@ function createJiraCli(opts = {}) {
|
|
|
345
357
|
"issue",
|
|
346
358
|
"list",
|
|
347
359
|
"-q",
|
|
348
|
-
`parent="${key}" OR "Epic Link"="${key}"`,
|
|
360
|
+
`(parent="${key}" OR "Epic Link"="${key}")`,
|
|
349
361
|
"--raw"
|
|
350
362
|
]);
|
|
351
363
|
if (result.code !== 0) {
|
|
@@ -364,7 +376,7 @@ function createJiraCli(opts = {}) {
|
|
|
364
376
|
"issue",
|
|
365
377
|
"list",
|
|
366
378
|
"-q",
|
|
367
|
-
`parent in (${list}) OR "Epic Link" in (${list})`,
|
|
379
|
+
`(parent in (${list}) OR "Epic Link" in (${list}))`,
|
|
368
380
|
"--raw"
|
|
369
381
|
]);
|
|
370
382
|
if (result.code !== 0) {
|
|
@@ -550,6 +562,24 @@ function stampMissingEpic(board, epic) {
|
|
|
550
562
|
}
|
|
551
563
|
return board;
|
|
552
564
|
}
|
|
565
|
+
function stampRawParent(raw, epic) {
|
|
566
|
+
if (!Array.isArray(raw))
|
|
567
|
+
return [];
|
|
568
|
+
return raw.map((issue) => {
|
|
569
|
+
if (!issue || typeof issue !== "object")
|
|
570
|
+
return issue;
|
|
571
|
+
const current = issue;
|
|
572
|
+
const fields = current.fields;
|
|
573
|
+
if (!fields || typeof fields !== "object" || fields.parent)
|
|
574
|
+
return issue;
|
|
575
|
+
return { ...current, fields: { ...fields, parent: { key: epic } } };
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
function cardsOf(raw) {
|
|
579
|
+
if (!Array.isArray(raw))
|
|
580
|
+
return [];
|
|
581
|
+
return issuesToBoard(raw).columns.flatMap((column) => column.cards);
|
|
582
|
+
}
|
|
553
583
|
function createApp(opts) {
|
|
554
584
|
const cli = opts.cli ?? createStoreCli(opts.store);
|
|
555
585
|
let flags = DEFAULT_FLAGS;
|
|
@@ -593,22 +623,33 @@ function createApp(opts) {
|
|
|
593
623
|
async refresh(next) {
|
|
594
624
|
if (next !== undefined)
|
|
595
625
|
flags = next;
|
|
596
|
-
childrenError = undefined;
|
|
597
626
|
const [issues, epics] = await Promise.all([
|
|
598
627
|
cli.list(flags),
|
|
599
628
|
cli.listEpics()
|
|
600
629
|
]);
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
const keys =
|
|
630
|
+
const nextPayload = JSON.parse(issues);
|
|
631
|
+
const nextEpics = JSON.parse(epics);
|
|
632
|
+
const keys = issuesToBoard(nextEpics).epics.map((epic) => epic.key);
|
|
633
|
+
let nextChildren = [];
|
|
634
|
+
let nextHasCache = false;
|
|
635
|
+
let nextError;
|
|
604
636
|
try {
|
|
605
|
-
|
|
606
|
-
|
|
637
|
+
nextChildren = JSON.parse(await cli.listChildren(keys));
|
|
638
|
+
const cards = cardsOf(nextChildren);
|
|
639
|
+
if (cards.length > 0 && !cards.some((card) => card.epic)) {
|
|
640
|
+
nextChildren = (await Promise.all(keys.map(async (key) => stampRawParent(JSON.parse(await cli.listEpic(key)), key)))).flat();
|
|
641
|
+
}
|
|
642
|
+
nextHasCache = true;
|
|
607
643
|
} catch (err) {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
644
|
+
nextHasCache = false;
|
|
645
|
+
nextChildren = [];
|
|
646
|
+
nextError = err instanceof Error ? err.message : "Epic children list failed";
|
|
611
647
|
}
|
|
648
|
+
payload = nextPayload;
|
|
649
|
+
epicsPayload = nextEpics;
|
|
650
|
+
childrenRaw = nextChildren;
|
|
651
|
+
hasChildrenCache = nextHasCache;
|
|
652
|
+
childrenError = nextError;
|
|
612
653
|
return app.board();
|
|
613
654
|
},
|
|
614
655
|
async children(epic) {
|
|
@@ -620,10 +661,9 @@ function createApp(opts) {
|
|
|
620
661
|
epic: card.epic ?? epic
|
|
621
662
|
}))
|
|
622
663
|
]));
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
epics: []
|
|
626
|
-
};
|
|
664
|
+
const columns = Object.entries(cards).filter(([, list]) => list.length).map(([title, list]) => ({ id: title, title, cards: list }));
|
|
665
|
+
if (columns.length)
|
|
666
|
+
return { columns, epics: [] };
|
|
627
667
|
}
|
|
628
668
|
return stampMissingEpic(issuesToBoard(JSON.parse(await cli.listEpic(epic))), epic);
|
|
629
669
|
},
|
|
@@ -1070,6 +1110,10 @@ async function runServer(opts) {
|
|
|
1070
1110
|
await new Promise((resolve) => server.listen(port, host, resolve));
|
|
1071
1111
|
const origin = `http://127.0.0.1:${port}`;
|
|
1072
1112
|
const fakeConfig = writeJiraConfig(join4(tmpdir(), "pipe-kan"), origin);
|
|
1113
|
+
console.log(`pipe-kan http://${host}:${port}`);
|
|
1114
|
+
console.log(`cli ${kind === "jira" ? resolveJiraBin() : "store"}`);
|
|
1115
|
+
console.log(`Fake Jira ${origin}/rest/api/2/search`);
|
|
1116
|
+
console.log(`Fake Jira config ${fakeConfig}`);
|
|
1073
1117
|
if (kind === "jira") {
|
|
1074
1118
|
try {
|
|
1075
1119
|
await refreshFromJira(app, kind, { piped: Boolean(piped) });
|
|
@@ -1078,10 +1122,6 @@ async function runServer(opts) {
|
|
|
1078
1122
|
console.error(err);
|
|
1079
1123
|
}
|
|
1080
1124
|
}
|
|
1081
|
-
console.log(`pipe-kan http://${host}:${port}`);
|
|
1082
|
-
console.log(`cli ${kind === "jira" ? resolveJiraBin() : "store"}`);
|
|
1083
|
-
console.log(`Fake Jira ${origin}/rest/api/2/search`);
|
|
1084
|
-
console.log(`Fake Jira config ${fakeConfig}`);
|
|
1085
1125
|
}
|
|
1086
1126
|
|
|
1087
1127
|
// src/bin.ts
|