@bobfrankston/npmglobalize 1.0.137 → 1.0.138
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/colors.d.ts +29 -0
- package/colors.js +64 -0
- package/ignorepatterns.json5 +1 -0
- package/lib/git.js +25 -1
- package/lib.js +114 -125
- package/package.json +5 -3
- package/bobfrankston-npmglobalize-1.0.77.tgz +0 -0
package/colors.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional color module for npmglobalize.
|
|
3
|
+
* Uses semantic names (success, warn, error, info, muted) instead of raw colors.
|
|
4
|
+
* Adapts to light/dark terminal backgrounds.
|
|
5
|
+
*/
|
|
6
|
+
/** Semantic color functions — use these instead of raw colors */
|
|
7
|
+
export declare const colors: {
|
|
8
|
+
/** Success: green on both themes */
|
|
9
|
+
success: (text: string) => string;
|
|
10
|
+
/** Warning: yellow on dark, magenta on light */
|
|
11
|
+
warn: (text: string) => string;
|
|
12
|
+
/** Error: red on both themes */
|
|
13
|
+
error: (text: string) => string;
|
|
14
|
+
/** Info: blue on both themes */
|
|
15
|
+
info: (text: string) => string;
|
|
16
|
+
/** Accent: cyan on both themes */
|
|
17
|
+
accent: (text: string) => string;
|
|
18
|
+
/** Muted/dim text */
|
|
19
|
+
muted: (text: string) => string;
|
|
20
|
+
/** Italic */
|
|
21
|
+
italic: (text: string) => string;
|
|
22
|
+
red: (text: string) => string;
|
|
23
|
+
yellow: (text: string) => string;
|
|
24
|
+
green: (text: string) => string;
|
|
25
|
+
blue: (text: string) => string;
|
|
26
|
+
cyan: (text: string) => string;
|
|
27
|
+
dim: (text: string) => string;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=colors.d.ts.map
|
package/colors.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional color module for npmglobalize.
|
|
3
|
+
* Uses semantic names (success, warn, error, info, muted) instead of raw colors.
|
|
4
|
+
* Adapts to light/dark terminal backgrounds.
|
|
5
|
+
*/
|
|
6
|
+
import { styleText } from 'util';
|
|
7
|
+
/** Detect terminal theme from environment or default to dark */
|
|
8
|
+
function detectTheme() {
|
|
9
|
+
// COLORFGBG is set by some terminals: "fg;bg" — high bg = light theme
|
|
10
|
+
const colorfgbg = process.env.COLORFGBG;
|
|
11
|
+
if (colorfgbg) {
|
|
12
|
+
const bg = parseInt(colorfgbg.split(';').pop() || '0', 10);
|
|
13
|
+
if (bg > 8)
|
|
14
|
+
return 'light';
|
|
15
|
+
}
|
|
16
|
+
// Explicit override
|
|
17
|
+
if (process.env.NPMG_THEME === 'light')
|
|
18
|
+
return 'light';
|
|
19
|
+
if (process.env.NPMG_THEME === 'dark')
|
|
20
|
+
return 'dark';
|
|
21
|
+
return 'dark';
|
|
22
|
+
}
|
|
23
|
+
const theme = detectTheme();
|
|
24
|
+
// Raw ANSI colors per theme — semantic → [dark, light]
|
|
25
|
+
const themeMap = {
|
|
26
|
+
success: ['green', 'green'],
|
|
27
|
+
warn: ['yellow', 'magenta'], // yellow is invisible on light bg
|
|
28
|
+
error: ['red', 'red'],
|
|
29
|
+
info: ['blue', 'blue'],
|
|
30
|
+
accent: ['cyan', 'cyan'],
|
|
31
|
+
muted: ['dim', 'dim'],
|
|
32
|
+
italic: ['italic', 'italic'],
|
|
33
|
+
};
|
|
34
|
+
function pick(semantic) {
|
|
35
|
+
const entry = themeMap[semantic];
|
|
36
|
+
if (!entry)
|
|
37
|
+
return semantic;
|
|
38
|
+
return theme === 'light' ? entry[1] : entry[0];
|
|
39
|
+
}
|
|
40
|
+
/** Semantic color functions — use these instead of raw colors */
|
|
41
|
+
export const colors = {
|
|
42
|
+
/** Success: green on both themes */
|
|
43
|
+
success: (text) => styleText(pick('success'), text),
|
|
44
|
+
/** Warning: yellow on dark, magenta on light */
|
|
45
|
+
warn: (text) => styleText(pick('warn'), text),
|
|
46
|
+
/** Error: red on both themes */
|
|
47
|
+
error: (text) => styleText(pick('error'), text),
|
|
48
|
+
/** Info: blue on both themes */
|
|
49
|
+
info: (text) => styleText(pick('info'), text),
|
|
50
|
+
/** Accent: cyan on both themes */
|
|
51
|
+
accent: (text) => styleText(pick('accent'), text),
|
|
52
|
+
/** Muted/dim text */
|
|
53
|
+
muted: (text) => styleText(pick('muted'), text),
|
|
54
|
+
/** Italic */
|
|
55
|
+
italic: (text) => styleText('italic', text),
|
|
56
|
+
// Legacy aliases for gradual migration
|
|
57
|
+
red: (text) => styleText(pick('error'), text),
|
|
58
|
+
yellow: (text) => styleText(pick('warn'), text),
|
|
59
|
+
green: (text) => styleText(pick('success'), text),
|
|
60
|
+
blue: (text) => styleText(pick('info'), text),
|
|
61
|
+
cyan: (text) => styleText(pick('accent'), text),
|
|
62
|
+
dim: (text) => styleText(pick('muted'), text),
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=colors.js.map
|
package/ignorepatterns.json5
CHANGED
package/lib/git.js
CHANGED
|
@@ -659,12 +659,36 @@ export function showPushProtectionGuidance(ppInfo) {
|
|
|
659
659
|
/** Push to git with push-protection detection and auto-bypass for installed OAuth.
|
|
660
660
|
* Returns true if push succeeded (possibly after auto-bypass). */
|
|
661
661
|
export function pushWithProtection(cwd, verbose) {
|
|
662
|
-
|
|
662
|
+
let pushResult = runCommand('git', ['push'], { cwd, silent: true });
|
|
663
663
|
if (pushResult.success) {
|
|
664
664
|
if (verbose)
|
|
665
665
|
console.log(colors.green(' ✓ Pushed to remote'));
|
|
666
666
|
return true;
|
|
667
667
|
}
|
|
668
|
+
// Check for "Everything up-to-date" — git sometimes returns non-zero
|
|
669
|
+
// alongside transient errors even though there's nothing to push
|
|
670
|
+
const combined = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
|
|
671
|
+
if (combined.includes('everything up-to-date')) {
|
|
672
|
+
if (verbose)
|
|
673
|
+
console.log(colors.green(' ✓ Already up-to-date'));
|
|
674
|
+
return true;
|
|
675
|
+
}
|
|
676
|
+
// Transient network errors (HTTP 408, RPC failed, unexpected disconnect) — retry once
|
|
677
|
+
if (/rpc failed|curl \d+|unexpected disconnect|hung up unexpectedly/i.test(pushResult.stderr)) {
|
|
678
|
+
console.log(colors.yellow('Git push failed with transient error — retrying...'));
|
|
679
|
+
pushResult = runCommand('git', ['push'], { cwd, silent: true });
|
|
680
|
+
if (pushResult.success) {
|
|
681
|
+
if (verbose)
|
|
682
|
+
console.log(colors.green(' ✓ Pushed to remote (retry)'));
|
|
683
|
+
return true;
|
|
684
|
+
}
|
|
685
|
+
const retryCombo = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
|
|
686
|
+
if (retryCombo.includes('everything up-to-date')) {
|
|
687
|
+
if (verbose)
|
|
688
|
+
console.log(colors.green(' ✓ Already up-to-date'));
|
|
689
|
+
return true;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
668
692
|
const ppInfo = parsePushProtection(pushResult.stderr, cwd);
|
|
669
693
|
if (!ppInfo.detected) {
|
|
670
694
|
console.error(colors.red('Git push failed:'));
|
package/lib.js
CHANGED
|
@@ -30,17 +30,9 @@ import readline from 'readline';
|
|
|
30
30
|
import libversion from 'libnpmversion';
|
|
31
31
|
import JSON5 from 'json5';
|
|
32
32
|
import { fileURLToPath } from 'url';
|
|
33
|
-
import {
|
|
34
|
-
/**
|
|
35
|
-
const colors =
|
|
36
|
-
red: (text) => styleText('red', text),
|
|
37
|
-
yellow: (text) => styleText('yellow', text),
|
|
38
|
-
green: (text) => styleText('green', text),
|
|
39
|
-
italic: (text) => styleText('italic', text),
|
|
40
|
-
blue: (text) => styleText('blue', text),
|
|
41
|
-
cyan: (text) => styleText('cyan', text),
|
|
42
|
-
dim: (text) => styleText('dim', text),
|
|
43
|
-
};
|
|
33
|
+
import { themeColors } from '@bobfrankston/themecolors';
|
|
34
|
+
/** Semantic color functions — adapts to terminal light/dark theme */
|
|
35
|
+
const colors = themeColors();
|
|
44
36
|
/**
|
|
45
37
|
* Remove 'nul' files from a directory tree (Windows reserved name issue).
|
|
46
38
|
* These files break git and npm on Windows. Uses \\?\ prefix to bypass name validation.
|
|
@@ -1641,12 +1633,36 @@ function showPushProtectionGuidance(ppInfo) {
|
|
|
1641
1633
|
/** Push to git with push-protection detection and auto-bypass for installed OAuth.
|
|
1642
1634
|
* Returns true if push succeeded (possibly after auto-bypass). */
|
|
1643
1635
|
function pushWithProtection(cwd, verbose) {
|
|
1644
|
-
|
|
1636
|
+
let pushResult = runCommand('git', ['push'], { cwd, silent: true });
|
|
1645
1637
|
if (pushResult.success) {
|
|
1646
1638
|
if (verbose)
|
|
1647
1639
|
console.log(colors.green(' ✓ Pushed to remote'));
|
|
1648
1640
|
return true;
|
|
1649
1641
|
}
|
|
1642
|
+
// Check for "Everything up-to-date" — git sometimes returns non-zero
|
|
1643
|
+
// alongside transient errors even though there's nothing to push
|
|
1644
|
+
const combined = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
|
|
1645
|
+
if (combined.includes('everything up-to-date')) {
|
|
1646
|
+
if (verbose)
|
|
1647
|
+
console.log(colors.green(' ✓ Already up-to-date'));
|
|
1648
|
+
return true;
|
|
1649
|
+
}
|
|
1650
|
+
// Transient network errors (HTTP 408, RPC failed, unexpected disconnect) — retry once
|
|
1651
|
+
if (/rpc failed|curl \d+|unexpected disconnect|hung up unexpectedly/i.test(pushResult.stderr)) {
|
|
1652
|
+
console.log(colors.yellow('Git push failed with transient error — retrying...'));
|
|
1653
|
+
pushResult = runCommand('git', ['push'], { cwd, silent: true });
|
|
1654
|
+
if (pushResult.success) {
|
|
1655
|
+
if (verbose)
|
|
1656
|
+
console.log(colors.green(' ✓ Pushed to remote (retry)'));
|
|
1657
|
+
return true;
|
|
1658
|
+
}
|
|
1659
|
+
const retryCombo = (pushResult.output + ' ' + pushResult.stderr).toLowerCase();
|
|
1660
|
+
if (retryCombo.includes('everything up-to-date')) {
|
|
1661
|
+
if (verbose)
|
|
1662
|
+
console.log(colors.green(' ✓ Already up-to-date'));
|
|
1663
|
+
return true;
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1650
1666
|
const ppInfo = parsePushProtection(pushResult.stderr, cwd);
|
|
1651
1667
|
if (!ppInfo.detected) {
|
|
1652
1668
|
console.error(colors.red('Git push failed:'));
|
|
@@ -2035,9 +2051,17 @@ export async function initGit(cwd, visibility, dryRun) {
|
|
|
2035
2051
|
const createResult = runCommand('gh', ['repo', 'create', repoName, visFlag, '--source=.', '--push'], { cwd, silent: true });
|
|
2036
2052
|
if (!createResult.success) {
|
|
2037
2053
|
const errText = createResult.stderr + createResult.output;
|
|
2038
|
-
if (
|
|
2054
|
+
// Check if repo was created but push failed (GitHub propagation delay)
|
|
2055
|
+
const repoCreatedButPushFailed = /repository not found|hung up unexpectedly|rpc failed/i.test(errText)
|
|
2056
|
+
&& /https?:\/\/github\.com\//i.test(errText);
|
|
2057
|
+
if (errText.includes('Name already exists') || repoCreatedButPushFailed) {
|
|
2039
2058
|
// Repo exists on GitHub — look up the owner and add as remote
|
|
2040
|
-
|
|
2059
|
+
if (repoCreatedButPushFailed) {
|
|
2060
|
+
console.log(colors.yellow(` GitHub repo created but initial push failed — retrying...`));
|
|
2061
|
+
}
|
|
2062
|
+
else {
|
|
2063
|
+
console.log(colors.yellow(` GitHub repo '${repoName}' already exists — linking as remote...`));
|
|
2064
|
+
}
|
|
2041
2065
|
const whoResult = runCommand('gh', ['api', 'user', '--jq', '.login'], { cwd, silent: true });
|
|
2042
2066
|
const ghUser = (whoResult.output || '').trim();
|
|
2043
2067
|
if (!ghUser) {
|
|
@@ -2050,9 +2074,22 @@ export async function initGit(cwd, visibility, dryRun) {
|
|
|
2050
2074
|
// Remote might already exist with wrong URL
|
|
2051
2075
|
runCommand('git', ['remote', 'set-url', 'origin', remoteUrl], { cwd, silent: true });
|
|
2052
2076
|
}
|
|
2053
|
-
// Push existing commits
|
|
2054
|
-
|
|
2055
|
-
|
|
2077
|
+
// Push existing commits (retry up to 2 times for propagation delay)
|
|
2078
|
+
let pushed = false;
|
|
2079
|
+
for (let attempt = 0; attempt < 2 && !pushed; attempt++) {
|
|
2080
|
+
if (attempt > 0) {
|
|
2081
|
+
console.log(colors.yellow(' Retrying push...'));
|
|
2082
|
+
spawnSafe(process.platform === 'win32' ? 'timeout' : 'sleep', process.platform === 'win32' ? ['\t', '3', '\nobreak'] : ['3'], { stdio: 'pipe' }); // brief delay for GitHub propagation
|
|
2083
|
+
}
|
|
2084
|
+
const pushRes = runCommand('git', ['push', '-u', 'origin', 'master'], { cwd, silent: true });
|
|
2085
|
+
pushed = pushRes.success;
|
|
2086
|
+
}
|
|
2087
|
+
if (pushed) {
|
|
2088
|
+
console.log(colors.green(` ✓ Linked to repo: ${remoteUrl}`));
|
|
2089
|
+
}
|
|
2090
|
+
else {
|
|
2091
|
+
console.log(colors.yellow(` ✓ Repo created but push failed — push manually: git push -u origin master`));
|
|
2092
|
+
}
|
|
2056
2093
|
}
|
|
2057
2094
|
else {
|
|
2058
2095
|
console.error(colors.red(`Failed to create GitHub repo: ${errText}`));
|
|
@@ -3641,12 +3678,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3641
3678
|
}
|
|
3642
3679
|
}
|
|
3643
3680
|
else if (error.message?.includes('unknown git error')) {
|
|
3644
|
-
console.error(colors.yellow('
|
|
3645
|
-
console.error(' • Git hooks (pre-commit, commit-msg) might be failing');
|
|
3646
|
-
console.error(' • GPG signing might be required but not configured');
|
|
3647
|
-
console.error(' • Git config issues (user.name, user.email)');
|
|
3648
|
-
console.error(' • Disk space or permissions issues');
|
|
3649
|
-
console.error(colors.yellow('\nTry running with --verbose or check git status manually'));
|
|
3681
|
+
console.error(colors.yellow('Unknown git error — check git hooks, signing, or permissions'));
|
|
3650
3682
|
}
|
|
3651
3683
|
else if (combinedOutput.includes('gh013') || combinedOutput.includes('push protection') || combinedOutput.includes('push declined due to repository rule')) {
|
|
3652
3684
|
// GitHub push protection blocked a push (from postversion script)
|
|
@@ -3694,29 +3726,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3694
3726
|
// Check npm authentication right before publishing
|
|
3695
3727
|
const authStatus = checkNpmAuth();
|
|
3696
3728
|
if (!authStatus.authenticated) {
|
|
3697
|
-
console.error(colors.red(
|
|
3698
|
-
console.error('');
|
|
3699
|
-
if (authStatus.error === 'token expired') {
|
|
3700
|
-
console.error('Your npm access token has expired or been revoked.');
|
|
3701
|
-
console.error('');
|
|
3702
|
-
console.error('To fix this, run:');
|
|
3703
|
-
console.error(colors.yellow(' npm logout'));
|
|
3704
|
-
console.error(colors.yellow(' npm login'));
|
|
3705
|
-
}
|
|
3706
|
-
else if (authStatus.error === 'not logged in') {
|
|
3707
|
-
console.error('You are not logged in to npm.');
|
|
3708
|
-
console.error('');
|
|
3709
|
-
console.error('To fix this, run:');
|
|
3710
|
-
console.error(colors.yellow(' npm login'));
|
|
3711
|
-
}
|
|
3712
|
-
else {
|
|
3713
|
-
console.error(`Authentication error: ${authStatus.error}`);
|
|
3714
|
-
console.error('');
|
|
3715
|
-
console.error('Try running:');
|
|
3716
|
-
console.error(colors.yellow(' npm whoami'));
|
|
3717
|
-
}
|
|
3718
|
-
console.error('');
|
|
3719
|
-
console.error('After logging in, try running this command again.');
|
|
3729
|
+
console.error(colors.red(`Not authenticated to npm (${authStatus.error}) — run: npm login`));
|
|
3720
3730
|
return false;
|
|
3721
3731
|
}
|
|
3722
3732
|
if (verbose) {
|
|
@@ -3738,9 +3748,40 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3738
3748
|
return false;
|
|
3739
3749
|
}
|
|
3740
3750
|
const tarballPath = path.join(cwd, tarballName);
|
|
3741
|
-
if
|
|
3742
|
-
|
|
3751
|
+
// Check tarball size — warn if suspiciously large
|
|
3752
|
+
try {
|
|
3753
|
+
const tarballSize = fs.statSync(tarballPath).size;
|
|
3754
|
+
const sizeMB = tarballSize / (1024 * 1024);
|
|
3755
|
+
if (sizeMB > 50) {
|
|
3756
|
+
console.error(colors.red(`\n⚠ Tarball is ${sizeMB.toFixed(0)}MB — something large is being included!`));
|
|
3757
|
+
// Show biggest files in the tarball
|
|
3758
|
+
const listResult = runCommand('npm', ['pack', '--dry-run'], { cwd, silent: true });
|
|
3759
|
+
if (listResult.success) {
|
|
3760
|
+
const lines = listResult.output.trim().split('\n')
|
|
3761
|
+
.filter(l => l.includes('B '))
|
|
3762
|
+
.map(l => { const m = l.match(/([\d.]+[kMG]?B)\s+(.*)/); return m ? { size: m[1], file: m[2] } : null; })
|
|
3763
|
+
.filter(Boolean)
|
|
3764
|
+
.filter((e) => e.size.includes('M') || e.size.includes('G'))
|
|
3765
|
+
.slice(0, 10);
|
|
3766
|
+
if (lines.length > 0) {
|
|
3767
|
+
console.error(colors.yellow(' Large files in tarball:'));
|
|
3768
|
+
for (const e of lines)
|
|
3769
|
+
console.error(colors.yellow(` ${e.size}\t${e.file}`));
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
console.error(colors.yellow(' Check .npmignore — you may need to exclude large files or directories.'));
|
|
3773
|
+
// Clean up and abort
|
|
3774
|
+
try {
|
|
3775
|
+
fs.unlinkSync(tarballPath);
|
|
3776
|
+
}
|
|
3777
|
+
catch { /* */ }
|
|
3778
|
+
return false;
|
|
3779
|
+
}
|
|
3780
|
+
if (verbose) {
|
|
3781
|
+
console.log(` Tarball: ${tarballName} (${sizeMB.toFixed(1)}MB)`);
|
|
3782
|
+
}
|
|
3743
3783
|
}
|
|
3784
|
+
catch { /* proceed if stat fails */ }
|
|
3744
3785
|
// Publish the tarball
|
|
3745
3786
|
const npmArgs = ['publish', tarballName];
|
|
3746
3787
|
// Determine access level (use effectiveNpmVisibility which accounts for current npm status)
|
|
@@ -3789,78 +3830,22 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3789
3830
|
}
|
|
3790
3831
|
if (!publishResult.success) {
|
|
3791
3832
|
console.error(colors.red('\nERROR: npm publish failed\n'));
|
|
3792
|
-
//
|
|
3793
|
-
if (publishResult.stderr && publishResult.stderr.trim()) {
|
|
3794
|
-
console.error('npm error output:');
|
|
3795
|
-
console.error(publishResult.stderr.trim());
|
|
3796
|
-
console.error('');
|
|
3797
|
-
}
|
|
3798
|
-
else if (publishResult.output && publishResult.output.trim()) {
|
|
3799
|
-
console.error('npm output:');
|
|
3800
|
-
console.error(publishResult.output.trim());
|
|
3801
|
-
console.error('');
|
|
3802
|
-
}
|
|
3803
|
-
// Check for E409 conflict (publishing too fast)
|
|
3833
|
+
// Check for specific error types
|
|
3804
3834
|
const output = (publishResult.output + '\n' + publishResult.stderr).toLowerCase();
|
|
3805
|
-
if (output.includes('
|
|
3806
|
-
console.error(colors.
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
console.error(colors.
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
// Extract the version number from the error if possible
|
|
3816
|
-
const versionMatch = output.match(/versions?[:\s]+(\d+\.\d+\.\d+)/);
|
|
3817
|
-
const failedVersion = versionMatch ? versionMatch[1] : null;
|
|
3818
|
-
// Check if this is the version we just bumped to
|
|
3819
|
-
const currentPkgVersion = readPackageJson(cwd).version;
|
|
3820
|
-
const isCurrentVersion = failedVersion === currentPkgVersion;
|
|
3821
|
-
console.error(colors.yellow('⚠ Version already published to npm'));
|
|
3822
|
-
console.error('');
|
|
3823
|
-
if (isCurrentVersion) {
|
|
3824
|
-
console.error(colors.green('✓ Good news: This version was already published (possibly just now)'));
|
|
3825
|
-
console.error('');
|
|
3826
|
-
console.error('The git commit and tag were created, but npm says this version exists.');
|
|
3827
|
-
console.error('This is actually SUCCESS - your package is published!');
|
|
3828
|
-
console.error('');
|
|
3829
|
-
console.error('Verify with: ' + colors.yellow(`npm view ${pkg.name}@${currentPkgVersion}`));
|
|
3830
|
-
console.error('');
|
|
3831
|
-
console.error(colors.yellow('Note: You may have a postversion script that auto-publishes.'));
|
|
3832
|
-
console.error(colors.yellow('npmglobalize will now skip that hook to prevent this issue.'));
|
|
3833
|
-
console.error('');
|
|
3834
|
-
// Treat as success and continue
|
|
3835
|
-
console.log(colors.green('✓ Treating as successful publish'));
|
|
3836
|
-
// Don't return false - let it continue to push git tags
|
|
3837
|
-
}
|
|
3838
|
-
else {
|
|
3839
|
-
console.error('Version ' + colors.yellow(failedVersion || 'unknown') + ' is already on npm.');
|
|
3840
|
-
console.error('This shouldn\'t happen - the version was bumped but publish failed.');
|
|
3841
|
-
console.error('');
|
|
3842
|
-
console.error(colors.yellow('To recover:'));
|
|
3843
|
-
console.error(' Just run npmglobalize again (it will bump to next version)');
|
|
3844
|
-
console.error('');
|
|
3845
|
-
if (transformResult.transformed) {
|
|
3846
|
-
console.log('Restoring file: dependencies...');
|
|
3847
|
-
const failPkg = readPackageJson(cwd);
|
|
3848
|
-
restoreDeps(failPkg, verbose);
|
|
3849
|
-
writePackageJson(cwd, failPkg);
|
|
3850
|
-
runCommand('git', ['add', 'package.json'], { cwd, silent: true });
|
|
3851
|
-
gitCommit('Restore file: dependencies', cwd);
|
|
3852
|
-
}
|
|
3853
|
-
return false;
|
|
3854
|
-
}
|
|
3835
|
+
if (output.includes('err_string_too_long') || output.includes('string longer than')) {
|
|
3836
|
+
console.error(colors.red('Tarball too large — check .npmignore. Run: npm pack --dry-run'));
|
|
3837
|
+
}
|
|
3838
|
+
else if (output.includes('e409') || output.includes('409 conflict')) {
|
|
3839
|
+
console.error(colors.yellow('npm still processing previous version — wait and retry'));
|
|
3840
|
+
}
|
|
3841
|
+
else if (output.includes('cannot publish over') || output.includes('previously published')) {
|
|
3842
|
+
const currentPkgVersion = readPackageJson(cwd).version;
|
|
3843
|
+
if (output.includes(currentPkgVersion)) {
|
|
3844
|
+
console.log(colors.green('✓ Already published — continuing'));
|
|
3855
3845
|
}
|
|
3856
3846
|
else {
|
|
3857
|
-
console.error(colors.yellow('
|
|
3858
|
-
console.error(' 1. Package name already taken by another user');
|
|
3859
|
-
console.error(' 2. No publish access to this package');
|
|
3860
|
-
console.error(' 3. Scope (@username) requires authentication');
|
|
3861
|
-
console.error('');
|
|
3847
|
+
console.error(colors.yellow('Version conflict — run npmglobalize again'));
|
|
3862
3848
|
if (transformResult.transformed) {
|
|
3863
|
-
console.log('Restoring file: dependencies...');
|
|
3864
3849
|
const failPkg = readPackageJson(cwd);
|
|
3865
3850
|
restoreDeps(failPkg, verbose);
|
|
3866
3851
|
writePackageJson(cwd, failPkg);
|
|
@@ -3870,18 +3855,22 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3870
3855
|
return false;
|
|
3871
3856
|
}
|
|
3872
3857
|
}
|
|
3858
|
+
else if (output.includes('403') || output.includes('forbidden')) {
|
|
3859
|
+
console.error(colors.yellow('Publish forbidden — check npm login and package access'));
|
|
3860
|
+
if (transformResult.transformed) {
|
|
3861
|
+
const failPkg = readPackageJson(cwd);
|
|
3862
|
+
restoreDeps(failPkg, verbose);
|
|
3863
|
+
writePackageJson(cwd, failPkg);
|
|
3864
|
+
runCommand('git', ['add', 'package.json'], { cwd, silent: true });
|
|
3865
|
+
gitCommit('Restore file: dependencies', cwd);
|
|
3866
|
+
}
|
|
3867
|
+
return false;
|
|
3868
|
+
}
|
|
3873
3869
|
else if (output.includes('402') || output.includes('payment required')) {
|
|
3874
|
-
console.error(colors.yellow('Private packages
|
|
3875
|
-
console.error(' • Use --npm public to publish as public');
|
|
3876
|
-
console.error(' • Or upgrade your npm account for private packages');
|
|
3877
|
-
console.error('');
|
|
3870
|
+
console.error(colors.yellow('Private packages need paid npm account — use --npm public'));
|
|
3878
3871
|
}
|
|
3879
3872
|
else {
|
|
3880
|
-
console.error(colors.yellow('
|
|
3881
|
-
console.error(' 1. Not logged in - run: npm login');
|
|
3882
|
-
console.error(' 2. Version already published');
|
|
3883
|
-
console.error(' 3. Authentication token expired');
|
|
3884
|
-
console.error('');
|
|
3873
|
+
console.error(colors.yellow('Publish failed — run npm login or check npm whoami'));
|
|
3885
3874
|
}
|
|
3886
3875
|
if (transformResult.transformed) {
|
|
3887
3876
|
console.log('Restoring file: dependencies...');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/npmglobalize",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.138",
|
|
4
4
|
"description": "Transform file: dependencies to npm versions for publishing",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
"url": "https://github.com/BobFrankston/npmglobalize.git"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@bobfrankston/freezepak": "^0.1.
|
|
35
|
-
"@bobfrankston/importgen": "^0.1.
|
|
34
|
+
"@bobfrankston/freezepak": "^0.1.6",
|
|
35
|
+
"@bobfrankston/importgen": "^0.1.32",
|
|
36
|
+
"@bobfrankston/themecolors": "^0.1.0",
|
|
36
37
|
"@bobfrankston/userconfig": "^1.0.5",
|
|
37
38
|
"@npmcli/package-json": "^7.0.4",
|
|
38
39
|
"json5": "^2.2.3",
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
".dependencies": {
|
|
48
49
|
"@bobfrankston/freezepak": "file:../freezepak",
|
|
49
50
|
"@bobfrankston/importgen": "file:../importgen",
|
|
51
|
+
"@bobfrankston/themecolors": "file:../themecolors",
|
|
50
52
|
"@bobfrankston/userconfig": "file:../userconfig",
|
|
51
53
|
"@npmcli/package-json": "^7.0.4",
|
|
52
54
|
"json5": "^2.2.3",
|
|
Binary file
|