@bobfrankston/npmglobalize 1.0.139 → 1.0.140
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/lib/types.d.ts +2 -10
- package/lib/types.js +3 -11
- package/lib.js +45 -28
- package/package.json +2 -2
package/lib/types.d.ts
CHANGED
|
@@ -6,16 +6,8 @@ import { type SpawnSyncOptions, type SpawnSyncReturns } from 'child_process';
|
|
|
6
6
|
/** Wrapper for spawnSync that avoids DEP0190 (args + shell: true).
|
|
7
7
|
* When shell is true, joins cmd+args into a single command string. */
|
|
8
8
|
export declare function spawnSafe(cmd: string, args: string[], options?: SpawnSyncOptions): SpawnSyncReturns<string>;
|
|
9
|
-
/**
|
|
10
|
-
export declare const colors:
|
|
11
|
-
red: (text: string) => string;
|
|
12
|
-
yellow: (text: string) => string;
|
|
13
|
-
green: (text: string) => string;
|
|
14
|
-
italic: (text: string) => string;
|
|
15
|
-
blue: (text: string) => string;
|
|
16
|
-
cyan: (text: string) => string;
|
|
17
|
-
dim: (text: string) => string;
|
|
18
|
-
};
|
|
9
|
+
/** Semantic color functions — adapts to terminal light/dark theme */
|
|
10
|
+
export declare const colors: import("@bobfrankston/themecolors").SemanticColors;
|
|
19
11
|
/** Get npm command for current platform (npm.cmd on Windows, npm elsewhere) */
|
|
20
12
|
export declare function getNpmCommand(): string;
|
|
21
13
|
/** Options for the globalize operation */
|
package/lib/types.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Leaf module — no internal dependencies.
|
|
4
4
|
*/
|
|
5
5
|
import { spawnSync } from 'child_process';
|
|
6
|
-
import {
|
|
6
|
+
import { themeColors } from '@bobfrankston/themecolors';
|
|
7
7
|
import readline from 'readline';
|
|
8
8
|
/** Wrapper for spawnSync that avoids DEP0190 (args + shell: true).
|
|
9
9
|
* When shell is true, joins cmd+args into a single command string. */
|
|
@@ -16,16 +16,8 @@ export function spawnSafe(cmd, args, options = {}) {
|
|
|
16
16
|
}
|
|
17
17
|
return spawnSync(cmd, args, opts);
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
export const colors =
|
|
21
|
-
red: (text) => styleText('red', text),
|
|
22
|
-
yellow: (text) => styleText('yellow', text),
|
|
23
|
-
green: (text) => styleText('green', text),
|
|
24
|
-
italic: (text) => styleText('italic', text),
|
|
25
|
-
blue: (text) => styleText('blue', text),
|
|
26
|
-
cyan: (text) => styleText('cyan', text),
|
|
27
|
-
dim: (text) => styleText('dim', text),
|
|
28
|
-
};
|
|
19
|
+
/** Semantic color functions — adapts to terminal light/dark theme */
|
|
20
|
+
export const colors = themeColors();
|
|
29
21
|
/** Get npm command for current platform (npm.cmd on Windows, npm elsewhere) */
|
|
30
22
|
export function getNpmCommand() {
|
|
31
23
|
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
package/lib.js
CHANGED
|
@@ -137,6 +137,10 @@ function getNpmCommand() {
|
|
|
137
137
|
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
138
138
|
}
|
|
139
139
|
const DEP_KEYS = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];
|
|
140
|
+
/** Format current time as HH:MM:SS for progress timestamps */
|
|
141
|
+
function timestamp() {
|
|
142
|
+
return colors.dim(new Date().toLocaleTimeString('en-US', { hour12: false }));
|
|
143
|
+
}
|
|
140
144
|
/** Read and parse package.json from a directory */
|
|
141
145
|
export function readPackageJson(dir) {
|
|
142
146
|
const pkgPath = path.join(dir, 'package.json');
|
|
@@ -1003,7 +1007,7 @@ export function fixVersionTagMismatch(cwd, pkg, verbose = false) {
|
|
|
1003
1007
|
function waitForNpmVersion(pkgName, version, maxWaitMs = 90000) {
|
|
1004
1008
|
const interval = 3000;
|
|
1005
1009
|
const maxAttempts = Math.ceil(maxWaitMs / interval);
|
|
1006
|
-
process.stdout.write(
|
|
1010
|
+
process.stdout.write(`${timestamp()} Waiting for ${pkgName}@${version} on npm registry`);
|
|
1007
1011
|
for (let i = 0; i < maxAttempts; i++) {
|
|
1008
1012
|
const result = spawnSafe('npm', ['view', `${pkgName}@${version}`, 'version'], {
|
|
1009
1013
|
shell: process.platform === 'win32',
|
|
@@ -2637,7 +2641,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2637
2641
|
const pkg = readPackageJson(cwd);
|
|
2638
2642
|
// Run build step if package.json has a build script (skip if CLI already built)
|
|
2639
2643
|
if (pkg.scripts?.build && !options._fromCli) {
|
|
2640
|
-
console.log(
|
|
2644
|
+
console.log(`${timestamp()} Running build...`);
|
|
2641
2645
|
if (!dryRun) {
|
|
2642
2646
|
const buildResult = runCommand('npm', ['run', 'build'], { cwd, silent: !verbose });
|
|
2643
2647
|
if (!buildResult.success) {
|
|
@@ -2648,7 +2652,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2648
2652
|
console.log(colors.yellow('Continuing with --force despite build failure...'));
|
|
2649
2653
|
}
|
|
2650
2654
|
else {
|
|
2651
|
-
console.log(colors.green('✓ Build succeeded'));
|
|
2655
|
+
console.log(`${timestamp()} ${colors.green('✓ Build succeeded')}`);
|
|
2652
2656
|
}
|
|
2653
2657
|
}
|
|
2654
2658
|
else {
|
|
@@ -3392,7 +3396,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3392
3396
|
// Git operations
|
|
3393
3397
|
if (currentGitStatus.hasUncommitted) {
|
|
3394
3398
|
const commitMsg = message || 'Pre-release commit';
|
|
3395
|
-
console.log(
|
|
3399
|
+
console.log(`${timestamp()} Committing changes: ${commitMsg}`);
|
|
3396
3400
|
if (!dryRun) {
|
|
3397
3401
|
// Remove 'nul' files that break git on Windows
|
|
3398
3402
|
const nulCount = removeNulFiles(cwd);
|
|
@@ -3490,7 +3494,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3490
3494
|
console.log(`Skipping version bump — ${pkg.version} already set locally.`);
|
|
3491
3495
|
}
|
|
3492
3496
|
else {
|
|
3493
|
-
console.log(
|
|
3497
|
+
console.log(`${timestamp()} Bumping version (${bump})...`);
|
|
3494
3498
|
}
|
|
3495
3499
|
if (!dryRun && !skipVersionBump) {
|
|
3496
3500
|
// Temporarily disable postversion hook to prevent double-publishing or push
|
|
@@ -3734,38 +3738,51 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3734
3738
|
else if (!skipVersionBump) {
|
|
3735
3739
|
console.log(` [dry-run] Would run: npm version ${bump}`);
|
|
3736
3740
|
}
|
|
3737
|
-
// Check for public package depending on private dependencies
|
|
3741
|
+
// Check for public package depending on private/unpublished scoped dependencies
|
|
3742
|
+
// Only scoped deps can be private — unscoped are always public on npm.
|
|
3743
|
+
// Use a single fast `npm view` per dep instead of the full checkNpmAccess.
|
|
3738
3744
|
const publishAccess = effectiveNpmVisibility || currentAccess || (isScoped ? 'restricted' : 'public');
|
|
3739
3745
|
if (publishAccess === 'public') {
|
|
3740
|
-
const
|
|
3746
|
+
const scopedDeps = [];
|
|
3741
3747
|
for (const depKey of ['dependencies', 'peerDependencies']) {
|
|
3742
3748
|
const deps = pkg[depKey];
|
|
3743
3749
|
if (!deps)
|
|
3744
3750
|
continue;
|
|
3745
3751
|
for (const depName of Object.keys(deps)) {
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
privateDeps.push(depName);
|
|
3749
|
-
}
|
|
3750
|
-
else if (depAccess === null && depName.startsWith('@')) {
|
|
3751
|
-
// Scoped package not on npm — will be private by default
|
|
3752
|
-
privateDeps.push(`${depName} (not yet published)`);
|
|
3753
|
-
}
|
|
3752
|
+
if (depName.startsWith('@'))
|
|
3753
|
+
scopedDeps.push(depName);
|
|
3754
3754
|
}
|
|
3755
3755
|
}
|
|
3756
|
-
if (
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3756
|
+
if (scopedDeps.length > 0) {
|
|
3757
|
+
const privateDeps = [];
|
|
3758
|
+
for (const depName of scopedDeps) {
|
|
3759
|
+
const viewResult = spawnSafe('npm', ['view', depName, 'name'], {
|
|
3760
|
+
encoding: 'utf-8', stdio: 'pipe', shell: true
|
|
3761
|
+
});
|
|
3762
|
+
if (viewResult.status !== 0) {
|
|
3763
|
+
const stderr = viewResult.stderr || '';
|
|
3764
|
+
if (stderr.includes('404') || stderr.includes('not found')) {
|
|
3765
|
+
privateDeps.push(`${depName} (not on npm)`);
|
|
3766
|
+
}
|
|
3767
|
+
else {
|
|
3768
|
+
privateDeps.push(`${depName} (restricted)`);
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
if (privateDeps.length > 0) {
|
|
3773
|
+
console.log('');
|
|
3774
|
+
console.error(colors.red('WARNING: Public package depends on PRIVATE/missing dependencies:'));
|
|
3775
|
+
for (const d of privateDeps) {
|
|
3776
|
+
console.error(colors.red(` ${d}`));
|
|
3777
|
+
}
|
|
3778
|
+
console.error(colors.yellow('Consumers will get E404 when installing this package.'));
|
|
3779
|
+
console.error(colors.yellow('Fix: publish those deps as public, or make this package private.'));
|
|
3780
|
+
console.log('');
|
|
3761
3781
|
}
|
|
3762
|
-
console.error(colors.yellow('Consumers will get E404 when installing this package.'));
|
|
3763
|
-
console.error(colors.yellow('Fix: publish those deps as public, or make this package private.'));
|
|
3764
|
-
console.log('');
|
|
3765
3782
|
}
|
|
3766
3783
|
}
|
|
3767
3784
|
// Publish
|
|
3768
|
-
console.log(
|
|
3785
|
+
console.log(`${timestamp()} Publishing to npm...`);
|
|
3769
3786
|
if (!dryRun) {
|
|
3770
3787
|
// Check npm authentication right before publishing
|
|
3771
3788
|
const authStatus = checkNpmAuth();
|
|
@@ -3929,7 +3946,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3929
3946
|
// Determine what was published
|
|
3930
3947
|
const finalAccess = effectiveNpmVisibility || currentAccess || (isScoped ? 'restricted' : 'public');
|
|
3931
3948
|
const accessLabel = (finalAccess === 'restricted' || finalAccess === 'private') ? 'PRIVATE' : 'PUBLIC';
|
|
3932
|
-
console.log(colors.green(`✓ Published to npm as ${accessLabel}`));
|
|
3949
|
+
console.log(`${timestamp()} ${colors.green(`✓ Published to npm as ${accessLabel}`)}`);
|
|
3933
3950
|
}
|
|
3934
3951
|
else {
|
|
3935
3952
|
console.log(` [dry-run] Would run: npm publish ${quiet ? '--quiet' : ''}`);
|
|
@@ -3937,7 +3954,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3937
3954
|
// Push to git (with push-protection detection and auto-bypass)
|
|
3938
3955
|
if (currentGitStatus.hasRemote) {
|
|
3939
3956
|
if (verbose) {
|
|
3940
|
-
console.log(
|
|
3957
|
+
console.log(`${timestamp()} Pushing to git...`);
|
|
3941
3958
|
}
|
|
3942
3959
|
if (!dryRun) {
|
|
3943
3960
|
if (pushWithProtection(cwd, verbose)) {
|
|
@@ -4001,7 +4018,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
4001
4018
|
}
|
|
4002
4019
|
}
|
|
4003
4020
|
else {
|
|
4004
|
-
console.log(
|
|
4021
|
+
console.log(`${timestamp()} Installing globally from registry: ${pkgName}@${pkgVersion}...`);
|
|
4005
4022
|
if (!dryRun) {
|
|
4006
4023
|
waitForNpmVersion(pkgName, pkgVersion);
|
|
4007
4024
|
const installResult = installGlobalWithRetry(`${pkgName}@${pkgVersion}`, cwd);
|
|
@@ -4072,7 +4089,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
4072
4089
|
else if (!files) {
|
|
4073
4090
|
console.log('Keeping npm versions (--nofiles mode).');
|
|
4074
4091
|
}
|
|
4075
|
-
console.log(
|
|
4092
|
+
console.log(`${timestamp()} Done!`);
|
|
4076
4093
|
// Run final audit report if not already run
|
|
4077
4094
|
const auditAlreadyRun = (fix || updateDeps) && (transformResult.transformed || alreadyTransformed || updateDeps);
|
|
4078
4095
|
if (!auditAlreadyRun && (fix || updateDeps || transformResult.transformed) && !dryRun) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/npmglobalize",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.140",
|
|
4
4
|
"description": "Transform file: dependencies to npm versions for publishing",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@bobfrankston/freezepak": "^0.1.6",
|
|
35
35
|
"@bobfrankston/importgen": "^0.1.32",
|
|
36
|
-
"@bobfrankston/themecolors": "^0.1.
|
|
36
|
+
"@bobfrankston/themecolors": "^0.1.4",
|
|
37
37
|
"@bobfrankston/userconfig": "^1.0.6",
|
|
38
38
|
"@npmcli/package-json": "^7.0.4",
|
|
39
39
|
"json5": "^2.2.3",
|