ripencli 1.0.0 → 1.0.1
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/cli.js +127 -34
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -141,8 +141,10 @@ async function fetchChangelog(packageName, fromVersion, toVersion) {
|
|
|
141
141
|
const ghRes = await fetch(`https://api.github.com/repos/${repo}/releases?per_page=30`, { headers: { Accept: "application/vnd.github+json" } });
|
|
142
142
|
if (!ghRes.ok) return [];
|
|
143
143
|
const releases = await ghRes.json();
|
|
144
|
+
const toMajor = parseVersion(toVersion)[0];
|
|
144
145
|
const filtered = releases.filter((r) => {
|
|
145
146
|
if (r.draft || r.prerelease) return false;
|
|
147
|
+
if (fromVersion === "") return parseVersion(r.tag_name)[0] === toMajor && compareVersions(r.tag_name, toVersion) <= 0;
|
|
146
148
|
return compareVersions(r.tag_name, fromVersion) > 0 && compareVersions(r.tag_name, toVersion) <= 0;
|
|
147
149
|
}).map((r) => ({
|
|
148
150
|
version: r.tag_name,
|
|
@@ -157,7 +159,7 @@ async function fetchChangelog(packageName, fromVersion, toVersion) {
|
|
|
157
159
|
url: latest.html_url
|
|
158
160
|
}];
|
|
159
161
|
}
|
|
160
|
-
return filtered;
|
|
162
|
+
return filtered.sort((a, b) => compareVersions(a.version, b.version));
|
|
161
163
|
} catch {
|
|
162
164
|
return [];
|
|
163
165
|
}
|
|
@@ -1432,9 +1434,13 @@ function openInBrowser(url) {
|
|
|
1432
1434
|
}
|
|
1433
1435
|
//#endregion
|
|
1434
1436
|
//#region src/ui/MarkdownLine.tsx
|
|
1435
|
-
|
|
1437
|
+
/** Wrap text in an OSC 8 hyperlink so modern terminals make it clickable. */
|
|
1438
|
+
function osc8(text, url) {
|
|
1439
|
+
return `\x1b]8;;${url}\x07${text}\x1b]8;;\x07`;
|
|
1440
|
+
}
|
|
1441
|
+
function parseInline(raw, repoUrl) {
|
|
1436
1442
|
const segments = [];
|
|
1437
|
-
const re = /(\*\*(.+?)
|
|
1443
|
+
const re = /(\*\*(.+?)\*\*|\*([^*\n]+)\*|~~([^~\n]+)~~|`([^`]+)`|\[([^\]]*)\]\(([^)]+)\)|<(?:strong|b)>(.+?)<\/(?:strong|b)>|<(?:em|i)>(.+?)<\/(?:em|i)>|<(?:del|s)>(.+?)<\/(?:del|s)>|<(?:code|samp|kbd)>(.+?)<\/(?:code|samp|kbd)>|(?<![/\w&#])#(\d+)|(?<!\w)@([a-zA-Z0-9][a-zA-Z0-9-]*)|(https?:\/\/[^\s)>\]]+))/g;
|
|
1438
1444
|
let last = 0;
|
|
1439
1445
|
let m;
|
|
1440
1446
|
while ((m = re.exec(raw)) !== null) {
|
|
@@ -1445,30 +1451,123 @@ function parseInline(raw) {
|
|
|
1445
1451
|
});
|
|
1446
1452
|
else if (m[3] !== void 0) segments.push({
|
|
1447
1453
|
text: m[3],
|
|
1454
|
+
italic: true
|
|
1455
|
+
});
|
|
1456
|
+
else if (m[4] !== void 0) segments.push({
|
|
1457
|
+
text: m[4],
|
|
1458
|
+
strikethrough: true
|
|
1459
|
+
});
|
|
1460
|
+
else if (m[5] !== void 0) segments.push({
|
|
1461
|
+
text: m[5],
|
|
1448
1462
|
code: true
|
|
1449
1463
|
});
|
|
1450
|
-
else if (m[
|
|
1451
|
-
|
|
1464
|
+
else if (m[6] !== void 0) {
|
|
1465
|
+
const linkText = m[6].trim() || m[7];
|
|
1452
1466
|
segments.push({
|
|
1453
|
-
text:
|
|
1454
|
-
|
|
1467
|
+
text: linkText,
|
|
1468
|
+
link: m[7]
|
|
1455
1469
|
});
|
|
1456
|
-
}
|
|
1470
|
+
} else if (m[8] !== void 0) segments.push({
|
|
1471
|
+
text: m[8],
|
|
1472
|
+
bold: true
|
|
1473
|
+
});
|
|
1474
|
+
else if (m[9] !== void 0) segments.push({
|
|
1475
|
+
text: m[9],
|
|
1476
|
+
italic: true
|
|
1477
|
+
});
|
|
1478
|
+
else if (m[10] !== void 0) segments.push({
|
|
1479
|
+
text: m[10],
|
|
1480
|
+
strikethrough: true
|
|
1481
|
+
});
|
|
1482
|
+
else if (m[11] !== void 0) segments.push({
|
|
1483
|
+
text: m[11],
|
|
1484
|
+
code: true
|
|
1485
|
+
});
|
|
1486
|
+
else if (m[12] !== void 0) {
|
|
1487
|
+
const num = m[12];
|
|
1488
|
+
const url = repoUrl ? `${repoUrl}/issues/${num}` : void 0;
|
|
1489
|
+
segments.push(url ? {
|
|
1490
|
+
text: `#${num}`,
|
|
1491
|
+
link: url
|
|
1492
|
+
} : {
|
|
1493
|
+
text: `#${num}`,
|
|
1494
|
+
code: true
|
|
1495
|
+
});
|
|
1496
|
+
} else if (m[13] !== void 0) {
|
|
1497
|
+
const user = m[13];
|
|
1498
|
+
segments.push({
|
|
1499
|
+
text: `@${user}`,
|
|
1500
|
+
link: `https://github.com/${user}`
|
|
1501
|
+
});
|
|
1502
|
+
} else if (m[14] !== void 0) segments.push({
|
|
1503
|
+
text: m[14],
|
|
1504
|
+
link: m[14]
|
|
1505
|
+
});
|
|
1457
1506
|
last = m.index + m[0].length;
|
|
1458
1507
|
}
|
|
1459
1508
|
if (last < raw.length) segments.push({ text: raw.slice(last) });
|
|
1460
1509
|
return segments;
|
|
1461
1510
|
}
|
|
1462
|
-
function
|
|
1463
|
-
|
|
1464
|
-
|
|
1511
|
+
function Segment({ s, baseColor }) {
|
|
1512
|
+
if (s.link) return /* @__PURE__ */ jsx(Text, {
|
|
1513
|
+
color: "blueBright",
|
|
1514
|
+
underline: true,
|
|
1515
|
+
children: osc8(s.text, s.link)
|
|
1516
|
+
});
|
|
1517
|
+
if (s.code) return /* @__PURE__ */ jsx(Text, {
|
|
1518
|
+
color: "cyan",
|
|
1519
|
+
children: s.text
|
|
1520
|
+
});
|
|
1521
|
+
if (s.bold) return /* @__PURE__ */ jsx(Text, {
|
|
1522
|
+
bold: true,
|
|
1523
|
+
color: baseColor,
|
|
1524
|
+
children: s.text
|
|
1525
|
+
});
|
|
1526
|
+
if (s.italic) return /* @__PURE__ */ jsx(Text, {
|
|
1527
|
+
italic: true,
|
|
1528
|
+
color: baseColor,
|
|
1529
|
+
children: s.text
|
|
1530
|
+
});
|
|
1531
|
+
if (s.strikethrough) return /* @__PURE__ */ jsx(Text, {
|
|
1532
|
+
strikethrough: true,
|
|
1533
|
+
color: "gray",
|
|
1534
|
+
children: s.text
|
|
1535
|
+
});
|
|
1536
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
1537
|
+
color: baseColor,
|
|
1538
|
+
children: s.text
|
|
1539
|
+
});
|
|
1540
|
+
}
|
|
1541
|
+
const HTML_ENTITIES = {
|
|
1542
|
+
" ": " ",
|
|
1543
|
+
"&": "&",
|
|
1544
|
+
"<": "<",
|
|
1545
|
+
">": ">",
|
|
1546
|
+
""": "\"",
|
|
1547
|
+
"'": "'",
|
|
1548
|
+
"—": "—",
|
|
1549
|
+
"–": "–",
|
|
1550
|
+
"…": "…",
|
|
1551
|
+
"«": "«",
|
|
1552
|
+
"»": "»"
|
|
1553
|
+
};
|
|
1554
|
+
function decodeEntities(s) {
|
|
1555
|
+
return s.replace(/&[a-z]+;/g, (e) => HTML_ENTITIES[e] ?? e).replace(/&#(\d+);/g, (_, n) => String.fromCodePoint(Number(n))).replace(/&#x([0-9a-f]+);/gi, (_, h) => String.fromCodePoint(parseInt(h, 16)));
|
|
1556
|
+
}
|
|
1557
|
+
function MarkdownLine({ line, baseColor = "white", repoUrl }) {
|
|
1558
|
+
const raw = decodeEntities(line);
|
|
1559
|
+
const headingMatch = raw.match(/^(#{1,6})\s+(.*)/);
|
|
1465
1560
|
if (headingMatch) {
|
|
1466
1561
|
const level = headingMatch[1].length;
|
|
1467
1562
|
const text = headingMatch[2];
|
|
1563
|
+
const color = level === 1 ? "whiteBright" : level === 2 ? "cyanBright" : level === 3 ? "cyan" : "gray";
|
|
1468
1564
|
return /* @__PURE__ */ jsxs(Text, {
|
|
1469
|
-
bold:
|
|
1470
|
-
color
|
|
1471
|
-
children: [" ", text
|
|
1565
|
+
bold: level <= 3,
|
|
1566
|
+
color,
|
|
1567
|
+
children: [" " + " ".repeat(Math.max(0, level - 3)), parseInline(text, repoUrl).map((s, i) => /* @__PURE__ */ jsx(Segment, {
|
|
1568
|
+
s,
|
|
1569
|
+
baseColor: color
|
|
1570
|
+
}, i))]
|
|
1472
1571
|
});
|
|
1473
1572
|
}
|
|
1474
1573
|
if (raw.startsWith("> ")) return /* @__PURE__ */ jsxs(Text, {
|
|
@@ -1479,11 +1578,10 @@ function MarkdownLine({ line, baseColor = "white", baseDim = false }) {
|
|
|
1479
1578
|
if (listMatch) {
|
|
1480
1579
|
const indent = listMatch[1].match(/^\s*/)?.[0].length ?? 0;
|
|
1481
1580
|
const content = listMatch[2];
|
|
1482
|
-
const segments = parseInline(content);
|
|
1483
|
-
return /* @__PURE__ */ jsxs(Text, { children: [" " + " ".repeat(indent) + "• ", segments.map((s, i) => /* @__PURE__ */ jsx(
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
children: s.text
|
|
1581
|
+
const segments = parseInline(content, repoUrl);
|
|
1582
|
+
return /* @__PURE__ */ jsxs(Text, { children: [" " + " ".repeat(indent) + "• ", segments.map((s, i) => /* @__PURE__ */ jsx(Segment, {
|
|
1583
|
+
s,
|
|
1584
|
+
baseColor
|
|
1487
1585
|
}, i))] });
|
|
1488
1586
|
}
|
|
1489
1587
|
if (/^[-*_]{3,}$/.test(raw.trim())) return /* @__PURE__ */ jsx(Text, {
|
|
@@ -1491,10 +1589,9 @@ function MarkdownLine({ line, baseColor = "white", baseDim = false }) {
|
|
|
1491
1589
|
children: " ────────────────────"
|
|
1492
1590
|
});
|
|
1493
1591
|
if (!raw.trim()) return /* @__PURE__ */ jsx(Text, { children: " " });
|
|
1494
|
-
return /* @__PURE__ */ jsxs(Text, { children: [" ", parseInline(raw).map((s, i) => /* @__PURE__ */ jsx(
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
children: s.text
|
|
1592
|
+
return /* @__PURE__ */ jsxs(Text, { children: [" ", parseInline(raw, repoUrl).map((s, i) => /* @__PURE__ */ jsx(Segment, {
|
|
1593
|
+
s,
|
|
1594
|
+
baseColor
|
|
1498
1595
|
}, i))] });
|
|
1499
1596
|
}
|
|
1500
1597
|
//#endregion
|
|
@@ -1507,10 +1604,11 @@ function ChangelogPanel({ pkg, onClose }) {
|
|
|
1507
1604
|
const [activeEntry, setActiveEntry] = useState(0);
|
|
1508
1605
|
const scrollRef = useRef(null);
|
|
1509
1606
|
const { stdout } = useStdout();
|
|
1607
|
+
const isUpToDate = pkg.current === (pkg.targetVersion ?? pkg.latest);
|
|
1510
1608
|
useEffect(() => {
|
|
1511
|
-
Promise.all([fetchChangelog(pkg.name, pkg.current, pkg.targetVersion ?? pkg.latest), fetchRepoUrl(pkg.name)]).then(([e, repo]) => {
|
|
1609
|
+
Promise.all([fetchChangelog(pkg.name, isUpToDate ? "" : pkg.current, pkg.targetVersion ?? pkg.latest), fetchRepoUrl(pkg.name)]).then(([e, repo]) => {
|
|
1512
1610
|
setEntries(e);
|
|
1513
|
-
setActiveEntry(0);
|
|
1611
|
+
setActiveEntry(isUpToDate ? Math.max(0, e.length - 1) : 0);
|
|
1514
1612
|
setRepoUrl(repo);
|
|
1515
1613
|
setLoading(false);
|
|
1516
1614
|
});
|
|
@@ -1597,14 +1695,6 @@ function ChangelogPanel({ pkg, onClose }) {
|
|
|
1597
1695
|
})
|
|
1598
1696
|
]
|
|
1599
1697
|
}),
|
|
1600
|
-
repoUrl && /* @__PURE__ */ jsxs(Text, {
|
|
1601
|
-
color: "gray",
|
|
1602
|
-
children: [
|
|
1603
|
-
" ",
|
|
1604
|
-
repoUrl,
|
|
1605
|
-
"/releases"
|
|
1606
|
-
]
|
|
1607
|
-
}),
|
|
1608
1698
|
/* @__PURE__ */ jsx(Text, {
|
|
1609
1699
|
color: "gray",
|
|
1610
1700
|
children: "────────────────────────────────────────────────────"
|
|
@@ -1674,7 +1764,10 @@ function ChangelogPanel({ pkg, onClose }) {
|
|
|
1674
1764
|
ref: scrollRef,
|
|
1675
1765
|
children: /* @__PURE__ */ jsx(Box, {
|
|
1676
1766
|
flexDirection: "column",
|
|
1677
|
-
children: currentEntry.body.split("\n").map((line, j) => /* @__PURE__ */ jsx(MarkdownLine, {
|
|
1767
|
+
children: currentEntry.body.split("\n").map((line, j) => /* @__PURE__ */ jsx(MarkdownLine, {
|
|
1768
|
+
line,
|
|
1769
|
+
repoUrl
|
|
1770
|
+
}, j))
|
|
1678
1771
|
})
|
|
1679
1772
|
})
|
|
1680
1773
|
}) : null,
|