@bobfrankston/npmglobalize 1.0.97 → 1.0.99
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/.claude/settings.local.json +3 -1
- package/index.d.ts +2 -1
- package/lib.js +96 -8
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* npmglobalize - Main entry point
|
|
4
4
|
*/
|
|
5
5
|
import './cli.js';
|
|
6
|
-
export { globalize, globalizeWorkspace
|
|
6
|
+
export { globalize, globalizeWorkspace } from './lib.js';
|
|
7
|
+
export type { GlobalizeOptions, WorkspaceResult } from './lib.js';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/lib.js
CHANGED
|
@@ -71,6 +71,51 @@ function removeNulFiles(dir, visited = new Set()) {
|
|
|
71
71
|
}
|
|
72
72
|
return count;
|
|
73
73
|
}
|
|
74
|
+
/** Repair a corrupted git index by rebuilding it.
|
|
75
|
+
* Handles "invalid object" / "Error building trees" errors caused by
|
|
76
|
+
* stale entries in .git/index referencing missing objects. */
|
|
77
|
+
function repairGitIndex(cwd) {
|
|
78
|
+
const indexPath = path.join(cwd, '.git', 'index');
|
|
79
|
+
try {
|
|
80
|
+
console.log(colors.yellow('Detected corrupted git index — rebuilding...'));
|
|
81
|
+
// Delete the corrupted index
|
|
82
|
+
if (fs.existsSync(indexPath)) {
|
|
83
|
+
fs.unlinkSync(indexPath);
|
|
84
|
+
}
|
|
85
|
+
// Rebuild from HEAD (reset index to match last commit)
|
|
86
|
+
const resetResult = spawnSafe('git', ['reset'], {
|
|
87
|
+
encoding: 'utf-8',
|
|
88
|
+
stdio: 'pipe',
|
|
89
|
+
cwd,
|
|
90
|
+
env: process.env
|
|
91
|
+
});
|
|
92
|
+
if (resetResult.status !== 0) {
|
|
93
|
+
// If no commits yet, just proceed — git add -A will build a fresh index
|
|
94
|
+
const stderr = resetResult.stderr || '';
|
|
95
|
+
if (!stderr.includes('does not have any commits')) {
|
|
96
|
+
console.error(colors.red('Failed to reset git index:'), stderr.trim());
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Re-stage all files
|
|
101
|
+
const addResult = spawnSafe('git', ['add', '-A'], {
|
|
102
|
+
encoding: 'utf-8',
|
|
103
|
+
stdio: 'pipe',
|
|
104
|
+
cwd,
|
|
105
|
+
env: process.env
|
|
106
|
+
});
|
|
107
|
+
if (addResult.status !== 0) {
|
|
108
|
+
console.error(colors.red('Failed to re-add files after index rebuild:'), (addResult.stderr || '').trim());
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
console.log(colors.green('✓ Git index rebuilt successfully'));
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
console.error(colors.red('Failed to repair git index:'), err.message);
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
74
119
|
/** Get npm command for current platform (npm.cmd on Windows, npm elsewhere) */
|
|
75
120
|
function getNpmCommand() {
|
|
76
121
|
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
@@ -833,7 +878,7 @@ export function fixVersionTagMismatch(cwd, pkg, verbose = false) {
|
|
|
833
878
|
return deletedAny;
|
|
834
879
|
}
|
|
835
880
|
/** Wait for a package version to appear on the npm registry */
|
|
836
|
-
function waitForNpmVersion(pkgName, version, maxWaitMs =
|
|
881
|
+
function waitForNpmVersion(pkgName, version, maxWaitMs = 90000) {
|
|
837
882
|
const interval = 3000;
|
|
838
883
|
const maxAttempts = Math.ceil(maxWaitMs / interval);
|
|
839
884
|
process.stdout.write(`Waiting for ${pkgName}@${version} on npm registry`);
|
|
@@ -853,6 +898,16 @@ function waitForNpmVersion(pkgName, version, maxWaitMs = 60000) {
|
|
|
853
898
|
process.stdout.write(' timed out\n');
|
|
854
899
|
return false;
|
|
855
900
|
}
|
|
901
|
+
/** Run npm install -g with retries for registry propagation delay */
|
|
902
|
+
function installGlobalWithRetry(pkgSpec, cwd, maxRetries = 3) {
|
|
903
|
+
let result = runCommand('npm', ['install', '-g', pkgSpec], { cwd, silent: false });
|
|
904
|
+
for (let attempt = 1; attempt < maxRetries && !result.success; attempt++) {
|
|
905
|
+
console.log(colors.yellow(` Retrying install (attempt ${attempt + 1}/${maxRetries}) in 10 seconds...`));
|
|
906
|
+
spawnSafe(process.platform === 'win32' ? 'timeout' : 'sleep', process.platform === 'win32' ? ['/t', '10', '/nobreak'] : ['10'], { stdio: 'pipe', shell: process.platform === 'win32' });
|
|
907
|
+
result = runCommand('npm', ['install', '-g', pkgSpec], { cwd, silent: false });
|
|
908
|
+
}
|
|
909
|
+
return result;
|
|
910
|
+
}
|
|
856
911
|
/** Run a command and return success status */
|
|
857
912
|
export function runCommand(cmd, args, options = {}) {
|
|
858
913
|
const { silent = false, cwd } = options;
|
|
@@ -958,6 +1013,27 @@ export function runCommandOrThrow(cmd, args, options = {}) {
|
|
|
958
1013
|
}
|
|
959
1014
|
throw new Error('Failed to add safe.directory to git config.');
|
|
960
1015
|
}
|
|
1016
|
+
// Detect corrupted git index and auto-repair
|
|
1017
|
+
if (cmd === 'git' && (stderr.includes('invalid object') || stderr.includes('Error building trees'))) {
|
|
1018
|
+
if (options.cwd && repairGitIndex(options.cwd)) {
|
|
1019
|
+
// Retry the original command
|
|
1020
|
+
const retry = spawnSafe(cmd, args, {
|
|
1021
|
+
encoding: 'utf-8',
|
|
1022
|
+
stdio: 'pipe',
|
|
1023
|
+
cwd: options.cwd,
|
|
1024
|
+
env: process.env,
|
|
1025
|
+
shell: needsShell
|
|
1026
|
+
});
|
|
1027
|
+
if (retry.status === 0) {
|
|
1028
|
+
return (retry.stdout || '') + (retry.stderr || '');
|
|
1029
|
+
}
|
|
1030
|
+
const retryStderr = retry.stderr || '';
|
|
1031
|
+
if (retryStderr.trim()) {
|
|
1032
|
+
console.error(colors.red(retryStderr.trim()));
|
|
1033
|
+
}
|
|
1034
|
+
throw new Error(`Command failed after git index repair: ${cmd} ${args.join(' ')}`);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
961
1037
|
// Show the error output
|
|
962
1038
|
if (stderr.trim()) {
|
|
963
1039
|
console.error(colors.red(stderr.trim()));
|
|
@@ -2471,7 +2547,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2471
2547
|
else if (install) {
|
|
2472
2548
|
waitForNpmVersion(pkgName, pkgVersion);
|
|
2473
2549
|
console.log(`Installing ${pkgName}@${pkgVersion} globally from registry...`);
|
|
2474
|
-
const registryInstallResult =
|
|
2550
|
+
const registryInstallResult = installGlobalWithRetry(`${pkgName}@${pkgVersion}`, cwd);
|
|
2475
2551
|
if (registryInstallResult.success) {
|
|
2476
2552
|
console.log(colors.green(`✓ Installed globally: ${pkgName}@${pkgVersion}`));
|
|
2477
2553
|
}
|
|
@@ -2520,13 +2596,25 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2520
2596
|
}
|
|
2521
2597
|
console.log(colors.yellow('Continuing with --force...'));
|
|
2522
2598
|
}
|
|
2523
|
-
|
|
2599
|
+
let commitResult = runCommand('git', ['commit', '-m', commitMsg], { cwd });
|
|
2524
2600
|
if (!commitResult.success) {
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2601
|
+
// Check for corrupted git index ("invalid object" / "Error building trees")
|
|
2602
|
+
// Run silently to capture stderr for detection
|
|
2603
|
+
const probe = runCommand('git', ['commit', '-m', commitMsg], { cwd, silent: true });
|
|
2604
|
+
const errText = probe.stderr + probe.output;
|
|
2605
|
+
if (errText.includes('invalid object') || errText.includes('Error building trees')) {
|
|
2606
|
+
if (repairGitIndex(cwd)) {
|
|
2607
|
+
// Retry commit after repair
|
|
2608
|
+
commitResult = runCommand('git', ['commit', '-m', commitMsg], { cwd });
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
if (!commitResult.success) {
|
|
2612
|
+
console.error(colors.red('ERROR: Failed to commit changes:'), commitResult.stderr);
|
|
2613
|
+
if (!force) {
|
|
2614
|
+
return false;
|
|
2615
|
+
}
|
|
2616
|
+
console.log(colors.yellow('Continuing with --force...'));
|
|
2528
2617
|
}
|
|
2529
|
-
console.log(colors.yellow('Continuing with --force...'));
|
|
2530
2618
|
}
|
|
2531
2619
|
}
|
|
2532
2620
|
else {
|
|
@@ -2930,7 +3018,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2930
3018
|
console.log(`Installing globally from registry: ${pkgName}@${pkgVersion}...`);
|
|
2931
3019
|
if (!dryRun) {
|
|
2932
3020
|
waitForNpmVersion(pkgName, pkgVersion);
|
|
2933
|
-
const installResult =
|
|
3021
|
+
const installResult = installGlobalWithRetry(`${pkgName}@${pkgVersion}`, cwd);
|
|
2934
3022
|
if (installResult.success) {
|
|
2935
3023
|
console.log(colors.green(`✓ Installed globally: ${pkgName}@${pkgVersion}`));
|
|
2936
3024
|
}
|