@getmaito/cli 0.1.0 → 0.1.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/README.md CHANGED
@@ -57,6 +57,8 @@ Update the global install:
57
57
  npm update -g @getmaito/cli
58
58
  ```
59
59
 
60
+ The CLI checks npm for a newer version at most once per day and prints an update hint after normal human-readable command output. JSON output is not changed.
61
+
60
62
  ## Release
61
63
 
62
64
  The CLI package is published as `@getmaito/cli`.
package/dist/index.js CHANGED
@@ -17401,6 +17401,117 @@ function printPostList(value) {
17401
17401
  }
17402
17402
  }
17403
17403
 
17404
+ // src/update-check.ts
17405
+ import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
17406
+ import { createRequire } from "node:module";
17407
+ import os2 from "node:os";
17408
+ import path2 from "node:path";
17409
+ var require2 = createRequire(import.meta.url);
17410
+ var packageJson = require2("../package.json");
17411
+ var PACKAGE_NAME = typeof packageJson.name === "string" ? packageJson.name : "@getmaito/cli";
17412
+ var CURRENT_VERSION = typeof packageJson.version === "string" ? packageJson.version : "0.0.0";
17413
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
17414
+ var REGISTRY_LATEST_URL = "https://registry.npmjs.org/@getmaito%2fcli/latest";
17415
+ var REQUEST_TIMEOUT_MS = 1500;
17416
+ async function maybePrintUpdateNotice(input) {
17417
+ if (input.json || isDisabled()) {
17418
+ return;
17419
+ }
17420
+ const store = await readUpdateCheckStore().catch(() => ({}));
17421
+ const lastCheckedAt = store.lastCheckedAt ? Date.parse(store.lastCheckedAt) : Number.NaN;
17422
+ if (Number.isFinite(lastCheckedAt) && Date.now() - lastCheckedAt < CHECK_INTERVAL_MS) {
17423
+ return;
17424
+ }
17425
+ await writeUpdateCheckStore({
17426
+ lastCheckedAt: new Date().toISOString()
17427
+ }).catch(() => {
17428
+ return;
17429
+ });
17430
+ const latestVersion = await fetchLatestVersion().catch(() => {
17431
+ return;
17432
+ });
17433
+ if (!latestVersion || compareVersions(latestVersion, CURRENT_VERSION) <= 0) {
17434
+ return;
17435
+ }
17436
+ console.error("");
17437
+ console.error(`Update available: ${PACKAGE_NAME} ${CURRENT_VERSION} -> ${latestVersion}`);
17438
+ console.error(`Run: npm update -g ${PACKAGE_NAME}`);
17439
+ }
17440
+ function isDisabled() {
17441
+ const value = process.env.MAITO_CLI_DISABLE_UPDATE_CHECK?.trim().toLowerCase();
17442
+ return value === "1" || value === "true" || value === "yes";
17443
+ }
17444
+ async function fetchLatestVersion() {
17445
+ const controller = new AbortController;
17446
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
17447
+ try {
17448
+ const response = await fetch(REGISTRY_LATEST_URL, {
17449
+ headers: {
17450
+ accept: "application/json"
17451
+ },
17452
+ signal: controller.signal
17453
+ });
17454
+ if (!response.ok) {
17455
+ return;
17456
+ }
17457
+ const payload = await response.json();
17458
+ return typeof payload.version === "string" && payload.version.trim() ? payload.version.trim() : undefined;
17459
+ } finally {
17460
+ clearTimeout(timeout);
17461
+ }
17462
+ }
17463
+ async function readUpdateCheckStore() {
17464
+ const filePath = getUpdateCheckFilePath();
17465
+ try {
17466
+ const raw = await readFile2(filePath, "utf8");
17467
+ const parsed = JSON.parse(raw);
17468
+ return parsed && typeof parsed === "object" ? parsed : {};
17469
+ } catch (error48) {
17470
+ if (error48.code === "ENOENT") {
17471
+ return {};
17472
+ }
17473
+ throw error48;
17474
+ }
17475
+ }
17476
+ async function writeUpdateCheckStore(store) {
17477
+ const filePath = getUpdateCheckFilePath();
17478
+ await mkdir2(path2.dirname(filePath), { recursive: true });
17479
+ await writeFile2(filePath, `${JSON.stringify(store, null, 2)}
17480
+ `, {
17481
+ encoding: "utf8",
17482
+ mode: 384
17483
+ });
17484
+ }
17485
+ function getUpdateCheckFilePath() {
17486
+ return path2.join(getConfigDir2(), "maito", "update-check.json");
17487
+ }
17488
+ function getConfigDir2() {
17489
+ if (process.platform === "win32") {
17490
+ return process.env.APPDATA?.trim() || path2.join(os2.homedir(), "AppData", "Roaming");
17491
+ }
17492
+ return process.env.XDG_CONFIG_HOME?.trim() || path2.join(os2.homedir(), ".config");
17493
+ }
17494
+ function compareVersions(left, right) {
17495
+ const leftParts = readVersionParts(left);
17496
+ const rightParts = readVersionParts(right);
17497
+ for (let index = 0;index < 3; index += 1) {
17498
+ const difference = (leftParts[index] ?? 0) - (rightParts[index] ?? 0);
17499
+ if (difference !== 0) {
17500
+ return difference;
17501
+ }
17502
+ }
17503
+ return 0;
17504
+ }
17505
+ function readVersionParts(value) {
17506
+ const release = value.split("-", 1)[0] ?? "";
17507
+ const parts = release.split(".");
17508
+ return [
17509
+ Number.parseInt(parts[0] ?? "0", 10) || 0,
17510
+ Number.parseInt(parts[1] ?? "0", 10) || 0,
17511
+ Number.parseInt(parts[2] ?? "0", 10) || 0
17512
+ ];
17513
+ }
17514
+
17404
17515
  // src/index.ts
17405
17516
  async function main() {
17406
17517
  const { positionals, flags } = parseArgs(process.argv.slice(2));
@@ -17422,6 +17533,7 @@ async function main() {
17422
17533
  return;
17423
17534
  }
17424
17535
  console.log(`Signed in to ${status.baseUrl}${formatSignedInUser(status.user)}`);
17536
+ await maybePrintUpdateNotice({ json: json2 });
17425
17537
  return;
17426
17538
  }
17427
17539
  if (commandKey === "logout") {
@@ -17434,10 +17546,12 @@ async function main() {
17434
17546
  return;
17435
17547
  }
17436
17548
  console.log(removed ? `Signed out from ${baseUrl}.` : `No saved OAuth session for ${baseUrl}.`);
17549
+ await maybePrintUpdateNotice({ json: json2 });
17437
17550
  return;
17438
17551
  }
17439
17552
  if (commandKey === "auth.status") {
17440
17553
  await printAuthStatus({ baseUrl, json: json2 });
17554
+ await maybePrintUpdateNotice({ json: json2 });
17441
17555
  return;
17442
17556
  }
17443
17557
  if (commandKey === "auth.use-api-key") {
@@ -17448,6 +17562,7 @@ async function main() {
17448
17562
  return;
17449
17563
  }
17450
17564
  console.log(`Stored API key for ${baseUrl}.`);
17565
+ await maybePrintUpdateNotice({ json: json2 });
17451
17566
  return;
17452
17567
  }
17453
17568
  if (commandKey === "auth.clear-api-key") {
@@ -17457,6 +17572,7 @@ async function main() {
17457
17572
  return;
17458
17573
  }
17459
17574
  console.log(removed ? `Removed stored API key for ${baseUrl}.` : `No stored API key for ${baseUrl}.`);
17575
+ await maybePrintUpdateNotice({ json: json2 });
17460
17576
  return;
17461
17577
  }
17462
17578
  const context = {
@@ -17516,6 +17632,7 @@ async function main() {
17516
17632
  return;
17517
17633
  }
17518
17634
  printHuman(outputKey, result);
17635
+ await maybePrintUpdateNotice({ json: json2 });
17519
17636
  }
17520
17637
  async function printAuthStatus(input) {
17521
17638
  const [status, storedApiKey] = await Promise.all([
@@ -0,0 +1,4 @@
1
+ export declare function maybePrintUpdateNotice(input: {
2
+ json: boolean;
3
+ }): Promise<void>;
4
+ //# 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":"AA4BA,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,iBA8BpE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getmaito/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "maito": "dist/index.js"