agy-cli-usage 0.3.1 → 0.4.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/src/update.js DELETED
@@ -1,87 +0,0 @@
1
- // Self-update + version helpers for the CLI.
2
- //
3
- // `agy-cli-usage update` check the registry and `npm install -g` if newer
4
- // `agy-cli-usage update --check` report only, don't install
5
- // `agy-cli-usage --version` print the installed version
6
-
7
- import { execFileSync, spawnSync } from 'node:child_process';
8
- import { readFileSync } from 'node:fs';
9
-
10
- const PKG_NAME = 'agy-cli-usage';
11
-
12
- /** Installed version, read from this package's package.json. */
13
- export function currentVersion() {
14
- const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
15
- return pkg.version;
16
- }
17
-
18
- /**
19
- * Compare two dotted versions numerically (prerelease tags ignored).
20
- * @returns negative if a<b, 0 if equal, positive if a>b
21
- */
22
- export function semverCompare(a, b) {
23
- const norm = (v) =>
24
- String(v)
25
- .replace(/^v/, '')
26
- .split('-')[0]
27
- .split('.')
28
- .map((n) => parseInt(n, 10) || 0);
29
- const pa = norm(a);
30
- const pb = norm(b);
31
- for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
32
- const d = (pa[i] || 0) - (pb[i] || 0);
33
- if (d !== 0) return d;
34
- }
35
- return 0;
36
- }
37
-
38
- /** Latest published version: prefer the user's configured registry (npm view), fall back to public. */
39
- export async function latestVersion() {
40
- try {
41
- const out = execFileSync('npm', ['view', PKG_NAME, 'version'], {
42
- encoding: 'utf8',
43
- stdio: ['ignore', 'pipe', 'ignore'],
44
- }).trim();
45
- if (out) return out;
46
- } catch {
47
- // npm missing or offline — try the public registry directly
48
- }
49
- try {
50
- const res = await fetch(`https://registry.npmjs.org/${PKG_NAME}/latest`);
51
- if (res.ok) return (await res.json()).version;
52
- } catch {
53
- // offline
54
- }
55
- return null;
56
- }
57
-
58
- /**
59
- * Run the update flow.
60
- * @param {{ checkOnly?: boolean }} opts
61
- * @returns {Promise<number>} process exit code
62
- */
63
- export async function runUpdate({ checkOnly = false } = {}) {
64
- const current = currentVersion();
65
- const latest = await latestVersion();
66
- if (!latest) {
67
- process.stderr.write('Could not determine the latest version (offline or npm unavailable).\n');
68
- return 1;
69
- }
70
- if (semverCompare(latest, current) <= 0) {
71
- process.stdout.write(`agy-cli-usage is up to date (${current}).\n`);
72
- return 0;
73
- }
74
- process.stdout.write(`Update available: ${current} -> ${latest}\n`);
75
- if (checkOnly) {
76
- process.stdout.write('Run `agy-cli-usage update` to install it.\n');
77
- return 0;
78
- }
79
- process.stdout.write(`Installing ${PKG_NAME}@${latest} globally…\n`);
80
- const r = spawnSync('npm', ['install', '-g', `${PKG_NAME}@${latest}`], { stdio: 'inherit' });
81
- if (r.error) {
82
- process.stderr.write(`Failed to run npm: ${r.error.message}\nInstall manually: npm install -g ${PKG_NAME}@latest\n`);
83
- return 1;
84
- }
85
- if (r.status === 0) process.stdout.write(`Updated to ${latest}.\n`);
86
- return r.status ?? 0;
87
- }