inup 1.5.5 → 1.6.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.
Files changed (75) hide show
  1. package/README.md +53 -10
  2. package/dist/cli.js +53 -31
  3. package/dist/config/constants.js +4 -6
  4. package/dist/config/package-meta.js +10 -0
  5. package/dist/config/project-config.js +11 -1
  6. package/dist/core/package-detector.js +37 -5
  7. package/dist/core/upgrade-runner.js +8 -10
  8. package/dist/core/upgrader.js +15 -11
  9. package/dist/features/changelog/clients/github-client.js +5 -6
  10. package/dist/features/changelog/services/changelog-service.js +2 -4
  11. package/dist/features/changelog/services/package-metadata-service.js +7 -23
  12. package/dist/features/changelog/services/release-notes-service.js +4 -29
  13. package/dist/features/debug/services/performance-tracker.js +6 -8
  14. package/dist/features/headless/headless-runner.js +53 -0
  15. package/dist/features/headless/index.js +27 -0
  16. package/dist/features/headless/report.js +64 -0
  17. package/dist/features/headless/types.js +6 -0
  18. package/dist/features/headless/vulnerability-audit.js +106 -0
  19. package/dist/index.js +1 -2
  20. package/dist/interactive-ui.js +15 -606
  21. package/dist/services/background-audit.js +3 -5
  22. package/dist/services/cache-manager.js +5 -7
  23. package/dist/services/http/inflight.js +22 -0
  24. package/dist/services/http/retry.js +30 -0
  25. package/dist/services/index.js +0 -1
  26. package/dist/services/npm-registry.js +20 -97
  27. package/dist/services/package-manager-detector.js +6 -3
  28. package/dist/services/persistent-cache.js +8 -13
  29. package/dist/types/domain.js +3 -0
  30. package/dist/types/streaming.js +3 -0
  31. package/dist/types/ui.js +3 -0
  32. package/dist/types.js +17 -0
  33. package/dist/ui/controllers/package-info-modal-controller.js +22 -31
  34. package/dist/ui/controllers/vulnerability-audit-controller.js +17 -8
  35. package/dist/ui/index.js +3 -0
  36. package/dist/ui/input-handler.js +58 -75
  37. package/dist/ui/keymap.js +208 -0
  38. package/dist/ui/modal/package-info-sections/release-notes.js +161 -0
  39. package/dist/ui/modal/package-info-sections/sections.js +174 -0
  40. package/dist/ui/modal/package-info-sections/text.js +75 -0
  41. package/dist/ui/modal/package-info-sections.js +15 -369
  42. package/dist/ui/modal/package-info.js +1 -1
  43. package/dist/ui/presenters/health.js +24 -0
  44. package/dist/ui/renderer/help-modal.js +75 -0
  45. package/dist/ui/renderer/index.js +2 -5
  46. package/dist/ui/renderer/package-list/interface.js +184 -0
  47. package/dist/ui/renderer/package-list/rows.js +177 -0
  48. package/dist/ui/renderer/package-list.js +15 -455
  49. package/dist/ui/session/action-dispatcher.js +233 -0
  50. package/dist/ui/session/index.js +13 -0
  51. package/dist/ui/session/interactive-session.js +280 -0
  52. package/dist/ui/session/selection-state-builder.js +149 -0
  53. package/dist/ui/state/filter-manager.js +17 -6
  54. package/dist/ui/state/modal-manager.js +35 -0
  55. package/dist/ui/state/navigation-manager.js +33 -4
  56. package/dist/ui/state/state-manager.js +68 -3
  57. package/dist/ui/state/theme-manager.js +1 -0
  58. package/dist/ui/themes-colors.js +16 -4
  59. package/dist/ui/themes.js +11 -19
  60. package/dist/ui/utils/cursor.js +12 -7
  61. package/dist/ui/utils/index.js +6 -1
  62. package/dist/ui/utils/text.js +3 -2
  63. package/dist/ui/utils/version.js +60 -86
  64. package/dist/utils/color.js +38 -0
  65. package/dist/utils/config.js +13 -1
  66. package/dist/utils/engines.js +63 -0
  67. package/dist/utils/filesystem/io.js +103 -0
  68. package/dist/utils/filesystem/paths.js +19 -0
  69. package/dist/utils/filesystem/scan.js +280 -0
  70. package/dist/utils/filesystem.js +17 -335
  71. package/dist/utils/index.js +3 -0
  72. package/dist/utils/manifest.js +35 -0
  73. package/dist/utils/version.js +38 -1
  74. package/package.json +8 -7
  75. package/dist/services/jsdelivr-registry.js +0 -395
