@trayai/tray-sync-cli 1.0.15 → 1.0.17

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/cli.js CHANGED
@@ -12,6 +12,8 @@ import { authCommand } from "./commands/auth.js";
12
12
  import { promoteCommand } from "./commands/promote.js";
13
13
  import { apiCommand } from "./commands/api/api.js";
14
14
  import { isApiEnabled } from "./lib/apiAuth.js";
15
+ import { checkVersion, VersionDeprecatedError } from "./lib/versionCheck.js";
16
+ import { formatDeprecationRefusal, formatOutdatedNag } from "./views/versionCheck.v2.js";
15
17
  import { BANNER } from "./views/banner.js";
16
18
  import { TrayHelp } from "./views/help.js";
17
19
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -41,6 +43,20 @@ if (isApiEnabled()) {
41
43
  apiCommand.helpGroup("General-purpose API (growing)");
42
44
  program.addCommand(apiCommand);
43
45
  }
46
+ program.hook("preAction", async () => {
47
+ try {
48
+ await checkVersion(pkg.version, {
49
+ onOutdated: (latest, installed) => console.error(formatOutdatedNag(latest, installed)),
50
+ });
51
+ }
52
+ catch (err) {
53
+ if (err instanceof VersionDeprecatedError) {
54
+ console.error(formatDeprecationRefusal(err.message));
55
+ process.exit(1);
56
+ }
57
+ throw err;
58
+ }
59
+ });
44
60
  program.parseAsync(process.argv).catch((err) => {
45
61
  const message = err instanceof Error ? err.message : String(err);
46
62
  console.error(message);
@@ -0,0 +1,48 @@
1
+ import { readJson, writeJson } from "../config/io.js";
2
+ import { versionCheckPath } from "../config/paths.js";
3
+ import { NetworkError } from "../api/errors.js";
4
+ const REGISTRY_URL = "https://registry.npmjs.org/@trayai/tray-sync-cli";
5
+ const TTL_MS = 24 * 60 * 60 * 1000;
6
+ const FETCH_TIMEOUT_MS = 5_000;
7
+ export async function checkVersion(installedVersion, deps = {}) {
8
+ const { env, now = () => new Date(), onOutdated } = deps;
9
+ const fetchImpl = deps.fetchImpl ?? fetch;
10
+ const cached = await readJson(versionCheckPath(env)).catch(() => undefined);
11
+ const isFresh = cached !== undefined && now().getTime() - Date.parse(cached.cached_at) < TTL_MS;
12
+ const response = isFresh
13
+ ? cached.response
14
+ : await fetchAndCache(installedVersion, fetchImpl, env, now).catch(() => undefined);
15
+ if (response === undefined)
16
+ return;
17
+ if (response.deprecated) {
18
+ throw new VersionDeprecatedError(response.deprecated);
19
+ }
20
+ if (installedVersion !== response.latest) {
21
+ onOutdated?.(response.latest, installedVersion);
22
+ }
23
+ }
24
+ async function fetchAndCache(installedVersion, fetchImpl, env, now) {
25
+ let raw;
26
+ try {
27
+ const res = await fetchImpl(REGISTRY_URL, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
28
+ if (!res.ok)
29
+ throw new Error(`HTTP ${res.status}`);
30
+ raw = (await res.json());
31
+ }
32
+ catch (err) {
33
+ throw new NetworkError(`Could not reach the npm registry to check for a deprecated version: ${err.message}`);
34
+ }
35
+ const latest = raw["dist-tags"]?.latest;
36
+ if (!latest) {
37
+ throw new NetworkError("Unexpected response from the npm registry: missing dist-tags.latest");
38
+ }
39
+ const response = {
40
+ latest,
41
+ deprecated: raw.versions?.[installedVersion]?.deprecated ?? null,
42
+ };
43
+ await writeJson(versionCheckPath(env), { cached_at: now().toISOString(), response });
44
+ return response;
45
+ }
46
+ export class VersionDeprecatedError extends Error {
47
+ }
48
+ //# sourceMappingURL=versionCheck.js.map
@@ -0,0 +1,11 @@
1
+ import ansis from "ansis";
2
+ import { INFO_ICON, WARNING_ICON } from "./icons.js";
3
+ export function formatOutdatedNag(latest, installed) {
4
+ return (`${INFO_ICON} A ${ansis.bold("newer")} version of tray-sync-cli is available ` +
5
+ `(${ansis.bold.green(latest)}, you have ${ansis.bold(installed)}).\n` +
6
+ `Upgrade: ${ansis.bold("npm install -g @trayai/tray-sync-cli")}`);
7
+ }
8
+ export function formatDeprecationRefusal(message) {
9
+ return `${WARNING_ICON} ${message}\n` + `Upgrade: ${ansis.bold("npm install -g @trayai/tray-sync-cli")}`;
10
+ }
11
+ //# sourceMappingURL=versionCheck.v2.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trayai/tray-sync-cli",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "CLI tool to clone Tray projects and related assets to a local directory, and promote them between Tray environments",
5
5
  "bin": {
6
6
  "tray": "dist/cli.js"