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
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.loadProjectConfig = loadProjectConfig;
|
|
4
4
|
exports.isPackageIgnored = isPackageIgnored;
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
7
|
const package_meta_1 = require("./package-meta");
|
|
8
8
|
const CONFIG_FILES = [
|
|
9
9
|
`.${package_meta_1.PACKAGE_NAME}rc`,
|
|
@@ -16,12 +16,12 @@ const CONFIG_FILES = [
|
|
|
16
16
|
*/
|
|
17
17
|
function loadProjectConfig(cwd) {
|
|
18
18
|
let currentDir = cwd;
|
|
19
|
-
while (
|
|
19
|
+
while (true) {
|
|
20
20
|
for (const configFile of CONFIG_FILES) {
|
|
21
|
-
const configPath = (0,
|
|
22
|
-
if ((0,
|
|
21
|
+
const configPath = (0, node_path_1.join)(currentDir, configFile);
|
|
22
|
+
if ((0, node_fs_1.existsSync)(configPath)) {
|
|
23
23
|
try {
|
|
24
|
-
const content = (0,
|
|
24
|
+
const content = (0, node_fs_1.readFileSync)(configPath, 'utf-8');
|
|
25
25
|
const config = JSON.parse(content);
|
|
26
26
|
return normalizeConfig(config);
|
|
27
27
|
}
|
|
@@ -31,8 +31,10 @@ function loadProjectConfig(cwd) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
// Move to parent directory
|
|
35
|
-
|
|
34
|
+
// Move to parent directory. join(root, '..') === root at the filesystem
|
|
35
|
+
// root on every platform ('/' on POSIX, 'C:\' on Windows), so this is the
|
|
36
|
+
// single, cross-platform loop terminator.
|
|
37
|
+
const parentDir = (0, node_path_1.join)(currentDir, '..');
|
|
36
38
|
if (parentDir === currentDir)
|
|
37
39
|
break;
|
|
38
40
|
currentDir = parentDir;
|
|
@@ -4,29 +4,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.configManager = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
9
|
const env_paths_1 = __importDefault(require("env-paths"));
|
|
10
|
-
const
|
|
10
|
+
const package_meta_1 = require("./package-meta");
|
|
11
11
|
class ConfigManager {
|
|
12
12
|
configDir;
|
|
13
13
|
configPath;
|
|
14
14
|
constructor() {
|
|
15
15
|
// Use env-paths for cross-platform config directory support
|
|
16
16
|
// Mac/Linux: ~/.config/inup, Windows: %APPDATA%/inup
|
|
17
|
-
const paths = (0, env_paths_1.default)(
|
|
17
|
+
const paths = (0, env_paths_1.default)(package_meta_1.PACKAGE_NAME);
|
|
18
18
|
this.configDir = paths.config;
|
|
19
|
-
this.configPath = (0,
|
|
19
|
+
this.configPath = (0, node_path_1.join)(this.configDir, 'config.json');
|
|
20
20
|
}
|
|
21
21
|
ensureConfigDir() {
|
|
22
|
-
if (!(0,
|
|
23
|
-
(0,
|
|
22
|
+
if (!(0, node_fs_1.existsSync)(this.configDir)) {
|
|
23
|
+
(0, node_fs_1.mkdirSync)(this.configDir, { recursive: true });
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
readConfig() {
|
|
27
27
|
try {
|
|
28
|
-
if ((0,
|
|
29
|
-
const content = (0,
|
|
28
|
+
if ((0, node_fs_1.existsSync)(this.configPath)) {
|
|
29
|
+
const content = (0, node_fs_1.readFileSync)(this.configPath, 'utf-8');
|
|
30
30
|
return JSON.parse(content);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -39,7 +39,7 @@ class ConfigManager {
|
|
|
39
39
|
writeConfig(config) {
|
|
40
40
|
try {
|
|
41
41
|
this.ensureConfigDir();
|
|
42
|
-
(0,
|
|
42
|
+
(0, node_fs_1.writeFileSync)(this.configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
43
43
|
}
|
|
44
44
|
catch (error) {
|
|
45
45
|
console.error('Error writing config:', error);
|
|
@@ -66,4 +66,4 @@ class ConfigManager {
|
|
|
66
66
|
}
|
|
67
67
|
// Export singleton instance
|
|
68
68
|
exports.configManager = new ConfigManager();
|
|
69
|
-
//# sourceMappingURL=config.js.map
|
|
69
|
+
//# sourceMappingURL=user-config.js.map
|
|
@@ -4,9 +4,9 @@ exports.debugLog = void 0;
|
|
|
4
4
|
exports.enableDebugLogging = enableDebugLogging;
|
|
5
5
|
exports.isDebugEnabled = isDebugEnabled;
|
|
6
6
|
exports.getDebugLogPath = getDebugLogPath;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_os_1 = require("node:os");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
10
|
let _enabled = false;
|
|
11
11
|
let _logFile = null;
|
|
12
12
|
const pad = (n, width = 2) => String(n).padStart(width, '0');
|
|
@@ -21,13 +21,13 @@ function getLogFile() {
|
|
|
21
21
|
const dateStr = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
22
22
|
// Write to the OS temp dir (matches the path advertised in --help), not the
|
|
23
23
|
// current working directory — a debug log must never litter the user's repo.
|
|
24
|
-
const dir = (0,
|
|
25
|
-
if (!(0,
|
|
26
|
-
(0,
|
|
24
|
+
const dir = (0, node_path_1.join)((0, node_os_1.tmpdir)(), 'inup');
|
|
25
|
+
if (!(0, node_fs_1.existsSync)(dir)) {
|
|
26
|
+
(0, node_fs_1.mkdirSync)(dir, { recursive: true });
|
|
27
27
|
}
|
|
28
|
-
_logFile = (0,
|
|
28
|
+
_logFile = (0, node_path_1.join)(dir, `inup-debug-${dateStr}.log`);
|
|
29
29
|
// Write a header so the file is easy to identify
|
|
30
|
-
(0,
|
|
30
|
+
(0, node_fs_1.writeFileSync)(_logFile, `=== inup debug log started at ${timestamp()} ===\n`, { flag: 'a' });
|
|
31
31
|
}
|
|
32
32
|
return _logFile;
|
|
33
33
|
}
|
|
@@ -69,7 +69,7 @@ function write(level, context, message, extra) {
|
|
|
69
69
|
}
|
|
70
70
|
line += '\n';
|
|
71
71
|
try {
|
|
72
|
-
(0,
|
|
72
|
+
(0, node_fs_1.appendFileSync)(getLogFile(), line);
|
|
73
73
|
}
|
|
74
74
|
catch {
|
|
75
75
|
// Never crash the app because of debug logging
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.executeCommand = executeCommand;
|
|
4
4
|
exports.executeCommandAsync = executeCommandAsync;
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const execAsync = (0,
|
|
5
|
+
const node_child_process_1 = require("node:child_process");
|
|
6
|
+
const node_util_1 = require("node:util");
|
|
7
|
+
const execAsync = (0, node_util_1.promisify)(node_child_process_1.exec);
|
|
8
8
|
/**
|
|
9
9
|
* Execute a command synchronously
|
|
10
10
|
*/
|
|
11
11
|
function executeCommand(command, cwd) {
|
|
12
12
|
try {
|
|
13
|
-
return (0,
|
|
13
|
+
return (0, node_child_process_1.execSync)(command, {
|
|
14
14
|
encoding: 'utf-8',
|
|
15
15
|
stdio: 'pipe',
|
|
16
16
|
cwd: cwd,
|
|
@@ -14,6 +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
|
-
|
|
17
|
+
__exportStar(require("./io"), exports);
|
|
18
|
+
__exportStar(require("./paths"), exports);
|
|
19
|
+
__exportStar(require("./scan"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -5,11 +5,10 @@ exports.detectJsonFormat = detectJsonFormat;
|
|
|
5
5
|
exports.readPackageJsonAsync = readPackageJsonAsync;
|
|
6
6
|
exports.collectAllDependencies = collectAllDependencies;
|
|
7
7
|
exports.collectAllDependenciesAsync = collectAllDependenciesAsync;
|
|
8
|
-
const
|
|
9
|
-
const fs_2 = require("fs");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
10
9
|
function readPackageJson(path) {
|
|
11
10
|
try {
|
|
12
|
-
const content = (0,
|
|
11
|
+
const content = (0, node_fs_1.readFileSync)(path, 'utf-8');
|
|
13
12
|
return JSON.parse(content);
|
|
14
13
|
}
|
|
15
14
|
catch (error) {
|
|
@@ -33,7 +32,7 @@ function detectJsonFormat(raw) {
|
|
|
33
32
|
}
|
|
34
33
|
async function readPackageJsonAsync(path) {
|
|
35
34
|
try {
|
|
36
|
-
const content = await
|
|
35
|
+
const content = await node_fs_1.promises.readFile(path, 'utf-8');
|
|
37
36
|
return JSON.parse(content);
|
|
38
37
|
}
|
|
39
38
|
catch (error) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findPackageJson = findPackageJson;
|
|
4
|
+
exports.findWorkspaceRoot = findWorkspaceRoot;
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const package_manager_1 = require("../package-manager");
|
|
8
|
+
function findPackageJson(cwd = process.cwd()) {
|
|
9
|
+
const packageJsonPath = (0, node_path_1.join)(cwd, 'package.json');
|
|
10
|
+
return (0, node_fs_1.existsSync)(packageJsonPath) ? packageJsonPath : null;
|
|
11
|
+
}
|
|
12
|
+
function findWorkspaceRoot(cwd = process.cwd(), packageManager) {
|
|
13
|
+
if (!packageManager) {
|
|
14
|
+
const detected = package_manager_1.PackageManagerDetector.detect(cwd);
|
|
15
|
+
packageManager = detected.name;
|
|
16
|
+
}
|
|
17
|
+
return package_manager_1.PackageManagerDetector.findWorkspaceRoot(cwd, packageManager);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findAllPackageJsonFiles = findAllPackageJsonFiles;
|
|
4
4
|
exports.findAllPackageJsonFilesAsync = findAllPackageJsonFilesAsync;
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const path_1 = require("path");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
8
7
|
/**
|
|
9
8
|
* Normalize a relative path to forward slashes before matching `.inuprc` exclude patterns.
|
|
10
9
|
* On Windows `path.relative` yields backslash separators (e.g. `packages\skipme`), but users write
|
|
@@ -55,12 +54,12 @@ function classifyDirectory(name, skipSet) {
|
|
|
55
54
|
* layout). Stays shallow (depth 1) so detecting a skip doesn't re-walk the subtree we just pruned.
|
|
56
55
|
*/
|
|
57
56
|
function prunedDirHoldsPackage(dir) {
|
|
58
|
-
if ((0,
|
|
57
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(dir, 'package.json'))) {
|
|
59
58
|
return true;
|
|
60
59
|
}
|
|
61
60
|
let entries;
|
|
62
61
|
try {
|
|
63
|
-
entries = (0,
|
|
62
|
+
entries = (0, node_fs_1.readdirSync)(dir);
|
|
64
63
|
}
|
|
65
64
|
catch {
|
|
66
65
|
return false;
|
|
@@ -68,9 +67,9 @@ function prunedDirHoldsPackage(dir) {
|
|
|
68
67
|
for (const entry of entries) {
|
|
69
68
|
if (entry.startsWith('.'))
|
|
70
69
|
continue;
|
|
71
|
-
const child = (0,
|
|
70
|
+
const child = (0, node_path_1.join)(dir, entry);
|
|
72
71
|
try {
|
|
73
|
-
if ((0,
|
|
72
|
+
if ((0, node_fs_1.statSync)(child).isDirectory() && (0, node_fs_1.existsSync)((0, node_path_1.join)(child, 'package.json'))) {
|
|
74
73
|
return true;
|
|
75
74
|
}
|
|
76
75
|
}
|
|
@@ -117,7 +116,7 @@ function findAllPackageJsonFiles(rootDir = process.cwd(), excludePatterns = [],
|
|
|
117
116
|
return;
|
|
118
117
|
}
|
|
119
118
|
lastProgressAt = now;
|
|
120
|
-
const relativePath = (0,
|
|
119
|
+
const relativePath = (0, node_path_1.relative)(rootDir, currentDir) || '.';
|
|
121
120
|
onProgress(relativePath, packageJsonFiles.length);
|
|
122
121
|
}
|
|
123
122
|
function traverseDirectory(dir, depth = 0) {
|
|
@@ -126,7 +125,7 @@ function findAllPackageJsonFiles(rootDir = process.cwd(), excludePatterns = [],
|
|
|
126
125
|
}
|
|
127
126
|
try {
|
|
128
127
|
// Prevent symlink cycles by tracking visited real paths
|
|
129
|
-
const realPath = (0,
|
|
128
|
+
const realPath = (0, node_fs_1.realpathSync)(dir);
|
|
130
129
|
if (visitedPaths.has(realPath)) {
|
|
131
130
|
return;
|
|
132
131
|
}
|
|
@@ -136,17 +135,17 @@ function findAllPackageJsonFiles(rootDir = process.cwd(), excludePatterns = [],
|
|
|
136
135
|
if (onProgress && (directoriesScanned % 10 === 0 || directoriesScanned === 1)) {
|
|
137
136
|
reportProgress(dir, true);
|
|
138
137
|
}
|
|
139
|
-
const files = (0,
|
|
138
|
+
const files = (0, node_fs_1.readdirSync)(dir);
|
|
140
139
|
for (const file of files) {
|
|
141
140
|
reportProgress(dir);
|
|
142
|
-
const fullPath = (0,
|
|
143
|
-
const relativePath = (0,
|
|
141
|
+
const fullPath = (0, node_path_1.join)(dir, file);
|
|
142
|
+
const relativePath = (0, node_path_1.relative)(rootDir, fullPath);
|
|
144
143
|
if (shouldExcludePath(relativePath)) {
|
|
145
144
|
continue;
|
|
146
145
|
}
|
|
147
146
|
let stat;
|
|
148
147
|
try {
|
|
149
|
-
stat = (0,
|
|
148
|
+
stat = (0, node_fs_1.statSync)(fullPath);
|
|
150
149
|
}
|
|
151
150
|
catch {
|
|
152
151
|
// Skip files/dirs we can't stat (broken symlinks, permission issues)
|
|
@@ -190,7 +189,7 @@ async function findAllPackageJsonFilesAsync(rootDir = process.cwd(), excludePatt
|
|
|
190
189
|
return;
|
|
191
190
|
}
|
|
192
191
|
lastProgressAt = now;
|
|
193
|
-
const relativePath = (0,
|
|
192
|
+
const relativePath = (0, node_path_1.relative)(rootDir, currentDir) || '.';
|
|
194
193
|
onProgress(relativePath, packageJsonFiles.length);
|
|
195
194
|
}
|
|
196
195
|
const pending = [];
|
|
@@ -217,7 +216,7 @@ async function findAllPackageJsonFilesAsync(rootDir = process.cwd(), excludePatt
|
|
|
217
216
|
}
|
|
218
217
|
let realPath;
|
|
219
218
|
try {
|
|
220
|
-
realPath = await
|
|
219
|
+
realPath = await node_fs_1.promises.realpath(dir);
|
|
221
220
|
}
|
|
222
221
|
catch {
|
|
223
222
|
return;
|
|
@@ -232,21 +231,21 @@ async function findAllPackageJsonFilesAsync(rootDir = process.cwd(), excludePatt
|
|
|
232
231
|
}
|
|
233
232
|
let files;
|
|
234
233
|
try {
|
|
235
|
-
files = await
|
|
234
|
+
files = await node_fs_1.promises.readdir(dir);
|
|
236
235
|
}
|
|
237
236
|
catch {
|
|
238
237
|
return;
|
|
239
238
|
}
|
|
240
239
|
for (const file of files) {
|
|
241
240
|
reportProgress(dir);
|
|
242
|
-
const fullPath = (0,
|
|
243
|
-
const relativePath = (0,
|
|
241
|
+
const fullPath = (0, node_path_1.join)(dir, file);
|
|
242
|
+
const relativePath = (0, node_path_1.relative)(rootDir, fullPath);
|
|
244
243
|
if (shouldExcludePath(relativePath)) {
|
|
245
244
|
continue;
|
|
246
245
|
}
|
|
247
246
|
let stat;
|
|
248
247
|
try {
|
|
249
|
-
stat = await
|
|
248
|
+
stat = await node_fs_1.promises.stat(fullPath);
|
|
250
249
|
}
|
|
251
250
|
catch {
|
|
252
251
|
continue;
|
|
@@ -262,17 +261,21 @@ async function findAllPackageJsonFilesAsync(rootDir = process.cwd(), excludePatt
|
|
|
262
261
|
}
|
|
263
262
|
}
|
|
264
263
|
function pump() {
|
|
265
|
-
while (activeTasks < concurrency &&
|
|
264
|
+
while (activeTasks < concurrency && !failedError) {
|
|
266
265
|
const next = pending.shift();
|
|
267
266
|
if (!next)
|
|
268
267
|
break;
|
|
269
268
|
activeTasks++;
|
|
270
269
|
void processDirectory(next.dir, next.depth)
|
|
271
270
|
.catch((error) => {
|
|
271
|
+
// First error wins; a second in-flight task rejecting in the same
|
|
272
|
+
// tick is a race window that cannot be scheduled deterministically.
|
|
273
|
+
/* v8 ignore start */
|
|
272
274
|
if (!failedError) {
|
|
273
275
|
failedError = error;
|
|
274
276
|
rejectDone?.(error);
|
|
275
277
|
}
|
|
278
|
+
/* v8 ignore stop */
|
|
276
279
|
})
|
|
277
280
|
.finally(() => {
|
|
278
281
|
activeTasks--;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getGitWorkingTreeState = getGitWorkingTreeState;
|
|
4
|
-
const
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
5
|
/**
|
|
6
6
|
* Detect whether cwd is a git work tree and whether it has local changes.
|
|
7
7
|
* Fail soft if git is unavailable or cwd is not a repository.
|
|
8
8
|
*/
|
|
9
9
|
function getGitWorkingTreeState(cwd) {
|
|
10
10
|
try {
|
|
11
|
-
const isInsideWorkTree = (0,
|
|
11
|
+
const isInsideWorkTree = (0, node_child_process_1.execSync)('git rev-parse --is-inside-work-tree', {
|
|
12
12
|
cwd,
|
|
13
13
|
encoding: 'utf-8',
|
|
14
14
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
@@ -16,7 +16,7 @@ function getGitWorkingTreeState(cwd) {
|
|
|
16
16
|
if (isInsideWorkTree !== 'true') {
|
|
17
17
|
return { isRepo: false, isDirty: false };
|
|
18
18
|
}
|
|
19
|
-
const status = (0,
|
|
19
|
+
const status = (0, node_child_process_1.execSync)('git status --porcelain', {
|
|
20
20
|
cwd,
|
|
21
21
|
encoding: 'utf-8',
|
|
22
22
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
@@ -1,34 +1,64 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.setEtagCacheEnabled = setEtagCacheEnabled;
|
|
7
|
+
exports.setEtagCacheRoot = setEtagCacheRoot;
|
|
4
8
|
exports.readEtag = readEtag;
|
|
5
9
|
exports.writeEtag = writeEtag;
|
|
6
10
|
exports.etagCacheDir = etagCacheDir;
|
|
7
11
|
const node_crypto_1 = require("node:crypto");
|
|
8
12
|
const node_fs_1 = require("node:fs");
|
|
9
|
-
const node_os_1 = require("node:os");
|
|
10
13
|
const node_path_1 = require("node:path");
|
|
14
|
+
const env_paths_1 = __importDefault(require("env-paths"));
|
|
15
|
+
const config_1 = require("../config");
|
|
11
16
|
/** Bump when the on-disk entry shape changes; old generations are ignored. */
|
|
12
17
|
const SCHEMA = 'v1';
|
|
13
18
|
/** Entries untouched for longer than this are swept on first access. */
|
|
14
19
|
const MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000; // 14 days
|
|
15
20
|
let enabled = true;
|
|
16
21
|
let sweptThisProcess = false;
|
|
22
|
+
let cacheRootOverride = null;
|
|
23
|
+
let resolvedSchemaDir = null;
|
|
17
24
|
/** Allow tests/callers to toggle the store without touching call sites. */
|
|
18
25
|
function setEtagCacheEnabled(value) {
|
|
19
26
|
enabled = value;
|
|
20
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Test hook: point the store at an isolated root instead of the user's real
|
|
30
|
+
* cache directory (null restores the default). Tests must never wipe or race
|
|
31
|
+
* on the persistent per-user cache.
|
|
32
|
+
*/
|
|
33
|
+
function setEtagCacheRoot(root) {
|
|
34
|
+
cacheRootOverride = root;
|
|
35
|
+
resolvedSchemaDir = null;
|
|
36
|
+
sweptThisProcess = false;
|
|
37
|
+
}
|
|
38
|
+
/** The root holding one subdirectory per schema generation. */
|
|
39
|
+
function cacheRoot() {
|
|
40
|
+
// Version data is not project-specific, so it lives in the per-user cache
|
|
41
|
+
// directory (env-paths, like the config dir), shared across every project the
|
|
42
|
+
// user scans. It used to live in the OS temp dir, but macOS clears that on
|
|
43
|
+
// reboot and Linux distros sweep it periodically — throwing the cache away
|
|
44
|
+
// exactly when it is most useful.
|
|
45
|
+
return cacheRootOverride ?? (0, node_path_1.join)((0, env_paths_1.default)(config_1.PACKAGE_NAME).cache, 'etag-cache');
|
|
46
|
+
}
|
|
21
47
|
/** Resolve (and lazily create) the cache directory, sweeping stale entries once. */
|
|
22
48
|
function cacheDir() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
49
|
+
if (resolvedSchemaDir === null) {
|
|
50
|
+
// The location is process-invariant; derive it once instead of running
|
|
51
|
+
// env-paths on every cache read/write of the registry hot path.
|
|
52
|
+
resolvedSchemaDir = (0, node_path_1.join)(cacheRoot(), SCHEMA);
|
|
53
|
+
}
|
|
54
|
+
const dir = resolvedSchemaDir;
|
|
26
55
|
if (!(0, node_fs_1.existsSync)(dir)) {
|
|
27
56
|
(0, node_fs_1.mkdirSync)(dir, { recursive: true });
|
|
28
57
|
}
|
|
29
58
|
if (!sweptThisProcess) {
|
|
30
59
|
sweptThisProcess = true;
|
|
31
60
|
sweepStale(dir);
|
|
61
|
+
sweepOldGenerations(cacheRoot());
|
|
32
62
|
}
|
|
33
63
|
return dir;
|
|
34
64
|
}
|
|
@@ -51,6 +81,28 @@ function sweepStale(dir) {
|
|
|
51
81
|
/* sweeping is optional; never fail a run over it */
|
|
52
82
|
}
|
|
53
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Remove schema generations other than the active one. The cache directory is
|
|
86
|
+
* persistent (unlike the old tmpdir location, which the OS reclaimed), so after
|
|
87
|
+
* a SCHEMA bump the previous generation would otherwise live on disk forever.
|
|
88
|
+
*/
|
|
89
|
+
function sweepOldGenerations(root) {
|
|
90
|
+
try {
|
|
91
|
+
for (const name of (0, node_fs_1.readdirSync)(root)) {
|
|
92
|
+
if (name === SCHEMA)
|
|
93
|
+
continue;
|
|
94
|
+
try {
|
|
95
|
+
(0, node_fs_1.rmSync)((0, node_path_1.join)(root, name), { recursive: true, force: true });
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
/* skip generations we can't remove */
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* sweeping is optional; never fail a run over it */
|
|
104
|
+
}
|
|
105
|
+
}
|
|
54
106
|
/** Stable, filesystem-safe filename for a cache key (the registry path). */
|
|
55
107
|
function fileFor(key) {
|
|
56
108
|
const hash = (0, node_crypto_1.createHash)('sha1').update(key).digest('hex');
|
|
@@ -60,8 +60,10 @@ class ResizableSemaphore {
|
|
|
60
60
|
* each as it is admitted so the count stays authoritative and synchronous.
|
|
61
61
|
*/
|
|
62
62
|
drainWaiters() {
|
|
63
|
-
while (this.inFlight < this.limit
|
|
63
|
+
while (this.inFlight < this.limit) {
|
|
64
64
|
const next = this.waiters.shift();
|
|
65
|
+
if (!next)
|
|
66
|
+
break;
|
|
65
67
|
this.inFlight++;
|
|
66
68
|
next();
|
|
67
69
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.loadInupLocalEnv = loadInupLocalEnv;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
6
|
/**
|
|
7
7
|
* Loads a gitignored `.env.local` from the inup repo itself (NOT the cwd), so
|
|
8
8
|
* developer-only toggles can be "set once" and apply to every `inup` run in any
|
|
9
9
|
* project — without committing anything or touching the shell profile.
|
|
10
10
|
*
|
|
11
11
|
* The repo is located by walking UP from this file's own directory until a
|
|
12
|
-
* `.env.local` is found, so it works regardless of nesting depth (src/
|
|
12
|
+
* `.env.local` is found, so it works regardless of nesting depth (src/shared when
|
|
13
13
|
* type-stripped, dist/utils when compiled) and resolves the inup repo even when
|
|
14
14
|
* the binary is linked and invoked from a different project directory.
|
|
15
15
|
*
|
|
@@ -21,15 +21,15 @@ const ENV_FILE_NAME = '.env.local';
|
|
|
21
21
|
/** Walk upward from this file's dir to find the .env.local; null if none. */
|
|
22
22
|
function findEnvFile() {
|
|
23
23
|
let dir = __dirname;
|
|
24
|
-
const root = (0,
|
|
24
|
+
const root = (0, node_path_1.parse)(dir).root;
|
|
25
25
|
// Cap the walk so a missing file can never loop unbounded.
|
|
26
26
|
for (let i = 0; i < 12; i++) {
|
|
27
|
-
const candidate = (0,
|
|
28
|
-
if ((0,
|
|
27
|
+
const candidate = (0, node_path_1.join)(dir, ENV_FILE_NAME);
|
|
28
|
+
if ((0, node_fs_1.existsSync)(candidate))
|
|
29
29
|
return candidate;
|
|
30
30
|
if (dir === root)
|
|
31
31
|
break;
|
|
32
|
-
dir = (0,
|
|
32
|
+
dir = (0, node_path_1.dirname)(dir);
|
|
33
33
|
}
|
|
34
34
|
return null;
|
|
35
35
|
}
|
|
@@ -65,7 +65,7 @@ function loadInupLocalEnv() {
|
|
|
65
65
|
const file = findEnvFile();
|
|
66
66
|
if (!file)
|
|
67
67
|
return null;
|
|
68
|
-
const parsed = parseEnv((0,
|
|
68
|
+
const parsed = parseEnv((0, node_fs_1.readFileSync)(file, 'utf8'));
|
|
69
69
|
for (const [key, value] of Object.entries(parsed)) {
|
|
70
70
|
if (process.env[key] === undefined) {
|
|
71
71
|
process.env[key] = value;
|