inup 1.6.6 → 1.6.8
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 +25 -2
- package/dist/{interactive-ui.js → app/interactive-ui.js} +34 -21
- package/dist/{core → app}/upgrade-runner.js +18 -22
- package/dist/cli.js +19 -18
- package/dist/{services → features/audit}/background-audit.js +2 -2
- package/dist/features/{headless/vulnerability-audit.js → audit/headless-audit.js} +8 -11
- package/dist/features/audit/index.js +36 -0
- package/dist/{ui/presenters/vulnerability.js → features/audit/presenter.js} +1 -3
- package/dist/{ui/controllers → features/audit}/vulnerability-audit-controller.js +14 -8
- package/dist/{services → features/audit}/vulnerability-checker.js +9 -10
- package/dist/features/changelog/clients/github-client.js +41 -21
- package/dist/features/changelog/clients/npm-registry-client.js +16 -2
- package/dist/features/changelog/index.js +1 -1
- package/dist/features/changelog/services/package-metadata-service.js +6 -2
- package/dist/features/changelog/services/release-notes-service.js +9 -12
- package/dist/features/changelog/types.js +3 -0
- package/dist/features/debug/index.js +3 -4
- package/dist/features/debug/{services/perf-logger.js → perf-logger.js} +15 -15
- package/dist/features/debug/types.js +3 -0
- package/dist/features/headless/headless-runner.js +32 -19
- package/dist/features/headless/index.js +2 -5
- package/dist/features/headless/report.js +2 -0
- package/dist/features/interactive/controllers/index.js +6 -0
- package/dist/{ui → features/interactive}/controllers/package-info-modal-controller.js +3 -3
- package/dist/features/interactive/index.js +21 -0
- package/dist/{ui → features/interactive}/input-handler.js +6 -6
- package/dist/{ui → features/interactive}/modal/index.js +1 -1
- package/dist/{ui → features/interactive}/modal/layout.js +5 -5
- package/dist/{ui/renderer/package-list.js → features/interactive/modal/package-info-sections/index.js} +3 -3
- package/dist/{ui → features/interactive}/modal/package-info-sections/release-notes.js +1 -1
- package/dist/{ui → features/interactive}/modal/package-info-sections/sections.js +55 -24
- package/dist/{ui → features/interactive}/modal/package-info-sections/text.js +6 -6
- package/dist/{ui → features/interactive}/modal/package-info.js +33 -18
- package/dist/features/interactive/modal/types.js +3 -0
- package/dist/{ui → features/interactive}/presenters/health.js +2 -2
- package/dist/{ui → features/interactive}/renderer/confirmation.js +6 -3
- package/dist/{ui → features/interactive}/renderer/help-modal.js +3 -3
- package/dist/{ui → features/interactive}/renderer/index.js +3 -4
- package/dist/{types.js → features/interactive/renderer/package-list/index.js} +3 -4
- package/dist/{ui → features/interactive}/renderer/package-list/interface.js +15 -16
- package/dist/{ui → features/interactive}/renderer/package-list/rows.js +31 -25
- package/dist/features/{debug → interactive}/renderer/performance-modal.js +3 -3
- package/dist/{ui/utils/version.js → features/interactive/renderer/version-format.js} +9 -13
- package/dist/{ui → features/interactive}/session/action-dispatcher.js +2 -2
- package/dist/{ui → features/interactive}/session/index.js +5 -4
- package/dist/{ui → features/interactive}/session/interactive-session.js +44 -23
- package/dist/{ui → features/interactive}/session/selection-state-builder.js +25 -9
- package/dist/{ui → features/interactive}/state/filter-manager.js +3 -3
- package/dist/{ui → features/interactive}/state/index.js +7 -7
- package/dist/{ui → features/interactive}/state/state-manager.js +10 -8
- package/dist/{ui → features/interactive}/state/theme-manager.js +7 -5
- package/dist/{ui → features/interactive}/themes-colors.js +3 -1
- package/dist/features/upgrade/index.js +8 -0
- package/dist/{core → features/upgrade}/package-detector.js +96 -37
- package/dist/{core → features/upgrade}/upgrader.js +84 -35
- package/dist/index.js +2 -2
- package/dist/{config → shared/config}/package-meta.js +1 -1
- package/dist/{config → shared/config}/project-config.js +10 -8
- package/dist/{utils/config.js → shared/config/user-config.js} +11 -11
- package/dist/{utils → shared}/debug-logger.js +9 -9
- package/dist/{utils → shared}/exec.js +4 -4
- package/dist/{ui/modal/package-info-sections.js → shared/fs/index.js} +4 -3
- package/dist/{utils/filesystem → shared/fs}/io.js +3 -4
- package/dist/shared/fs/paths.js +19 -0
- package/dist/{utils/filesystem → shared/fs}/scan.js +23 -20
- package/dist/{utils → shared}/git.js +3 -3
- package/dist/{services → shared}/http/etag-store.js +56 -4
- package/dist/{services → shared}/http/resizable-semaphore.js +3 -1
- package/dist/{utils → shared}/local-env.js +8 -8
- package/dist/{services/package-manager-detector.js → shared/package-manager.js} +26 -25
- package/dist/shared/pnpm-catalogs.js +138 -0
- package/dist/{services → shared/registry}/npm-registry.js +54 -33
- package/dist/shared/registry/registry-config.js +76 -0
- package/dist/{services → shared/registry}/version-checker.js +25 -26
- package/dist/{ui/utils → shared/terminal}/cursor.js +1 -1
- package/dist/{ui/utils → shared/terminal}/index.js +5 -7
- package/dist/{ui/utils → shared/terminal}/terminal-input.js +5 -0
- package/dist/shared/terminal/text.js +48 -0
- package/dist/shared/types/index.js +20 -0
- package/dist/{utils/version.js → shared/versions.js} +45 -30
- package/package.json +21 -8
- package/dist/core/index.js +0 -23
- package/dist/features/changelog/types/changelog.types.js +0 -3
- package/dist/features/debug/types/debug.types.js +0 -3
- package/dist/services/index.js +0 -25
- package/dist/ui/controllers/index.js +0 -8
- package/dist/ui/index.js +0 -27
- package/dist/ui/presenters/index.js +0 -11
- package/dist/ui/utils/text.js +0 -76
- package/dist/utils/filesystem/paths.js +0 -19
- package/dist/utils/filesystem.js +0 -20
- package/dist/utils/index.js +0 -34
- /package/dist/{ui/modal → features/audit}/types.js +0 -0
- /package/dist/features/debug/{services/performance-tracker.js → performance-tracker.js} +0 -0
- /package/dist/{ui → features/interactive}/keymap.js +0 -0
- /package/dist/{ui → features/interactive}/modal/theme-selector.js +0 -0
- /package/dist/{ui → features/interactive}/state/modal-manager.js +0 -0
- /package/dist/{ui → features/interactive}/state/navigation-manager.js +0 -0
- /package/dist/{ui → features/interactive}/themes.js +0 -0
- /package/dist/{config → shared/config}/constants.js +0 -0
- /package/dist/{config → shared/config}/index.js +0 -0
- /package/dist/{utils → shared}/engines.js +0 -0
- /package/dist/{services → shared}/http/adaptive-controller.js +0 -0
- /package/dist/{services → shared}/http/inflight.js +0 -0
- /package/dist/{services → shared}/http/retry.js +0 -0
- /package/dist/{utils → shared}/manifest.js +0 -0
- /package/dist/{utils → shared/terminal}/color.js +0 -0
- /package/dist/{types → shared/types}/domain.js +0 -0
- /package/dist/{types → shared/types}/streaming.js +0 -0
- /package/dist/{types → shared/types}/ui.js +0 -0
|
@@ -1,9 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GitHubClient = void 0;
|
|
4
|
+
const config_1 = require("../../../shared/config");
|
|
4
5
|
const repository_ref_1 = require("../parsers/repository-ref");
|
|
5
|
-
const config_1 = require("../../../config");
|
|
6
6
|
const GITHUB_RELEASES_PAGE_LIMIT = 3;
|
|
7
|
+
/**
|
|
8
|
+
* Headers for api.github.com requests. Honors an ambient token (GitHub Actions
|
|
9
|
+
* sets GITHUB_TOKEN, gh CLI users often export GH_TOKEN): authenticated requests
|
|
10
|
+
* get 5,000 req/hr instead of the 60 req/hr anonymous limit, which large upgrade
|
|
11
|
+
* sessions can exhaust while fetching release notes.
|
|
12
|
+
*/
|
|
13
|
+
function githubApiHeaders() {
|
|
14
|
+
const headers = {
|
|
15
|
+
accept: 'application/vnd.github.v3+json',
|
|
16
|
+
'user-agent': `${config_1.PACKAGE_NAME}-cli`,
|
|
17
|
+
};
|
|
18
|
+
const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
|
|
19
|
+
if (token) {
|
|
20
|
+
headers.authorization = `Bearer ${token}`;
|
|
21
|
+
}
|
|
22
|
+
return headers;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* GET an api.github.com URL, retrying anonymously when the ambient token is
|
|
26
|
+
* rejected (401). A stale/revoked GITHUB_TOKEN sitting in the environment must
|
|
27
|
+
* never make release notes *worse* than having no token at all — public-repo
|
|
28
|
+
* requests that used to succeed anonymously keep succeeding.
|
|
29
|
+
*/
|
|
30
|
+
async function fetchGitHubApi(url, signal) {
|
|
31
|
+
const headers = githubApiHeaders();
|
|
32
|
+
const response = await fetch(url, { method: 'GET', headers, signal });
|
|
33
|
+
if (response.status === 401 && headers.authorization) {
|
|
34
|
+
const { authorization: _rejected, ...anonymousHeaders } = headers;
|
|
35
|
+
return fetch(url, { method: 'GET', headers: anonymousHeaders, signal });
|
|
36
|
+
}
|
|
37
|
+
return response;
|
|
38
|
+
}
|
|
7
39
|
class GitHubClient {
|
|
8
40
|
releasesCache = new Map();
|
|
9
41
|
rawChangelogCache = new Map();
|
|
@@ -16,14 +48,7 @@ class GitHubClient {
|
|
|
16
48
|
if (!repo)
|
|
17
49
|
return null;
|
|
18
50
|
try {
|
|
19
|
-
const response = await
|
|
20
|
-
method: 'GET',
|
|
21
|
-
headers: {
|
|
22
|
-
accept: 'application/vnd.github.v3+json',
|
|
23
|
-
'user-agent': `${config_1.PACKAGE_NAME}-cli`,
|
|
24
|
-
},
|
|
25
|
-
signal,
|
|
26
|
-
});
|
|
51
|
+
const response = await fetchGitHubApi(`https://api.github.com/repos/${repo.owner}/${repo.repo}/releases/tags/${tag}`, signal);
|
|
27
52
|
if (!response.ok)
|
|
28
53
|
return null;
|
|
29
54
|
const data = (await response.json());
|
|
@@ -61,20 +86,14 @@ class GitHubClient {
|
|
|
61
86
|
if (!repo)
|
|
62
87
|
return null;
|
|
63
88
|
const cacheKey = `${repo.owner}/${repo.repo}`;
|
|
64
|
-
|
|
65
|
-
|
|
89
|
+
const cached = this.releasesCache.get(cacheKey);
|
|
90
|
+
if (cached !== undefined) {
|
|
91
|
+
return cached;
|
|
66
92
|
}
|
|
67
93
|
const releases = [];
|
|
68
94
|
for (let page = 1; page <= GITHUB_RELEASES_PAGE_LIMIT; page += 1) {
|
|
69
95
|
try {
|
|
70
|
-
const response = await
|
|
71
|
-
method: 'GET',
|
|
72
|
-
headers: {
|
|
73
|
-
accept: 'application/vnd.github.v3+json',
|
|
74
|
-
'user-agent': `${config_1.PACKAGE_NAME}-cli`,
|
|
75
|
-
},
|
|
76
|
-
signal,
|
|
77
|
-
});
|
|
96
|
+
const response = await fetchGitHubApi(`https://api.github.com/repos/${repo.owner}/${repo.repo}/releases?per_page=100&page=${page}`, signal);
|
|
78
97
|
if (!response.ok)
|
|
79
98
|
break;
|
|
80
99
|
const pageReleases = (await response.json());
|
|
@@ -100,8 +119,9 @@ class GitHubClient {
|
|
|
100
119
|
if (!repo)
|
|
101
120
|
return null;
|
|
102
121
|
const cacheKey = `${repo.owner}/${repo.repo}`;
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
const cached = this.rawChangelogCache.get(cacheKey);
|
|
123
|
+
if (cached !== undefined) {
|
|
124
|
+
return cached;
|
|
105
125
|
}
|
|
106
126
|
const branches = ['main', 'master'];
|
|
107
127
|
const filenames = ['CHANGELOG.md', 'CHANGES.md', 'HISTORY.md'];
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NpmRegistryClient = void 0;
|
|
4
|
-
const constants_1 = require("../../../config/constants");
|
|
4
|
+
const constants_1 = require("../../../shared/config/constants");
|
|
5
|
+
const registry_config_1 = require("../../../shared/registry/registry-config");
|
|
6
|
+
const PUBLIC_REGISTRY_ORIGIN = new URL(constants_1.NPM_REGISTRY_URL).origin;
|
|
5
7
|
class NpmRegistryClient {
|
|
8
|
+
resolveRegistryTarget;
|
|
9
|
+
constructor(resolveRegistryTarget = registry_config_1.registryTargetFor) {
|
|
10
|
+
this.resolveRegistryTarget = resolveRegistryTarget;
|
|
11
|
+
}
|
|
6
12
|
async fetchPackageManifest(packageName, version, signal) {
|
|
7
13
|
try {
|
|
8
|
-
const
|
|
14
|
+
const target = this.resolveRegistryTarget(packageName);
|
|
15
|
+
const response = await fetch(`${target.origin}${target.pathPrefix}/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`, {
|
|
9
16
|
method: 'GET',
|
|
10
17
|
headers: {
|
|
11
18
|
accept: 'application/json',
|
|
19
|
+
...(target.authHeader ? { authorization: target.authHeader } : {}),
|
|
12
20
|
},
|
|
13
21
|
signal,
|
|
14
22
|
});
|
|
@@ -25,6 +33,12 @@ class NpmRegistryClient {
|
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
35
|
async fetchDownloadStats(packageName, signal) {
|
|
36
|
+
// Download counts only exist for the public registry. Skip the call for
|
|
37
|
+
// packages that resolve elsewhere — no stats there, and private package
|
|
38
|
+
// names should not be sent to api.npmjs.org.
|
|
39
|
+
if (this.resolveRegistryTarget(packageName).origin !== PUBLIC_REGISTRY_ORIGIN) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
28
42
|
try {
|
|
29
43
|
const response = await fetch(`https://api.npmjs.org/downloads/point/last-week/${encodeURIComponent(packageName)}`, {
|
|
30
44
|
method: 'GET',
|
|
@@ -14,6 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./types/changelog.types"), exports);
|
|
18
17
|
__exportStar(require("./services/changelog-service"), exports);
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PackageMetadataService = void 0;
|
|
4
|
+
const inflight_1 = require("../../../shared/http/inflight");
|
|
4
5
|
const npm_registry_client_1 = require("../clients/npm-registry-client");
|
|
5
6
|
const package_metadata_1 = require("../parsers/package-metadata");
|
|
6
|
-
const inflight_1 = require("../../../services/http/inflight");
|
|
7
7
|
class PackageMetadataService {
|
|
8
8
|
npmRegistryClient;
|
|
9
9
|
cache = new Map();
|
|
@@ -16,7 +16,11 @@ class PackageMetadataService {
|
|
|
16
16
|
this.inFlight.clear();
|
|
17
17
|
}
|
|
18
18
|
getCached(packageName, version) {
|
|
19
|
-
for (const key of [
|
|
19
|
+
for (const key of [
|
|
20
|
+
this.getCacheKey(packageName, version),
|
|
21
|
+
this.getCacheKey(packageName),
|
|
22
|
+
packageName,
|
|
23
|
+
]) {
|
|
20
24
|
if (this.cache.has(key)) {
|
|
21
25
|
return this.cache.get(key) ?? null;
|
|
22
26
|
}
|
|
@@ -39,7 +39,6 @@ const github_client_1 = require("../clients/github-client");
|
|
|
39
39
|
const changelog_parser_1 = require("../parsers/changelog-parser");
|
|
40
40
|
const github_release_html_parser_1 = require("../parsers/github-release-html-parser");
|
|
41
41
|
const RELEASE_NOTES_FETCH_TIMEOUT_MS = 5000;
|
|
42
|
-
const PREFER_GITHUB_RELEASE_PAGE = true;
|
|
43
42
|
class ReleaseNotesService {
|
|
44
43
|
metadataService;
|
|
45
44
|
githubClient;
|
|
@@ -56,8 +55,9 @@ class ReleaseNotesService {
|
|
|
56
55
|
}
|
|
57
56
|
async fetchReleaseNotesForVersion(packageName, version, signal) {
|
|
58
57
|
const cacheKey = `release-notes:${packageName}@${version}`;
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const cached = this.releaseNotesCache.get(cacheKey);
|
|
59
|
+
if (cached !== undefined) {
|
|
60
|
+
return cached;
|
|
61
61
|
}
|
|
62
62
|
const inFlight = this.releaseNotesInFlight.get(cacheKey);
|
|
63
63
|
if (inFlight) {
|
|
@@ -91,15 +91,12 @@ class ReleaseNotesService {
|
|
|
91
91
|
return null;
|
|
92
92
|
}
|
|
93
93
|
getGitHubSources(repoUrl, version, signal) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
() => this.fetchGitHubReleaseNotes(repoUrl, version, signal),
|
|
101
|
-
() => this.fetchGitHubReleasePageNotes(repoUrl, version, signal),
|
|
102
|
-
];
|
|
94
|
+
// Scraped release page first (richer content than the API body), then the
|
|
95
|
+
// release API by tag.
|
|
96
|
+
const directReleaseSources = [
|
|
97
|
+
() => this.fetchGitHubReleasePageNotes(repoUrl, version, signal),
|
|
98
|
+
() => this.fetchGitHubReleaseNotes(repoUrl, version, signal),
|
|
99
|
+
];
|
|
103
100
|
return [
|
|
104
101
|
...directReleaseSources,
|
|
105
102
|
() => this.fetchGitHubReleaseListNotes(repoUrl, version, signal),
|
|
@@ -14,8 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./
|
|
20
|
-
__exportStar(require("./renderer/performance-modal"), exports);
|
|
17
|
+
__exportStar(require("./perf-logger"), exports);
|
|
18
|
+
__exportStar(require("./performance-tracker"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
21
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -4,9 +4,9 @@ exports.isPerfLoggingEnabled = isPerfLoggingEnabled;
|
|
|
4
4
|
exports.perfEnv = perfEnv;
|
|
5
5
|
exports.getPerfDir = getPerfDir;
|
|
6
6
|
exports.writePerfLog = writePerfLog;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const adaptive_controller_1 = require("
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const adaptive_controller_1 = require("../../shared/http/adaptive-controller");
|
|
10
10
|
/**
|
|
11
11
|
* Performance debug logger.
|
|
12
12
|
*
|
|
@@ -27,7 +27,7 @@ const adaptive_controller_1 = require("../../../services/http/adaptive-controlle
|
|
|
27
27
|
const PERF_DIR_NAME = '.inup-perf';
|
|
28
28
|
/** Filesystem-safe slug of a project name for use in filenames. */
|
|
29
29
|
function projectSlug(cwd) {
|
|
30
|
-
const name = (0,
|
|
30
|
+
const name = (0, node_path_1.basename)((0, node_path_1.resolve)(cwd)) || 'root';
|
|
31
31
|
return name.replace(/[^a-zA-Z0-9._-]/g, '-').slice(0, 40);
|
|
32
32
|
}
|
|
33
33
|
function isPerfLoggingEnabled() {
|
|
@@ -53,12 +53,12 @@ function perfEnv() {
|
|
|
53
53
|
function getPerfDir(cwd = process.cwd()) {
|
|
54
54
|
const override = process.env.INUP_PERF_DIR;
|
|
55
55
|
const dir = override
|
|
56
|
-
? (0,
|
|
56
|
+
? (0, node_path_1.isAbsolute)(override)
|
|
57
57
|
? override
|
|
58
|
-
: (0,
|
|
59
|
-
: (0,
|
|
60
|
-
if (!(0,
|
|
61
|
-
(0,
|
|
58
|
+
: (0, node_path_1.resolve)(cwd, override)
|
|
59
|
+
: (0, node_path_1.join)(cwd, PERF_DIR_NAME);
|
|
60
|
+
if (!(0, node_fs_1.existsSync)(dir)) {
|
|
61
|
+
(0, node_fs_1.mkdirSync)(dir, { recursive: true });
|
|
62
62
|
}
|
|
63
63
|
return dir;
|
|
64
64
|
}
|
|
@@ -92,10 +92,10 @@ function writePerfLog(config, snapshot) {
|
|
|
92
92
|
// Project name in the filename keeps multi-project runs distinct when many
|
|
93
93
|
// collect into one centralized INUP_PERF_DIR.
|
|
94
94
|
const fileName = `run-${fileStamp(now)}-${projectSlug(config.cwd)}-${adaptiveTag}-${modeTag}.json`;
|
|
95
|
-
const filePath = (0,
|
|
96
|
-
(0,
|
|
95
|
+
const filePath = (0, node_path_1.join)(dir, fileName);
|
|
96
|
+
(0, node_fs_1.writeFileSync)(filePath, JSON.stringify(record, null, 2));
|
|
97
97
|
// Maintain a stable pointer to the most recent run for quick reads.
|
|
98
|
-
(0,
|
|
98
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, 'latest.json'), JSON.stringify(record, null, 2));
|
|
99
99
|
// And a cheap one-line-per-run index for fast scanning.
|
|
100
100
|
appendPerfIndex(dir, record);
|
|
101
101
|
if (process.env.INUP_DEBUG === '1') {
|
|
@@ -111,7 +111,7 @@ function writePerfLog(config, snapshot) {
|
|
|
111
111
|
/** Append a single line to a NDJSON index for ultra-cheap scanning, best-effort. */
|
|
112
112
|
function appendPerfIndex(dir, record) {
|
|
113
113
|
try {
|
|
114
|
-
const line = JSON.stringify({
|
|
114
|
+
const line = `${JSON.stringify({
|
|
115
115
|
timestamp: record.timestamp,
|
|
116
116
|
wallMs: record.wallMs,
|
|
117
117
|
adaptive: record.config.adaptive,
|
|
@@ -119,8 +119,8 @@ function appendPerfIndex(dir, record) {
|
|
|
119
119
|
uniquePackages: record.snapshot.counts.uniquePackages,
|
|
120
120
|
registryFetch: record.snapshot.phases.registryFetch,
|
|
121
121
|
controlTicks: record.snapshot.controlTicks.length,
|
|
122
|
-
})
|
|
123
|
-
(0,
|
|
122
|
+
})}\n`;
|
|
123
|
+
(0, node_fs_1.appendFileSync)((0, node_path_1.join)(dir, 'index.ndjson'), line);
|
|
124
124
|
}
|
|
125
125
|
catch {
|
|
126
126
|
/* best-effort */
|
|
@@ -5,13 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.HeadlessRunner = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const package_detector_1 = require("../../core/package-detector");
|
|
9
|
-
const upgrader_1 = require("../../core/upgrader");
|
|
10
|
-
const package_manager_detector_1 = require("../../services/package-manager-detector");
|
|
11
|
-
const version_1 = require("../../ui/utils/version");
|
|
12
|
-
const vulnerability_audit_1 = require("./vulnerability-audit");
|
|
13
|
-
const report_1 = require("./report");
|
|
14
8
|
const debug_1 = require("../../features/debug");
|
|
9
|
+
const package_manager_1 = require("../../shared/package-manager");
|
|
10
|
+
const versions_1 = require("../../shared/versions");
|
|
11
|
+
const audit_1 = require("../audit");
|
|
12
|
+
const upgrade_1 = require("../upgrade");
|
|
13
|
+
const report_1 = require("./report");
|
|
15
14
|
/**
|
|
16
15
|
* Non-interactive entry point. Resolves the outdated list without rendering the TUI, then either
|
|
17
16
|
* emits a JSON report (--json) or a plain line-based report. With --check, sets a non-zero exit
|
|
@@ -26,7 +25,7 @@ class HeadlessRunner {
|
|
|
26
25
|
options;
|
|
27
26
|
constructor(options) {
|
|
28
27
|
this.options = options;
|
|
29
|
-
this.detector = new
|
|
28
|
+
this.detector = new upgrade_1.PackageDetector(options);
|
|
30
29
|
}
|
|
31
30
|
async run(options) {
|
|
32
31
|
try {
|
|
@@ -52,7 +51,7 @@ class HeadlessRunner {
|
|
|
52
51
|
}
|
|
53
52
|
// Audit the current versions (one bulk request, best-effort) and cross-reference each
|
|
54
53
|
// advisory against the upgrade targets, so the report says whether upgrading *fixes* it.
|
|
55
|
-
const vulnerabilities = await (0,
|
|
54
|
+
const vulnerabilities = await (0, audit_1.auditVulnerabilities)(outdated);
|
|
56
55
|
// Build the report from the *pre-apply* outdated set: it describes what this run addressed.
|
|
57
56
|
const report = (0, report_1.buildHeadlessReport)(packages, outdated, vulnerabilities);
|
|
58
57
|
// --apply writes the bumps + lockfile. The scan above already honored .inuprc
|
|
@@ -89,48 +88,62 @@ class HeadlessRunner {
|
|
|
89
88
|
const packageManager = this.resolvePackageManager();
|
|
90
89
|
// With --json, run the upgrader quietly: its own progress + the install child's stdout go to
|
|
91
90
|
// stderr, leaving stdout for the JSON document only.
|
|
92
|
-
const upgrader = new
|
|
91
|
+
const upgrader = new upgrade_1.PackageUpgrader(packageManager, { quiet: json });
|
|
93
92
|
await upgrader.upgradePackages(choices, outdated);
|
|
94
93
|
}
|
|
95
94
|
/**
|
|
96
95
|
* Build `PackageUpgradeChoice[]` from the outdated set per the version policy. Mirrors
|
|
97
96
|
* `createUpgradeChoices` in the TUI: preserves the original range prefix (^/~) unless --save-exact.
|
|
98
97
|
*
|
|
99
|
-
* - minor
|
|
98
|
+
* - minor: take the in-range target (`rangeVersion`); skip packages whose only update is a
|
|
100
99
|
* major (no in-range bump). Uses upgradeType 'range'.
|
|
100
|
+
* - patch: take the highest patch in the current major.minor line; skip packages whose only
|
|
101
|
+
* update crosses a minor (or major) boundary. Uses upgradeType 'range'.
|
|
101
102
|
* - latest: take `latestVersion`; uses upgradeType 'latest' (majors included).
|
|
102
103
|
*/
|
|
103
104
|
buildChoices(outdated, target) {
|
|
104
105
|
const saveExact = this.options?.saveExact ?? false;
|
|
105
106
|
const choices = [];
|
|
106
107
|
for (const pkg of outdated) {
|
|
107
|
-
const
|
|
108
|
-
// minor/patch only act on packages with an in-range bump; major-only updates are skipped.
|
|
109
|
-
if (!useLatest && !pkg.hasRangeUpdate)
|
|
110
|
-
continue;
|
|
111
|
-
const targetVersion = useLatest ? pkg.latestVersion : pkg.rangeVersion;
|
|
108
|
+
const targetVersion = this.resolveTargetVersion(pkg, target);
|
|
112
109
|
if (!targetVersion)
|
|
113
110
|
continue;
|
|
114
111
|
const targetVersionWithPrefix = saveExact
|
|
115
112
|
? targetVersion
|
|
116
|
-
: (0,
|
|
113
|
+
: (0, versions_1.applyVersionPrefix)(pkg.currentVersion, targetVersion);
|
|
117
114
|
choices.push({
|
|
118
115
|
name: pkg.name,
|
|
119
116
|
packageJsonPath: pkg.packageJsonPath,
|
|
120
117
|
dependencyType: pkg.type,
|
|
121
|
-
upgradeType:
|
|
118
|
+
upgradeType: target === 'latest' ? 'latest' : 'range',
|
|
122
119
|
targetVersion: targetVersionWithPrefix,
|
|
123
120
|
currentVersionSpecifier: pkg.currentVersion,
|
|
121
|
+
catalog: pkg.catalog,
|
|
124
122
|
});
|
|
125
123
|
}
|
|
126
124
|
return choices;
|
|
127
125
|
}
|
|
126
|
+
/** Resolve the version a package should be bumped to under the given policy, or null to skip. */
|
|
127
|
+
resolveTargetVersion(pkg, target) {
|
|
128
|
+
if (target === 'latest') {
|
|
129
|
+
return pkg.latestVersion || null;
|
|
130
|
+
}
|
|
131
|
+
if (target === 'patch') {
|
|
132
|
+
// Strictly patch-level: computed from the full version list, not `rangeVersion` (which may
|
|
133
|
+
// be a minor bump). Null when the only updates cross a minor boundary.
|
|
134
|
+
return (0, versions_1.findHighestPatchVersion)(pkg.currentVersion, pkg.allVersions ?? []);
|
|
135
|
+
}
|
|
136
|
+
// minor: in-range bump only; major-only updates are skipped.
|
|
137
|
+
if (!pkg.hasRangeUpdate)
|
|
138
|
+
return null;
|
|
139
|
+
return pkg.rangeVersion || null;
|
|
140
|
+
}
|
|
128
141
|
/** Resolve the package manager the same way the interactive runner does. */
|
|
129
142
|
resolvePackageManager() {
|
|
130
143
|
const cwd = this.options?.cwd || process.cwd();
|
|
131
144
|
return this.options?.packageManager
|
|
132
|
-
?
|
|
133
|
-
:
|
|
145
|
+
? package_manager_1.PackageManagerDetector.getInfo(this.options.packageManager)
|
|
146
|
+
: package_manager_1.PackageManagerDetector.detect(cwd);
|
|
134
147
|
}
|
|
135
148
|
}
|
|
136
149
|
exports.HeadlessRunner = HeadlessRunner;
|
|
@@ -14,14 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.renderPlainReport = exports.buildHeadlessReport = exports.
|
|
18
|
-
__exportStar(require("./types"), exports);
|
|
17
|
+
exports.renderPlainReport = exports.buildHeadlessReport = exports.HeadlessRunner = void 0;
|
|
19
18
|
var headless_runner_1 = require("./headless-runner");
|
|
20
19
|
Object.defineProperty(exports, "HeadlessRunner", { enumerable: true, get: function () { return headless_runner_1.HeadlessRunner; } });
|
|
21
|
-
var vulnerability_audit_1 = require("./vulnerability-audit");
|
|
22
|
-
Object.defineProperty(exports, "auditVulnerabilities", { enumerable: true, get: function () { return vulnerability_audit_1.auditVulnerabilities; } });
|
|
23
|
-
Object.defineProperty(exports, "upgradeClears", { enumerable: true, get: function () { return vulnerability_audit_1.upgradeClears; } });
|
|
24
20
|
var report_1 = require("./report");
|
|
25
21
|
Object.defineProperty(exports, "buildHeadlessReport", { enumerable: true, get: function () { return report_1.buildHeadlessReport; } });
|
|
26
22
|
Object.defineProperty(exports, "renderPlainReport", { enumerable: true, get: function () { return report_1.renderPlainReport; } });
|
|
23
|
+
__exportStar(require("./types"), exports);
|
|
27
24
|
//# sourceMappingURL=index.js.map
|
|
@@ -23,6 +23,8 @@ function buildHeadlessReport(all, outdated, vulnerabilities) {
|
|
|
23
23
|
packageJsonPath: pkg.packageJsonPath,
|
|
24
24
|
hasMajorUpdate: pkg.hasMajorUpdate,
|
|
25
25
|
};
|
|
26
|
+
if (pkg.catalog)
|
|
27
|
+
entry.catalog = pkg.catalog;
|
|
26
28
|
if (pkg.deprecated)
|
|
27
29
|
entry.deprecated = pkg.deprecated;
|
|
28
30
|
if (pkg.enginesNode)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PackageInfoModalController = void 0;
|
|
4
|
+
var package_info_modal_controller_1 = require("./package-info-modal-controller");
|
|
5
|
+
Object.defineProperty(exports, "PackageInfoModalController", { enumerable: true, get: function () { return package_info_modal_controller_1.PackageInfoModalController; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -35,7 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.PackageInfoModalController = void 0;
|
|
37
37
|
const semver = __importStar(require("semver"));
|
|
38
|
-
const
|
|
38
|
+
const changelog_1 = require("../../changelog");
|
|
39
39
|
const RELEASE_NOTES_LOAD_DEBOUNCE_MS = 120;
|
|
40
40
|
class PackageInfoModalController {
|
|
41
41
|
abortController = null;
|
|
@@ -62,7 +62,7 @@ class PackageInfoModalController {
|
|
|
62
62
|
this.cancel();
|
|
63
63
|
const controller = new AbortController();
|
|
64
64
|
this.abortController = controller;
|
|
65
|
-
const metadata = await
|
|
65
|
+
const metadata = await changelog_1.changelogFetcher.fetchPackageMetadata(state.name, state.latestVersion, controller.signal);
|
|
66
66
|
if (!metadata) {
|
|
67
67
|
return null;
|
|
68
68
|
}
|
|
@@ -142,7 +142,7 @@ class PackageInfoModalController {
|
|
|
142
142
|
state.releaseNotesLoadingVersion = version;
|
|
143
143
|
onLoaded(); // Re-render to show loading indicator
|
|
144
144
|
try {
|
|
145
|
-
const notes = await
|
|
145
|
+
const notes = await changelog_1.changelogFetcher.fetchReleaseNotesForVersion(state.name, version, this.abortController?.signal);
|
|
146
146
|
loadedNotes.set(version, notes);
|
|
147
147
|
return true;
|
|
148
148
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StateManager = exports.selectionKey = exports.runInteractiveSession = exports.createUpgradeChoices = exports.createSelectionStates = exports.createPendingSelectionStates = exports.UIRenderer = exports.renderReadmeKeyTable = exports.InputHandler = exports.ConfirmationInputHandler = exports.PackageInfoModalController = void 0;
|
|
4
|
+
var controllers_1 = require("./controllers");
|
|
5
|
+
Object.defineProperty(exports, "PackageInfoModalController", { enumerable: true, get: function () { return controllers_1.PackageInfoModalController; } });
|
|
6
|
+
var input_handler_1 = require("./input-handler");
|
|
7
|
+
Object.defineProperty(exports, "ConfirmationInputHandler", { enumerable: true, get: function () { return input_handler_1.ConfirmationInputHandler; } });
|
|
8
|
+
Object.defineProperty(exports, "InputHandler", { enumerable: true, get: function () { return input_handler_1.InputHandler; } });
|
|
9
|
+
var keymap_1 = require("./keymap");
|
|
10
|
+
Object.defineProperty(exports, "renderReadmeKeyTable", { enumerable: true, get: function () { return keymap_1.renderReadmeKeyTable; } });
|
|
11
|
+
var renderer_1 = require("./renderer");
|
|
12
|
+
Object.defineProperty(exports, "UIRenderer", { enumerable: true, get: function () { return renderer_1.UIRenderer; } });
|
|
13
|
+
var session_1 = require("./session");
|
|
14
|
+
Object.defineProperty(exports, "createPendingSelectionStates", { enumerable: true, get: function () { return session_1.createPendingSelectionStates; } });
|
|
15
|
+
Object.defineProperty(exports, "createSelectionStates", { enumerable: true, get: function () { return session_1.createSelectionStates; } });
|
|
16
|
+
Object.defineProperty(exports, "createUpgradeChoices", { enumerable: true, get: function () { return session_1.createUpgradeChoices; } });
|
|
17
|
+
Object.defineProperty(exports, "runInteractiveSession", { enumerable: true, get: function () { return session_1.runInteractiveSession; } });
|
|
18
|
+
Object.defineProperty(exports, "selectionKey", { enumerable: true, get: function () { return session_1.selectionKey; } });
|
|
19
|
+
var state_1 = require("./state");
|
|
20
|
+
Object.defineProperty(exports, "StateManager", { enumerable: true, get: function () { return state_1.StateManager; } });
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ConfirmationInputHandler = exports.InputHandler = void 0;
|
|
4
|
-
const
|
|
4
|
+
const terminal_1 = require("../../shared/terminal");
|
|
5
5
|
const keymap_1 = require("./keymap");
|
|
6
6
|
class InputHandler {
|
|
7
7
|
stateManager;
|
|
@@ -21,7 +21,7 @@ class InputHandler {
|
|
|
21
21
|
if (!key && !str) {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
if (key
|
|
24
|
+
if (key?.ctrl && key.name === 'c') {
|
|
25
25
|
this.onCancel();
|
|
26
26
|
process.exit(0);
|
|
27
27
|
}
|
|
@@ -201,7 +201,7 @@ class InputHandler {
|
|
|
201
201
|
}
|
|
202
202
|
// Normal mode (not in filter mode). Keys resolve through the keymap so that
|
|
203
203
|
// dispatch, the help overlay, the footer, and the README share one source.
|
|
204
|
-
if (!key
|
|
204
|
+
if (!key?.name) {
|
|
205
205
|
return;
|
|
206
206
|
}
|
|
207
207
|
// Enter confirms the selection (guarding against an empty selection). It runs
|
|
@@ -235,7 +235,7 @@ class InputHandler {
|
|
|
235
235
|
this.onAction({ type: 'resize', height });
|
|
236
236
|
}
|
|
237
237
|
cleanup() {
|
|
238
|
-
|
|
238
|
+
terminal_1.CursorUtils.cleanup();
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
exports.InputHandler = InputHandler;
|
|
@@ -249,7 +249,7 @@ class ConfirmationInputHandler {
|
|
|
249
249
|
if (!key && !str) {
|
|
250
250
|
return;
|
|
251
251
|
}
|
|
252
|
-
if (key
|
|
252
|
+
if (key?.ctrl && key.name === 'c') {
|
|
253
253
|
// onConfirm runs the normal cleanup path (cursor show, raw-mode off, listener
|
|
254
254
|
// removal). The 'exit' listener registered by confirmUpgrade is a final backstop.
|
|
255
255
|
this.onConfirm(false);
|
|
@@ -275,7 +275,7 @@ class ConfirmationInputHandler {
|
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
cleanup() {
|
|
278
|
-
|
|
278
|
+
terminal_1.CursorUtils.cleanup();
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
exports.ConfirmationInputHandler = ConfirmationInputHandler;
|
|
@@ -14,9 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./types"), exports);
|
|
18
17
|
__exportStar(require("./layout"), exports);
|
|
19
18
|
__exportStar(require("./package-info"), exports);
|
|
20
19
|
__exportStar(require("./package-info-sections"), exports);
|
|
21
20
|
__exportStar(require("./theme-selector"), exports);
|
|
21
|
+
__exportStar(require("./types"), exports);
|
|
22
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -11,12 +11,12 @@ exports.getModalSectionRowCount = getModalSectionRowCount;
|
|
|
11
11
|
exports.getModalFrameHeight = getModalFrameHeight;
|
|
12
12
|
exports.renderModalFrame = renderModalFrame;
|
|
13
13
|
const chalk_1 = __importDefault(require("chalk"));
|
|
14
|
-
const
|
|
14
|
+
const terminal_1 = require("../../../shared/terminal");
|
|
15
15
|
function getModalWidth(terminalWidth, minWidth, maxWidth) {
|
|
16
16
|
return Math.min(Math.max(minWidth, terminalWidth - 6), maxWidth);
|
|
17
17
|
}
|
|
18
18
|
function renderModalRow(padding, modalWidth, text) {
|
|
19
|
-
const rowLength = (0,
|
|
19
|
+
const rowLength = (0, terminal_1.getVisualLength)(text);
|
|
20
20
|
const rowPadding = Math.max(0, modalWidth - 4 - rowLength);
|
|
21
21
|
return (' '.repeat(padding) +
|
|
22
22
|
chalk_1.default.gray('│') +
|
|
@@ -27,7 +27,7 @@ function renderModalRow(padding, modalWidth, text) {
|
|
|
27
27
|
chalk_1.default.gray('│'));
|
|
28
28
|
}
|
|
29
29
|
function renderModalSeparator(padding, modalWidth) {
|
|
30
|
-
return ' '.repeat(padding) + chalk_1.default.gray('
|
|
30
|
+
return ' '.repeat(padding) + chalk_1.default.gray(`├${'─'.repeat(modalWidth - 2)}┤`);
|
|
31
31
|
}
|
|
32
32
|
function fitModalSections(sections, maxHeight, trimOrder) {
|
|
33
33
|
const activeSections = sections.map((section) => ({ ...section, rows: [...section.rows] }));
|
|
@@ -69,7 +69,7 @@ function renderModalFrame(sections, options) {
|
|
|
69
69
|
for (let i = 0; i < topPadding; i++) {
|
|
70
70
|
lines.push('');
|
|
71
71
|
}
|
|
72
|
-
lines.push(' '.repeat(padding) + chalk_1.default.gray('
|
|
72
|
+
lines.push(' '.repeat(padding) + chalk_1.default.gray(`╭${'─'.repeat(modalWidth - 2)}╮`));
|
|
73
73
|
sections.forEach((section, index) => {
|
|
74
74
|
if (index > 0) {
|
|
75
75
|
lines.push(renderModalSeparator(padding, modalWidth));
|
|
@@ -78,7 +78,7 @@ function renderModalFrame(sections, options) {
|
|
|
78
78
|
lines.push(renderModalRow(padding, modalWidth, row));
|
|
79
79
|
});
|
|
80
80
|
});
|
|
81
|
-
lines.push(' '.repeat(padding) + chalk_1.default.gray('
|
|
81
|
+
lines.push(' '.repeat(padding) + chalk_1.default.gray(`╰${'─'.repeat(modalWidth - 2)}╯`));
|
|
82
82
|
return lines;
|
|
83
83
|
}
|
|
84
84
|
//# sourceMappingURL=layout.js.map
|
|
@@ -14,6 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
//# sourceMappingURL=
|
|
17
|
+
__exportStar(require("./release-notes"), exports);
|
|
18
|
+
__exportStar(require("./sections"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -114,7 +114,7 @@ function buildReleaseNotesSections(state, modalWidth) {
|
|
|
114
114
|
});
|
|
115
115
|
return sections;
|
|
116
116
|
}
|
|
117
|
-
if (!loaded
|
|
117
|
+
if (!loaded?.has(currentVersion)) {
|
|
118
118
|
sections.push({
|
|
119
119
|
key: 'release-pending',
|
|
120
120
|
rows: [chalk_1.default.gray(`Press ←/→ to load release notes for v${currentVersion}`)],
|