pipe-kan 0.20.2 → 0.20.4

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 CHANGED
@@ -261,6 +261,10 @@ function flagsToJql(flags) {
261
261
  function emptyList(text) {
262
262
  return /no result found/i.test(text);
263
263
  }
264
+ function rateLimited(text) {
265
+ return /\b429\b/.test(text);
266
+ }
267
+ var RETRY_LIMIT = 4;
264
268
  var LIST_PAGE = 100;
265
269
  function issueKey(issue) {
266
270
  if (!issue || typeof issue !== "object" || !("key" in issue))
@@ -319,6 +323,7 @@ function resolveJiraBin(bin = process.env.JIRA_BIN ?? "jira", pathVar = process.
319
323
  }
320
324
  function createJiraCli(opts = {}) {
321
325
  const bin = opts.bin ?? "jira";
326
+ const retryDelayMs = opts.retryDelayMs ?? 1000;
322
327
  function run(args) {
323
328
  return new Promise((resolveRun, reject) => {
324
329
  const env = { ...process.env };
@@ -339,8 +344,20 @@ function createJiraCli(opts = {}) {
339
344
  child.on("close", (code) => resolveRun({ code: code ?? 1, stdout, stderr }));
340
345
  });
341
346
  }
347
+ async function runRetry(args) {
348
+ let result = await run(args);
349
+ for (let attempt = 0;attempt < RETRY_LIMIT; attempt++) {
350
+ if (result.code === 0 || !rateLimited(result.stderr || result.stdout))
351
+ return result;
352
+ if (retryDelayMs) {
353
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs * 2 ** attempt));
354
+ }
355
+ result = await run(args);
356
+ }
357
+ return result;
358
+ }
342
359
  async function listOnce(args) {
343
- const result = await run(args);
360
+ const result = await runRetry(args);
344
361
  if (result.code !== 0) {
345
362
  const text = result.stderr || result.stdout || "jira issue list failed";
346
363
  if (emptyList(text))
@@ -382,7 +399,7 @@ function createJiraCli(opts = {}) {
382
399
  return {
383
400
  async list(flags) {
384
401
  const extra = (flags || DEFAULT_FLAGS).split(/\s+/).filter(Boolean);
385
- return listAll(["issue", "list", ...extra]);
402
+ return JSON.stringify(await listOnce(["issue", "list", ...extra, "--raw"]));
386
403
  },
387
404
  async listEpics() {
388
405
  return listAll(["issue", "list", "-tEpic"]);
@@ -407,7 +424,7 @@ function createJiraCli(opts = {}) {
407
424
  ]);
408
425
  },
409
426
  async move(key, status) {
410
- const result = await run(["issue", "move", key, status]);
427
+ const result = await runRetry(["issue", "move", key, status]);
411
428
  if (result.code !== 0) {
412
429
  return {
413
430
  ok: false,
@@ -417,12 +434,12 @@ function createJiraCli(opts = {}) {
417
434
  return { ok: true };
418
435
  },
419
436
  async open(key) {
420
- const result = await run(["open", key, "--no-browser"]);
437
+ const result = await runRetry(["open", key, "--no-browser"]);
421
438
  return result.stdout.trim().split(`
422
439
  `).pop() ?? `/browse/${key}`;
423
440
  },
424
441
  async view(key) {
425
- const result = await run(["issue", "view", key, "--raw"]);
442
+ const result = await runRetry(["issue", "view", key, "--raw"]);
426
443
  if (result.code !== 0) {
427
444
  throw new Error((result.stderr || result.stdout || "jira issue view failed").trim());
428
445
  }
@@ -656,7 +673,11 @@ function createApp(opts) {
656
673
  nextChildren = JSON.parse(await cli.listChildren(keys));
657
674
  const cards = cardsOf(nextChildren);
658
675
  if (cards.length > 0 && !cards.some((card) => card.epic)) {
659
- nextChildren = (await Promise.all(keys.map(async (key) => stampRawParent(JSON.parse(await cli.listEpic(key)), key)))).flat();
676
+ const stamped = [];
677
+ for (const key of keys) {
678
+ stamped.push(...stampRawParent(JSON.parse(await cli.listEpic(key)), key));
679
+ }
680
+ nextChildren = stamped;
660
681
  }
661
682
  nextHasCache = true;
662
683
  } catch (err) {