nukebase 2.0.4 → 2.0.5

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/bin/nukebase.js CHANGED
@@ -8,6 +8,19 @@
8
8
  const args = require('../lib/args').parse(process.argv.slice(2));
9
9
  const { version } = require('../package.json');
10
10
 
11
+ // "nukebase X is available": checked once a day while the command runs, printed
12
+ // when the command finishes. 'exit' covers both kinds of command: project
13
+ // commands end with process.exit, account commands end by themselves.
14
+ // Not after --version, whose output scripts read.
15
+ if (!(args.has('version') && !args.command)) {
16
+ const updates = require('../lib/update-check');
17
+ updates.scheduleCheck();
18
+ process.on('exit', () => {
19
+ const line = updates.notice(version);
20
+ if (line) console.error(line);
21
+ });
22
+ }
23
+
11
24
  const ACCOUNT_COMMANDS = ['login', 'logout', 'accounts', 'use', 'whoami', 'create', 'link'];
12
25
  const PROJECT_COMMANDS = [
13
26
  'push', 'pull', 'update', 'rollback', 'restorepoints', 'restore-points', 'backup', 'env',
@@ -0,0 +1,73 @@
1
+ // "A newer nukebase is available" notice.
2
+ //
3
+ // A global install never updates itself, and while one is installed even
4
+ // `npx nukebase` keeps running it. So once a day, while a command runs, the
5
+ // CLI asks the npm registry for the latest version (one small request, 1.5 s
6
+ // at most) and saves it next to the credentials. When the command finishes it
7
+ // prints one line if that version is newer than the one running.
8
+ //
9
+ // Off when NUKEBASE_NO_UPDATE_CHECK or CI is set.
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const { FILE: CREDENTIALS_FILE } = require('./credentials');
14
+
15
+ const CACHE = path.join(path.dirname(CREDENTIALS_FILE), 'update-check.json');
16
+ const CHECK_EVERY_MS = 24 * 60 * 60 * 1000;
17
+ const REGISTRY_URL = 'https://registry.npmjs.org/nukebase/latest';
18
+
19
+ const disabled = () => !!(process.env.NUKEBASE_NO_UPDATE_CHECK || process.env.CI);
20
+
21
+ function readCache() {
22
+ try { return JSON.parse(fs.readFileSync(CACHE, 'utf8')); } catch { return {}; }
23
+ }
24
+
25
+ // "2.0.10" > "2.0.9"; pre-release tags are ignored.
26
+ function isNewer(a, b) {
27
+ const pa = String(a).split('-')[0].split('.').map(Number);
28
+ const pb = String(b).split('-')[0].split('.').map(Number);
29
+ for (let i = 0; i < 3; i++) {
30
+ if ((pa[i] || 0) !== (pb[i] || 0)) return (pa[i] || 0) > (pb[i] || 0);
31
+ }
32
+ return false;
33
+ }
34
+
35
+ // Ask the registry, if a day has passed since the last time. Runs alongside
36
+ // the command; a command that exits first simply checks again next time.
37
+ // Never throws.
38
+ function scheduleCheck() {
39
+ if (disabled()) return;
40
+ if (Date.now() - (readCache().checkedAt || 0) < CHECK_EVERY_MS) return;
41
+ runCheck().catch(() => {});
42
+ }
43
+
44
+ // The notice for the version running now, or null.
45
+ function notice(current) {
46
+ if (disabled()) return null;
47
+ const { latest } = readCache();
48
+ if (!latest || !isNewer(latest, current)) return null;
49
+ // Run through npx (from npm's cache), or installed globally?
50
+ const viaNpx = __dirname.split(path.sep).includes('_npx');
51
+ const how = viaNpx
52
+ ? 'Run it with: npx nukebase@latest <command>'
53
+ : 'Update with: npm i -g nukebase@latest';
54
+ return `\nnukebase ${latest} is available (you have ${current}). ${how}`;
55
+ }
56
+
57
+ // One request to the registry; the answer is saved for a day.
58
+ async function runCheck() {
59
+ let latest = null;
60
+ try {
61
+ const r = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(1500) });
62
+ if (r.ok) latest = (await r.json()).version || null;
63
+ } catch {}
64
+ try {
65
+ fs.mkdirSync(path.dirname(CACHE), { recursive: true });
66
+ // Record the attempt even when it failed, so an offline machine doesn't
67
+ // re-check on every command; keep the last known version.
68
+ const prev = readCache();
69
+ fs.writeFileSync(CACHE, JSON.stringify({ checkedAt: Date.now(), latest: latest || prev.latest || null }) + '\n');
70
+ } catch {}
71
+ }
72
+
73
+ module.exports = { scheduleCheck, notice, isNewer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nukebase",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "NukeBase CLI: create, deploy and manage NukeBase projects",
5
5
  "bin": {
6
6
  "nukebase": "bin/nukebase.js"