@tillstack/cli 0.2.2 → 0.3.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.
- package/dist/api.d.ts +195 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +59 -5
- package/dist/api.js.map +1 -1
- package/dist/index.js +1132 -18
- package/dist/index.js.map +1 -1
- package/dist/update-check.d.ts +10 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +124 -0
- package/dist/update-check.js.map +1 -0
- package/package.json +11 -10
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** True when `candidate` is a strictly-higher release than `current`. */
|
|
2
|
+
export declare function isNewer(candidate: string, current: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Print a one-line "update available" notice if npm has a newer release than
|
|
5
|
+
* `current`. No-op (and no network) when non-interactive, in CI, in --json
|
|
6
|
+
* mode, when opted out (TILLDEV_NO_UPDATE_CHECK / NO_UPDATE_NOTIFIER), or when
|
|
7
|
+
* we couldn't determine our own version. Never throws.
|
|
8
|
+
*/
|
|
9
|
+
export declare function notifyUpdate(current: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=update-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AA6DA,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAYnE;AAgBD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BjE"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Update notifier — tells the user when a newer @tillstack/cli is on npm and
|
|
2
|
+
// how to get it. Deliberately dependency-free (the CLI ships zero runtime deps)
|
|
3
|
+
// and defensive: a broken or slow registry must never disrupt a real command.
|
|
4
|
+
//
|
|
5
|
+
// Cadence: the latest version is cached under ~/.tilldev for a day, so at most
|
|
6
|
+
// one registry round-trip happens per 24h and every other invocation is a
|
|
7
|
+
// synchronous file read. The notice prints to STDERR after the command's own
|
|
8
|
+
// output, so it never corrupts stdout / --json and is invisible when piped.
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { c } from './output.js';
|
|
13
|
+
// The registry resolves a dist-tag in the version slot and returns just that
|
|
14
|
+
// version's manifest (small), not the full packument with every version.
|
|
15
|
+
const REGISTRY_LATEST = 'https://registry.npmjs.org/@tillstack%2Fcli/latest';
|
|
16
|
+
const UPGRADE_CMD = 'npm install -g @tillstack/cli@latest';
|
|
17
|
+
const INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
18
|
+
const FETCH_TIMEOUT_MS = 1200;
|
|
19
|
+
function cacheDir() {
|
|
20
|
+
return join(homedir(), '.tilldev');
|
|
21
|
+
}
|
|
22
|
+
function cachePath() {
|
|
23
|
+
return join(cacheDir(), 'update-check.json');
|
|
24
|
+
}
|
|
25
|
+
function readCache() {
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(readFileSync(cachePath(), 'utf8'));
|
|
28
|
+
return { lastCheck: typeof parsed.lastCheck === 'number' ? parsed.lastCheck : 0, latest: parsed.latest };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return { lastCheck: 0 };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function writeCache(cache) {
|
|
35
|
+
try {
|
|
36
|
+
mkdirSync(cacheDir(), { recursive: true, mode: 0o700 });
|
|
37
|
+
writeFileSync(cachePath(), JSON.stringify(cache), 'utf8');
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* best-effort: a read-only home must not break the CLI */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Numeric x.y.z comparison. Prerelease/build metadata is dropped — the `latest`
|
|
44
|
+
// dist-tag is a stable release, so comparing release cores is sufficient and
|
|
45
|
+
// avoids nagging about a `-rc` a user is deliberately running.
|
|
46
|
+
function parseVer(v) {
|
|
47
|
+
const core = v.trim().replace(/^v/, '').split('+')[0]?.split('-')[0] ?? '';
|
|
48
|
+
if (!core)
|
|
49
|
+
return null;
|
|
50
|
+
const parts = core.split('.').map((p) => Number(p));
|
|
51
|
+
if (!parts.length || parts.some((n) => !Number.isInteger(n) || n < 0))
|
|
52
|
+
return null;
|
|
53
|
+
return parts;
|
|
54
|
+
}
|
|
55
|
+
/** True when `candidate` is a strictly-higher release than `current`. */
|
|
56
|
+
export function isNewer(candidate, current) {
|
|
57
|
+
const a = parseVer(candidate);
|
|
58
|
+
const b = parseVer(current);
|
|
59
|
+
if (!a || !b)
|
|
60
|
+
return false;
|
|
61
|
+
const len = Math.max(a.length, b.length);
|
|
62
|
+
for (let i = 0; i < len; i++) {
|
|
63
|
+
const x = a[i] ?? 0;
|
|
64
|
+
const y = b[i] ?? 0;
|
|
65
|
+
if (x > y)
|
|
66
|
+
return true;
|
|
67
|
+
if (x < y)
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
async function fetchLatest() {
|
|
73
|
+
try {
|
|
74
|
+
const res = await fetch(REGISTRY_LATEST, {
|
|
75
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
76
|
+
headers: { accept: 'application/json' },
|
|
77
|
+
});
|
|
78
|
+
if (!res.ok)
|
|
79
|
+
return undefined;
|
|
80
|
+
const j = (await res.json());
|
|
81
|
+
return typeof j.version === 'string' ? j.version : undefined;
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return undefined; // offline, DNS, timeout, 5xx — all silent
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Print a one-line "update available" notice if npm has a newer release than
|
|
89
|
+
* `current`. No-op (and no network) when non-interactive, in CI, in --json
|
|
90
|
+
* mode, when opted out (TILLDEV_NO_UPDATE_CHECK / NO_UPDATE_NOTIFIER), or when
|
|
91
|
+
* we couldn't determine our own version. Never throws.
|
|
92
|
+
*/
|
|
93
|
+
export async function notifyUpdate(current) {
|
|
94
|
+
try {
|
|
95
|
+
if (current === '0.0.0')
|
|
96
|
+
return; // couldn't read our own version — don't guess
|
|
97
|
+
if (!process.stderr.isTTY)
|
|
98
|
+
return;
|
|
99
|
+
if (process.env['CI'])
|
|
100
|
+
return;
|
|
101
|
+
if (process.env['TILLDEV_NO_UPDATE_CHECK'] || process.env['NO_UPDATE_NOTIFIER'])
|
|
102
|
+
return;
|
|
103
|
+
if (process.argv.slice(2).includes('--json'))
|
|
104
|
+
return;
|
|
105
|
+
const cache = readCache();
|
|
106
|
+
let latest = cache.latest;
|
|
107
|
+
if (Date.now() - cache.lastCheck > INTERVAL_MS) {
|
|
108
|
+
const fetched = await fetchLatest();
|
|
109
|
+
// Stamp the attempt either way: on a registry blip we back off for the
|
|
110
|
+
// interval rather than adding latency to every subsequent command.
|
|
111
|
+
writeCache({ lastCheck: Date.now(), latest: fetched ?? cache.latest });
|
|
112
|
+
latest = fetched ?? cache.latest;
|
|
113
|
+
}
|
|
114
|
+
if (!latest || !isNewer(latest, current))
|
|
115
|
+
return;
|
|
116
|
+
console.error();
|
|
117
|
+
console.error(` ${c.yellow('●')} ${c.bold('Update available')} ${c.dim(current)} ${c.dim('→')} ${c.green(latest)}`);
|
|
118
|
+
console.error(` ${c.dim('run')} ${c.bold(UPGRADE_CMD)} ${c.dim('(silence: TILLDEV_NO_UPDATE_CHECK=1)')}`);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
/* a broken update check must never disrupt the CLI */
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tillstack/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "TillDev command-line interface — manage TillPulse observability, TillShield edge WAF, TillGate and TillAuth from your terminal (source-map uploads, rules-as-code, and more).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
"engines": {
|
|
15
15
|
"node": ">=20"
|
|
16
16
|
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsx src/index.ts",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"prepack": "tsc",
|
|
22
|
+
"clean": "rm -rf dist"
|
|
23
|
+
},
|
|
17
24
|
"devDependencies": {
|
|
18
25
|
"@types/node": "^22.0.0",
|
|
19
26
|
"tsx": "^4.19.2",
|
|
@@ -21,12 +28,12 @@
|
|
|
21
28
|
},
|
|
22
29
|
"repository": {
|
|
23
30
|
"type": "git",
|
|
24
|
-
"url": "git+https://
|
|
31
|
+
"url": "git+https://git.tilldev.dev/tillafrica/tilldev.git",
|
|
25
32
|
"directory": "apps/cli"
|
|
26
33
|
},
|
|
27
34
|
"homepage": "https://tilldev.dev/docs/tilldev/cli",
|
|
28
35
|
"bugs": {
|
|
29
|
-
"url": "https://
|
|
36
|
+
"url": "https://tilldev.dev/docs/tilldev/cli"
|
|
30
37
|
},
|
|
31
38
|
"keywords": [
|
|
32
39
|
"tilldev",
|
|
@@ -39,11 +46,5 @@
|
|
|
39
46
|
],
|
|
40
47
|
"publishConfig": {
|
|
41
48
|
"access": "public"
|
|
42
|
-
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"build": "tsc",
|
|
45
|
-
"dev": "tsx src/index.ts",
|
|
46
|
-
"typecheck": "tsc --noEmit",
|
|
47
|
-
"clean": "rm -rf dist"
|
|
48
49
|
}
|
|
49
|
-
}
|
|
50
|
+
}
|