@@ -3,11 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BackgroundAuditTracker = void 0;
4
4
  const utils_1 = require("../utils");
5
5
  class BackgroundAuditTracker {
6
- constructor() {
7
- this.pending = new Map();
8
- this.inFlight = new Set();
9
- this.completed = new Set();
10
- }
6
+ pending = new Map();
7
+ inFlight = new Set();
8
+ completed = new Set();
11
9
  enqueue(packages) {
12
10
  let added = 0;
13
11
  for (const pkg of packages) {
@@ -3,13 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.packageCache = exports.CacheManager = void 0;
4
4
  const config_1 = require("../config");
5
5
  const persistent_cache_1 = require("./persistent-cache");
6
- /**
7
- * Unified cache manager that handles both in-memory and persistent disk caching.
8
- * Consolidates caching logic used across registry services.
9
- */
6
+ // Single TTL policy for both memory and disk.
10
7
  class CacheManager {
8
+ memoryCache = new Map();
9
+ ttl;
11
10
  constructor(ttl = config_1.CACHE_TTL) {
12
- this.memoryCache = new Map();
13
11
  this.ttl = ttl;
14
12
  }
15
13
  /**
@@ -24,11 +22,11 @@ class CacheManager {
24
22
  }
25
23
  // Check persistent disk cache (survives restarts)
26
24
  const diskCached = persistent_cache_1.persistentCache.get(key);
27
- if (diskCached) {
25
+ if (diskCached && Date.now() - diskCached.timestamp < this.ttl) {
28
26
  // Populate in-memory cache for subsequent accesses
29
27
  this.memoryCache.set(key, {
30
28
  data: diskCached,
31
- timestamp: Date.now(),
29
+ timestamp: diskCached.timestamp,
32
30
  });
33
31
  return diskCached;
34
32
  }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InflightMap = void 0;
4
+ class InflightMap {
5
+ map = new Map();
6
+ async dedupe(key, fn) {
7
+ const existing = this.map.get(key);
8
+ if (existing) {
9
+ return await existing;
10
+ }
11
+ const promise = fn().finally(() => {
12
+ this.map.delete(key);
13
+ });
14
+ this.map.set(key, promise);
15
+ return await promise;
16
+ }
17
+ clear() {
18
+ this.map.clear();
19
+ }
20
+ }
21
+ exports.InflightMap = InflightMap;
22
+ //# sourceMappingURL=inflight.js.map
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTransientNetworkError = exports.isRetryableStatus = exports.sleep = void 0;
4
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5
+ exports.sleep = sleep;
6
+ const isRetryableStatus = (statusCode) => statusCode === 408 || statusCode === 429 || statusCode >= 500;
7
+ exports.isRetryableStatus = isRetryableStatus;
8
+ const isTransientNetworkError = (error) => {
9
+ if (!(error instanceof Error)) {
10
+ return false;
11
+ }
12
+ const maybeCode = error.code;
13
+ return (error.name === 'AbortError' ||
14
+ error.name === 'HeadersTimeoutError' ||
15
+ error.name === 'BodyTimeoutError' ||
16
+ error.name === 'ConnectTimeoutError' ||
17
+ error.name === 'SocketError' ||
18
+ maybeCode === 'UND_ERR_HEADERS_TIMEOUT' ||
19
+ maybeCode === 'UND_ERR_BODY_TIMEOUT' ||
20
+ maybeCode === 'UND_ERR_CONNECT_TIMEOUT' ||
21
+ maybeCode === 'UND_ERR_SOCKET' ||
22
+ maybeCode === 'ENOTFOUND' ||
23
+ maybeCode === 'EAI_AGAIN' ||
24
+ maybeCode === 'ECONNRESET' ||
25
+ maybeCode === 'ECONNREFUSED' ||
26
+ maybeCode === 'ETIMEDOUT' ||
27
+ maybeCode === 'EPIPE');
28
+ };
29
+ exports.isTransientNetworkError = isTransientNetworkError;
30
+ //# sourceMappingURL=retry.js.map
@@ -18,7 +18,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
20
  __exportStar(require("./npm-registry"), exports);
21
- __exportStar(require("./jsdelivr-registry"), exports);
22
21
  __exportStar(require("../features/changelog"), exports);
23
22
  __exportStar(require("./version-checker"), exports);
24
23
  __exportStar(require("./vulnerability-checker"), exports);
@@ -1,42 +1,8 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.fetchPackageVersions = fetchPackageVersions;
37
4
  exports.clearPackageCache = clearPackageCache;
38
5
  exports.closeRegistryPool = closeRegistryPool;
39
- const semver = __importStar(require("semver"));
40
6
  const undici_1 = require("undici");
41
7
  const node_zlib_1 = require("node:zlib");
42
8
  const node_util_1 = require("node:util");
@@ -44,8 +10,10 @@ const gunzipAsync = (0, node_util_1.promisify)(node_zlib_1.gunzip);
44
10
  const inflateAsync = (0, node_util_1.promisify)(node_zlib_1.inflate);
45
11
  const brotliDecompressAsync = (0, node_util_1.promisify)(node_zlib_1.brotliDecompress);
46
12
  const config_1 = require("../config");
47
- const jsdelivr_registry_1 = require("./jsdelivr-registry");
48
- const inFlightLookups = new Map();
13
+ const version_1 = require("../utils/version");
14
+ const retry_1 = require("./http/retry");
15
+ const inflight_1 = require("./http/inflight");
16
+ const inFlightLookups = new inflight_1.InflightMap();
49
17
  const registryOrigin = new URL(config_1.NPM_REGISTRY_URL).origin;
50
18
  const registryPathPrefix = new URL(config_1.NPM_REGISTRY_URL).pathname.replace(/\/$/, '');
51
19
  // Few connections + many requests per connection = maximum keep-alive reuse.
@@ -54,60 +22,18 @@ const registryPathPrefix = new URL(config_1.NPM_REGISTRY_URL).pathname.replace(/
54
22
  const registryPool = new undici_1.Pool(registryOrigin, {
55
23
  connections: 6,
56
24
  pipelining: 1,
57
- keepAliveTimeout: 30000,
58
- keepAliveMaxTimeout: 600000,
25
+ keepAliveTimeout: 30_000,
26
+ keepAliveMaxTimeout: 600_000,
59
27
  headersTimeout: 0,
60
28
  bodyTimeout: 0,
61
- connectTimeout: 15000,
29
+ connectTimeout: 15_000,
62
30
  allowH2: false,
63
31
  });
64
32
  const MAX_REGISTRY_ATTEMPTS = 3;
65
33
  const RETRY_BACKOFF_MS = [500, 1500, 3000];
66
- const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
67
- const isRetryableStatus = (statusCode) => statusCode === 408 || statusCode === 429 || statusCode >= 500;
68
- const isTransientNetworkError = (error) => {
69
- if (!(error instanceof Error)) {
70
- return false;
71
- }
72
- const maybeCode = error.code;
73
- return (error.name === 'AbortError' ||
74
- error.name === 'HeadersTimeoutError' ||
75
- error.name === 'BodyTimeoutError' ||
76
- error.name === 'ConnectTimeoutError' ||
77
- error.name === 'SocketError' ||
78
- maybeCode === 'UND_ERR_HEADERS_TIMEOUT' ||
79
- maybeCode === 'UND_ERR_BODY_TIMEOUT' ||
80
- maybeCode === 'UND_ERR_CONNECT_TIMEOUT' ||
81
- maybeCode === 'UND_ERR_SOCKET' ||
82
- maybeCode === 'ENOTFOUND' ||
83
- maybeCode === 'EAI_AGAIN' ||
84
- maybeCode === 'ECONNRESET' ||
85
- maybeCode === 'ECONNREFUSED' ||
86
- maybeCode === 'ETIMEDOUT' ||
87
- maybeCode === 'EPIPE');
88
- };
89
- const fetchFromJsdelivrFallback = async (packageName, currentVersion) => {
90
- const jsdelivrData = await (0, jsdelivr_registry_1.getAllPackageDataFromJsdelivr)([packageName], currentVersion ? new Map([[packageName, currentVersion]]) : undefined);
91
- return jsdelivrData.get(packageName) ?? { latestVersion: 'unknown', allVersions: [] };
92
- };
93
34
  async function getFreshPackageData(packageName, currentVersion) {
94
35
  const cacheKey = `${packageName}@${currentVersion ?? ''}`;
95
- const inFlight = inFlightLookups.get(cacheKey);
96
- if (inFlight) {
97
- return await inFlight;
98
- }
99
- const lookupPromise = fetchPackageFromRegistryWithFallback(packageName, currentVersion).finally(() => {
100
- inFlightLookups.delete(cacheKey);
101
- });
102
- inFlightLookups.set(cacheKey, lookupPromise);
103
- return await lookupPromise;
104
- }
105
- function parseVersions(raw) {
106
- const data = JSON.parse(raw);
107
- const allVersions = Object.keys(data.versions || {}).filter((v) => /^[0-9]+\.[0-9]+\.[0-9]+$/.test(v));
108
- const sortedVersions = allVersions.sort(semver.rcompare);
109
- const latestVersion = sortedVersions.length > 0 ? sortedVersions[0] : 'unknown';
110
- return { latestVersion, allVersions };
36
+ return inFlightLookups.dedupe(cacheKey, () => fetchPackageFromRegistry(packageName));
111
37
  }
112
38
  const encodeRegistryPath = (packageName) => {
113
39
  const encodedName = packageName.startsWith('@')
@@ -130,7 +56,7 @@ async function attemptRegistryFetch(path) {
130
56
  });
131
57
  if (statusCode < 200 || statusCode >= 300) {
132
58
  await body.dump().catch(() => undefined);
133
- if (isRetryableStatus(statusCode)) {
59
+ if ((0, retry_1.isRetryableStatus)(statusCode)) {
134
60
  return { kind: 'retryable' };
135
61
  }
136
62
  return { kind: 'not-found' };
@@ -153,10 +79,10 @@ async function attemptRegistryFetch(path) {
153
79
  else {
154
80
  decoded = raw;
155
81
  }
156
- return { kind: 'success', data: parseVersions(decoded.toString('utf8')) };
82
+ return { kind: 'success', data: (0, version_1.parseVersions)(decoded.toString('utf8')) };
157
83
  }
158
84
  catch (error) {
159
- if (isTransientNetworkError(error)) {
85
+ if ((0, retry_1.isTransientNetworkError)(error)) {
160
86
  return { kind: 'transient' };
161
87
  }
162
88
  // Unknown error: treat as transient so we try the fallback rather than
@@ -174,24 +100,20 @@ async function fetchFromRegistryWithRetries(path) {
174
100
  lastOutcome = outcome;
175
101
  if (attempt < MAX_REGISTRY_ATTEMPTS - 1) {
176
102
  const backoff = RETRY_BACKOFF_MS[Math.min(attempt, RETRY_BACKOFF_MS.length - 1)];
177
- await sleep(backoff);
103
+ await (0, retry_1.sleep)(backoff);
178
104
  }
179
105
  }
180
106
  return lastOutcome;
181
107
  }
182
- async function fetchPackageFromRegistryWithFallback(packageName, currentVersion) {
108
+ async function fetchPackageFromRegistry(packageName) {
183
109
  const path = encodeRegistryPath(packageName);
184
110
  const outcome = await fetchFromRegistryWithRetries(path);
185
111
  if (outcome.kind === 'success') {
186
112
  return outcome.data;
187
113
  }
188
- if (outcome.kind === 'not-found') {
189
- return { latestVersion: 'unknown', allVersions: [] };
190
- }
191
- // Only reach here after exhausted retries against real errors — try jsdelivr
192
- // as last-resort safety net so we don't silently return 'unknown'.
193
- const fallback = await fetchFromJsdelivrFallback(packageName, currentVersion).catch(() => null);
194
- return fallback ?? { latestVersion: 'unknown', allVersions: [] };
114
+ // Not found, or exhausted retries against real errors: report unavailable.
115
+ // The registry is the single source of truth — there is no secondary fetch.
116
+ return { latestVersion: 'unknown', allVersions: [] };
195
117
  }
196
118
  /**
197
119
  * Fetches version data for a list of packages from the npm registry.
@@ -201,9 +123,10 @@ async function fetchPackageFromRegistryWithFallback(packageName, currentVersion)
201
123
  * It doesn't interact with batch size — batches exist only to group
202
124
  * emissions for the UI.
203
125
  * - No per-request timeouts: slow responses are allowed to finish. Real
204
- * network errors are retried with exponential backoff; after that, we
205
- * fall back to jsdelivr as a last resort. A result is never silently
206
- * dropped due to slowness.
126
+ * network errors are retried with exponential backoff; after the retry
127
+ * budget is exhausted the package is reported as unavailable
128
+ * (`latestVersion: 'unknown'`). A result is never silently dropped due to
129
+ * slowness.
207
130
  *
208
131
  * Callbacks:
209
132
  * - `onBatchReady` fires once a whole emission batch has resolved, in
@@ -56,8 +56,8 @@ class PackageManagerDetector {
56
56
  if (fromLockFile) {
57
57
  return fromLockFile;
58
58
  }
59
- // 3. Fallback to npm
60
- console.log(chalk_1.default.yellow('⚠️ No package manager detected. Defaulting to npm. Consider adding a "packageManager" field to your package.json.'));
59
+ // 3. Fallback to npm. Warn on stderr so it never corrupts --json output on stdout.
60
+ console.error(chalk_1.default.yellow('⚠️ No package manager detected. Defaulting to npm. Consider adding a "packageManager" field to your package.json.'));
61
61
  return PACKAGE_MANAGERS.npm;
62
62
  }
63
63
  /**
@@ -92,6 +92,8 @@ class PackageManagerDetector {
92
92
  const lockFileChecks = [
93
93
  { pm: PACKAGE_MANAGERS.pnpm, path: (0, path_1.join)(cwd, 'pnpm-lock.yaml') },
94
94
  { pm: PACKAGE_MANAGERS.bun, path: (0, path_1.join)(cwd, 'bun.lockb') },
95
+ // Bun >= 1.2 writes a text `bun.lock` instead of the binary `bun.lockb`.
96
+ { pm: PACKAGE_MANAGERS.bun, path: (0, path_1.join)(cwd, 'bun.lock') },
95
97
  { pm: PACKAGE_MANAGERS.yarn, path: (0, path_1.join)(cwd, 'yarn.lock') },
96
98
  { pm: PACKAGE_MANAGERS.npm, path: (0, path_1.join)(cwd, 'package-lock.json') },
97
99
  ];
@@ -107,7 +109,8 @@ class PackageManagerDetector {
107
109
  }
108
110
  // If multiple lock files, use most recently modified
109
111
  if (existingLocks.length > 1) {
110
- console.log(chalk_1.default.yellow('⚠️ Multiple lock files detected. Using most recently modified. Consider cleaning up unused lock files.'));
112
+ // stderr so it never corrupts --json output on stdout.
113
+ console.error(chalk_1.default.yellow('⚠️ Multiple lock files detected. Using most recently modified. Consider cleaning up unused lock files.'));
111
114
  existingLocks.sort((a, b) => b.mtime - a.mtime);
112
115
  }
113
116
  return existingLocks[0].pm;
@@ -7,21 +7,22 @@ exports.persistentCache = void 0;
7
7
  const fs_1 = require("fs");
8
8
  const path_1 = require("path");
9
9
  const env_paths_1 = __importDefault(require("env-paths"));
10
- // Cache TTL: 24 hours for disk cache (much longer than in-memory 5 minutes)
11
- const DISK_CACHE_TTL = 24 * 60 * 60 * 1000;
10
+ const config_1 = require("../config");
12
11
  // Maximum cache size (number of packages)
13
12
  const MAX_CACHE_ENTRIES = 5000;
14
13
  // Cache file format version (increment when structure changes)
15
- const CACHE_VERSION = 1;
14
+ const CACHE_VERSION = 2;
16
15
  /**
17
16
  * Persistent cache manager for package registry data.
18
17
  * Stores cache on disk for fast repeated runs across CLI invocations.
19
18
  */
20
19
  class PersistentCacheManager {
20
+ cacheDir;
21
+ indexPath;
22
+ index = null;
23
+ dirty = false;
21
24
  constructor() {
22
- this.index = null;
23
- this.dirty = false;
24
- const paths = (0, env_paths_1.default)('inup');
25
+ const paths = (0, env_paths_1.default)(config_1.PACKAGE_NAME);
25
26
  this.cacheDir = (0, path_1.join)(paths.cache, 'registry');
26
27
  this.indexPath = (0, path_1.join)(this.cacheDir, 'index.json');
27
28
  }
@@ -93,13 +94,6 @@ class PersistentCacheManager {
93
94
  if (!entry) {
94
95
  return null;
95
96
  }
96
- // Check TTL
97
- if (Date.now() - entry.timestamp > DISK_CACHE_TTL) {
98
- // Expired, remove from index
99
- delete index.entries[packageName];
100
- this.dirty = true;
101
- return null;
102
- }
103
97
  // Read the actual cache file
104
98
  try {
105
99
  const filePath = (0, path_1.join)(this.cacheDir, entry.file);
@@ -113,6 +107,7 @@ class PersistentCacheManager {
113
107
  return {
114
108
  latestVersion: cached.latestVersion,
115
109
  allVersions: cached.allVersions,
110
+ timestamp: entry.timestamp,
116
111
  };
117
112
  }
118
113
  catch {
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=domain.js.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=ui.js.map
package/dist/types.js CHANGED
@@ -1,3 +1,20 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types/domain"), exports);
18
+ __exportStar(require("./types/ui"), exports);
19
+ __exportStar(require("./types/streaming"), exports);
3
20
  //# sourceMappingURL=types.js.map
@@ -38,12 +38,10 @@ const semver = __importStar(require("semver"));
38
38
  const services_1 = require("../../services");
39
39
  const RELEASE_NOTES_LOAD_DEBOUNCE_MS = 120;
40
40
  class PackageInfoModalController {
41
- constructor() {
42
- this.abortController = null;
43
- this.pendingReleaseNotesVersion = null;
44
- this.releaseNotesDebounceTimer = null;
45
- this.resolveDebouncedLoad = null;
46
- }
41
+ abortController = null;
42
+ pendingReleaseNotesVersion = null;
43
+ releaseNotesDebounceTimer = null;
44
+ resolveDebouncedLoad = null;
47
45
  /**
48
46
  * Cancel any in-flight hydrate/release-notes fetches.
49
47
  * Safe to call multiple times or when nothing is in flight.
@@ -68,32 +66,11 @@ class PackageInfoModalController {
68
66
  if (!metadata) {
69
67
  return null;
70
68
  }
71
- const result = {
72
- description: metadata.description,
73
- homepage: metadata.homepage,
74
- repository: metadata.releaseNotes,
75
- weeklyDownloads: metadata.weeklyDownloads,
76
- author: metadata.author,
77
- license: metadata.license,
78
- };
79
- state.description = result.description;
80
- state.homepage = result.homepage;
81
- state.repository = result.repository;
82
- state.weeklyDownloads = result.weeklyDownloads;
83
- state.author = result.author;
84
- state.license = result.license;
85
69
  // Compute the version range for release notes
86
70
  const targetVersion = state.selectedOption === 'range' ? state.rangeVersion : state.latestVersion;
87
- if (state.allVersions && state.allVersions.length > 0) {
88
- state.releaseNotesVersions = this.buildReleaseNotesVersionQueue(state.allVersions, state.currentVersion, targetVersion);
89
- }
90
- else {
91
- // No allVersions available — just show the target version
92
- state.releaseNotesVersions = [targetVersion];
93
- }
94
- state.releaseNotesLoaded = new Map();
95
- state.releaseNotesViewIndex = 0;
96
- state.releaseNotesLoadingVersion = undefined;
71
+ const releaseNotesVersions = state.allVersions && state.allVersions.length > 0
72
+ ? this.buildReleaseNotesVersionQueue(state.allVersions, state.currentVersion, targetVersion)
73
+ : [targetVersion];
97
74
  this.pendingReleaseNotesVersion = null;
98
75
  if (this.releaseNotesDebounceTimer) {
99
76
  clearTimeout(this.releaseNotesDebounceTimer);
@@ -101,7 +78,21 @@ class PackageInfoModalController {
101
78
  }
102
79
  this.resolveDebouncedLoad?.(false);
103
80
  this.resolveDebouncedLoad = null;
104
- return result;
81
+ return {
82
+ name: state.name,
83
+ patch: {
84
+ description: metadata.description,
85
+ homepage: metadata.homepage,
86
+ repository: metadata.releaseNotes,
87
+ weeklyDownloads: metadata.weeklyDownloads,
88
+ author: metadata.author,
89
+ license: metadata.license,
90
+ releaseNotesVersions,
91
+ releaseNotesLoaded: new Map(),
92
+ releaseNotesViewIndex: 0,
93
+ releaseNotesLoadingVersion: undefined,
94
+ },
95
+ };
105
96
  }
106
97
  /**
107
98
  * Load release notes for a specific version by index.
@@ -4,11 +4,9 @@ exports.VulnerabilityAuditController = void 0;
4
4
  const services_1 = require("../../services");
5
5
  const vulnerability_1 = require("../presenters/vulnerability");
6
6
  class VulnerabilityAuditController {
7
- constructor() {
8
- this.tracker = new services_1.BackgroundAuditTracker();
9
- this.cache = new Map();
10
- this.drainPromise = null;
11
- }
7
+ tracker = new services_1.BackgroundAuditTracker();
8
+ cache = new Map();
9
+ drainPromise = null;
12
10
  getCachedSummary(packageName, currentVersionSpecifier, type) {
13
11
  return this.cache.get(this.getCacheKey(packageName, currentVersionSpecifier, type));
14
12
  }
@@ -25,16 +23,18 @@ class VulnerabilityAuditController {
25
23
  this.drain(selectionStates, onUpdate);
26
24
  }
27
25
  }
28
- drain(selectionStates, onUpdate) {
26
+ async drain(selectionStates, onUpdate) {
29
27
  if (this.drainPromise) {
30
- return;
28
+ return [];
31
29
  }
30
+ const allUpdates = [];
32
31
  this.drainPromise = (async () => {
33
32
  while (true) {
34
33
  const batch = this.tracker.reserveNextBatch(20);
35
34
  if (batch.packageNames.length === 0) {
36
35
  break;
37
36
  }
37
+ const batchUpdates = [];
38
38
  try {
39
39
  const vulnerabilityData = await (0, services_1.fetchVulnerabilities)(batch.packages);
40
40
  const batchNames = new Set(batch.packageNames);
@@ -55,8 +55,8 @@ class VulnerabilityAuditController {
55
55
  url: item.url,
56
56
  })), vulnerability.highestSeverity);
57
57
  const merged = (0, vulnerability_1.mergeVulnerabilitySummary)(state.vulnerability, summary);
58
- state.vulnerability = merged;
59
58
  this.cache.set(this.getCacheKey(state.name, state.currentVersionSpecifier, state.type), merged);
59
+ batchUpdates.push({ name: state.name, patch: { vulnerability: merged } });
60
60
  }
61
61
  }
62
62
  catch {
@@ -64,6 +64,13 @@ class VulnerabilityAuditController {
64
64
  }
65
65
  finally {
66
66
  this.tracker.markCompleted(batch.packageNames);
67
+ for (const update of batchUpdates) {
68
+ for (const state of selectionStates) {
69
+ if (state.name === update.name)
70
+ Object.assign(state, update.patch);
71
+ }
72
+ }
73
+ allUpdates.push(...batchUpdates);
67
74
  onUpdate?.();
68
75
  }
69
76
  }
@@ -73,6 +80,8 @@ class VulnerabilityAuditController {
73
80
  this.drain(selectionStates, onUpdate);
74
81
  }
75
82
  });
83
+ await this.drainPromise;
84
+ return allUpdates;
76
85
  }
77
86
  getCacheKey(packageName, currentVersionSpecifier, type) {
78
87
  return `${packageName}@${currentVersionSpecifier}@${type}`;
package/dist/ui/index.js CHANGED
@@ -21,4 +21,7 @@ __exportStar(require("./modal"), exports);
21
21
  __exportStar(require("./presenters"), exports);
22
22
  __exportStar(require("./controllers"), exports);
23
23
  __exportStar(require("./input-handler"), exports);
24
+ __exportStar(require("./keymap"), exports);
25
+ __exportStar(require("./themes"), exports);
26
+ __exportStar(require("./themes-colors"), exports);
24
27
  //# sourceMappingURL=index.js.map