@flyingboat/upup 0.2.1 → 0.4.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.
Files changed (3) hide show
  1. package/README.md +4 -4
  2. package/dist/bundle.js +134 -47
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -23,8 +23,8 @@ Run in the current project:
23
23
  upup
24
24
  ```
25
25
 
26
- for CICD
26
+ ## Flags
27
27
 
28
- ```
29
- upup --ci
30
- ```
28
+ - `--ci`: Run in CI mode, disabling animations
29
+ - `--compact`: Render the result in a compact format
30
+ - `--export-to-file`: Export the result to a file instead of printing it to stdout
package/dist/bundle.js CHANGED
@@ -59,6 +59,34 @@ const green = (t) => wrap(t, codes.green);
59
59
  const yellow = (t) => wrap(t, codes.yellow);
60
60
  const gray = (t) => wrap(t, codes.gray);
61
61
  const bold = (t) => wrap(t, codes.bold);
62
+ function clearColor(t) {
63
+ return t.replace(/\x1b\[[0-9;]*m/g, "");
64
+ }
65
+
66
+ //#endregion
67
+ //#region src/cli-compact.ts
68
+ function renderCompact(rows, ctx) {
69
+ ctx.console.log(compact(rows).join("\n"));
70
+ }
71
+ function compact(rows) {
72
+ const content = [];
73
+ for (const row of rows) {
74
+ content.push(...block(row));
75
+ content.push("");
76
+ }
77
+ return content;
78
+ }
79
+ function block(row) {
80
+ const content = [];
81
+ let status = row.status;
82
+ if (status === "need update") status = yellow(status);
83
+ else if (status === "ok") status = green(status);
84
+ content.push(`[${bold(row.package)}]`);
85
+ content.push(` status: ${status}`);
86
+ content.push(` current: ${row.current} (${row.age} ago)`);
87
+ if (row.status === "need update") content.push(` latest: ${row.latest} (${row.latestAge} ago) change: ${row.change}`);
88
+ return content;
89
+ }
62
90
 
63
91
  //#endregion
64
92
  //#region src/cli-table.ts
@@ -70,8 +98,8 @@ const leftMiddleCorner = "├";
70
98
  const rightMiddleCorner = "┤";
71
99
  const horizontal = "─";
72
100
  const vertical = "│";
73
- function renderTable(rows) {
74
- console.log(table(rows).join("\n"));
101
+ function renderTable(rows, ctx) {
102
+ ctx.console.log(table(rows).join("\n"));
75
103
  }
76
104
  function table(rows) {
77
105
  const content = [];
@@ -1625,7 +1653,6 @@ function getBump(current, latest) {
1625
1653
 
1626
1654
  //#endregion
1627
1655
  //#region src/cli.ts
1628
- const defaultRefreshInterval = 80;
1629
1656
  const spinnerFrames = [
1630
1657
  "⠋",
1631
1658
  "⠙",
@@ -1647,41 +1674,86 @@ var Renderer = class {
1647
1674
  this._renderFn(props);
1648
1675
  }
1649
1676
  };
1650
- function spinner(refreshInterval = defaultRefreshInterval) {
1651
- return spinnerFrames[Math.floor(Date.now() / refreshInterval) % spinnerFrames.length];
1677
+ function spinner(ctx) {
1678
+ return spinnerFrames[Math.floor(Date.now() / ctx.refreshInterval) % spinnerFrames.length];
1679
+ }
1680
+ function parseRow(r, ctx) {
1681
+ if (r.status === "error") ctx.console.error(`Failed to fetch ${r.dep.name}`);
1682
+ let age = r.dep.versionValid ? "-" : "invalid version";
1683
+ if (!r.dep.localDep && r.dep.versionValid) age = r.dep.versionAge ? timeAgoFromAge(r.dep.versionAge) : spinner(ctx);
1684
+ let latestAge = r.dep.localDep ? "-" : spinner(ctx);
1685
+ if (!r.dep.localDep && r.dep.latestVersionAge) latestAge = timeAgoFromAge(r.dep.latestVersionAge);
1686
+ const status = r.status === "pending" ? spinner(ctx) : r.status === "done" && r.needUpdate ? "need update" : "ok";
1687
+ const change = r.needUpdate ? getBump(r.dep.version, r.dep.latestVersion ?? "") : "-";
1688
+ return {
1689
+ package: r.dep.name,
1690
+ current: r.dep.version,
1691
+ age,
1692
+ latest: r.dep.latestVersion ?? spinner(ctx),
1693
+ latestAge,
1694
+ status,
1695
+ change
1696
+ };
1652
1697
  }
1653
- function renderDepsTable(rows, refreshInterval = defaultRefreshInterval) {
1654
- const nDeps = rows.filter((x) => x.dep.type === "dep").length;
1655
- const nDevDeps = rows.filter((x) => x.dep.type === "devDep").length;
1656
- const fn = (r) => {
1657
- if (r.status === "error") console.error(`Failed to fetch ${r.dep.name}`);
1658
- let age = r.dep.versionValid ? "-" : "invalid version";
1659
- if (!r.dep.localDep && r.dep.versionValid) age = r.dep.versionAge ? timeAgoFromAge(r.dep.versionAge) : spinner(refreshInterval);
1660
- let latestAge = r.dep.localDep ? "-" : spinner(refreshInterval);
1661
- if (!r.dep.localDep && r.dep.latestVersionAge) latestAge = timeAgoFromAge(r.dep.latestVersionAge);
1662
- const status = r.status === "pending" ? spinner(refreshInterval) : r.status === "done" && r.needUpdate ? "need update" : "ok";
1663
- const change = r.needUpdate ? getBump(r.dep.version, r.dep.latestVersion ?? "") : "-";
1664
- return {
1665
- package: r.dep.name,
1666
- current: r.dep.version,
1667
- age,
1668
- latest: r.dep.latestVersion ?? spinner(refreshInterval),
1669
- latestAge,
1670
- status,
1671
- change
1672
- };
1698
+ function unwrap(rows, ctx) {
1699
+ return {
1700
+ deps: rows.filter((x) => x.dep.type === "dep").map((r) => parseRow(r, ctx)),
1701
+ devDeps: rows.filter((x) => x.dep.type === "devDep").map((r) => parseRow(r, ctx))
1673
1702
  };
1674
- if (nDeps > 0) {
1675
- console.log(`${nDeps} Dependencies`);
1676
- renderTable(rows.filter((x) => x.dep.type === "dep").map((r) => fn(r)));
1703
+ }
1704
+ function pluralDependency(n) {
1705
+ return `${n} Dependenc${n === 1 ? "y" : "ies"}`;
1706
+ }
1707
+ function renderDepsCompact(rows, ctx) {
1708
+ const { deps, devDeps } = unwrap(rows, ctx);
1709
+ if (deps.length > 0) {
1710
+ ctx.console.log(`${pluralDependency(deps.length)}\n`);
1711
+ renderCompact(deps, ctx);
1712
+ }
1713
+ if (devDeps.length > 0) {
1714
+ if (deps.length > 0) ctx.console.log("");
1715
+ ctx.console.log(`${pluralDependency(devDeps.length)}\n`);
1716
+ renderCompact(devDeps, ctx);
1717
+ }
1718
+ }
1719
+ function renderDepsTable(rows, ctx) {
1720
+ const { deps, devDeps } = unwrap(rows, ctx);
1721
+ if (deps.length > 0) {
1722
+ ctx.console.log(`${pluralDependency(deps.length)}\n`);
1723
+ renderTable(deps, ctx);
1677
1724
  }
1678
- if (nDevDeps > 0) {
1679
- if (nDeps > 0) console.log("");
1680
- console.log(`${nDevDeps} Dev Dependencies`);
1681
- renderTable(rows.filter((x) => x.dep.type === "devDep").map((r) => fn(r)));
1725
+ if (devDeps.length > 0) {
1726
+ if (deps.length > 0) ctx.console.log("");
1727
+ ctx.console.log(`${pluralDependency(devDeps.length)}\n`);
1728
+ renderTable(devDeps, ctx);
1682
1729
  }
1683
1730
  }
1684
1731
 
1732
+ //#endregion
1733
+ //#region src/console.ts
1734
+ var CliOutput = class {
1735
+ error(...message) {
1736
+ console.error(...message);
1737
+ }
1738
+ log(...message) {
1739
+ console.log(...message);
1740
+ }
1741
+ };
1742
+ var FileOutput = class {
1743
+ content = [];
1744
+ error(...message) {
1745
+ this.content.push(...message);
1746
+ }
1747
+ log(...message) {
1748
+ this.content.push(...message);
1749
+ }
1750
+ saveTo(filePath) {
1751
+ this.content = this.content.map((l) => clearColor(l));
1752
+ const header = `Upup report generated on ${(/* @__PURE__ */ new Date()).toISOString()}\n\n`;
1753
+ fs.writeFileSync(filePath, `${header}${this.content.join("\n")}`);
1754
+ }
1755
+ };
1756
+
1685
1757
  //#endregion
1686
1758
  //#region src/npm.ts
1687
1759
  function getPackageJson(packageJsonPath) {
@@ -1742,20 +1814,23 @@ if (!process$1 || !process$1.argv) {
1742
1814
  console.log("no process");
1743
1815
  process$1.exit(1);
1744
1816
  }
1745
- let args = process$1.argv;
1746
- args = args.slice(2);
1747
- let ci = false;
1748
- let cwd = process$1.cwd();
1749
- if (args.length > 0) for (const arg of args) if (arg.startsWith("--")) {
1750
- if (arg === "--ci") ci = true;
1751
- } else cwd = args[0];
1752
- const refreshInterval = 80;
1753
1817
  async function run() {
1818
+ let args = process$1.argv;
1819
+ args = args.slice(2);
1820
+ let compact = false;
1821
+ let ci = false;
1822
+ let cwd = process$1.cwd();
1823
+ let outputType = "cli";
1824
+ if (args.length > 0) for (const arg of args) if (arg.startsWith("--")) {
1825
+ if (arg === "--ci") ci = true;
1826
+ else if (arg === "--compact") compact = true;
1827
+ else if (arg === "--export-to-file") outputType = "file";
1828
+ } else cwd = args[0];
1829
+ const ctx = {
1830
+ console: outputType === "cli" ? new CliOutput() : new FileOutput(),
1831
+ refreshInterval: 80
1832
+ };
1754
1833
  console.log("Checking for packages updates ...\n");
1755
- const renderer = new Renderer((props) => {
1756
- if (!ci) console.clear();
1757
- renderDepsTable(props.deps);
1758
- });
1759
1834
  const pkgFile = `${cwd}/package.json`;
1760
1835
  if (!fs.existsSync(pkgFile)) {
1761
1836
  console.error(`package.json file not found at ${cwd}`);
@@ -1766,7 +1841,15 @@ async function run() {
1766
1841
  needUpdate: false,
1767
1842
  status: "pending"
1768
1843
  })) };
1769
- const ticker = ci ? null : setInterval(() => renderer.render(props), refreshInterval);
1844
+ const renderer = new Renderer((props) => {
1845
+ if (!ci) console.clear();
1846
+ if (compact) {
1847
+ renderDepsCompact(props.deps, ctx);
1848
+ return;
1849
+ }
1850
+ renderDepsTable(props.deps, ctx);
1851
+ });
1852
+ const ticker = ci ? null : setInterval(() => renderer.render(props), ctx.refreshInterval);
1770
1853
  const tasks = props.deps.map(async (row) => {
1771
1854
  try {
1772
1855
  if (row.dep.localDep) {
@@ -1791,8 +1874,12 @@ async function run() {
1791
1874
  if (ticker) clearInterval(ticker);
1792
1875
  renderer.render(props);
1793
1876
  const nOutdated = props.deps.filter((x) => x.needUpdate).length;
1794
- const nUpToDate = props.deps.filter((x) => !x.needUpdate).length;
1795
- console.log(`\n${yellow(`${nOutdated}`)} outdated, ${green(`${nUpToDate}`)} up to date`);
1877
+ const nUpToDate = props.deps.length - nOutdated;
1878
+ ctx.console.log(`\n${yellow(`${nOutdated}`)} outdated, ${green(`${nUpToDate}`)} up to date`);
1879
+ if ("saveTo" in ctx.console) {
1880
+ ctx.console.saveTo(".upup_report");
1881
+ console.log("Result saved to .upup_report");
1882
+ }
1796
1883
  }
1797
1884
  run().catch((err) => {
1798
1885
  console.error(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flyingboat/upup",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "CLI tool for listing outdated dependencies",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Francois Lajoie",
@@ -29,9 +29,9 @@
29
29
  },
30
30
  "devDependencies": {
31
31
  "@biomejs/biome": "^2.3.14",
32
- "@types/node": "^25.2.2",
32
+ "@types/node": "^25.2.3",
33
33
  "@types/semver": "^7.7.1",
34
- "rolldown": "^1.0.0-rc.3",
34
+ "rolldown": "^1.0.0-rc.4",
35
35
  "typescript": "~5.9.3",
36
36
  "vitest": "^4.0.18"
37
37
  }