@bobfrankston/npmglobalize 1.0.121 → 1.0.123
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.js +86 -46
- package/package.json +1 -1
package/lib.js
CHANGED
|
@@ -2998,16 +2998,18 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2998
2998
|
console.log(' No file: dependencies found.');
|
|
2999
2999
|
}
|
|
3000
3000
|
// Hoist workspace sub-package deps into root for publishing/global install.
|
|
3001
|
-
// npm install -g only installs root-level dependencies
|
|
3002
|
-
//
|
|
3003
|
-
//
|
|
3001
|
+
// npm install -g only installs root-level dependencies and doesn't process
|
|
3002
|
+
// the workspaces field, so:
|
|
3003
|
+
// 1. Third-party deps (express, ws, etc.) must be in root dependencies
|
|
3004
|
+
// 2. Sibling workspace packages must be in bundledDependencies so npm
|
|
3005
|
+
// includes them in the tarball's node_modules/
|
|
3006
|
+
// All changes are temporary — restoreDeps removes them via .dependencies backup.
|
|
3004
3007
|
if (pkg.workspaces) {
|
|
3005
3008
|
const wsPatterns = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages || [];
|
|
3006
3009
|
// Collect all workspace sub-package dirs
|
|
3007
3010
|
const wsDirs = [];
|
|
3008
3011
|
for (const pattern of wsPatterns) {
|
|
3009
3012
|
if (pattern.includes('*')) {
|
|
3010
|
-
// Glob pattern like "packages/*" — enumerate subdirectories
|
|
3011
3013
|
const baseDir = path.resolve(cwd, pattern.replace(/\/?\*$/, ''));
|
|
3012
3014
|
if (!fs.existsSync(baseDir))
|
|
3013
3015
|
continue;
|
|
@@ -3017,14 +3019,13 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3017
3019
|
}
|
|
3018
3020
|
}
|
|
3019
3021
|
else {
|
|
3020
|
-
// Direct directory like "client"
|
|
3021
3022
|
const dir = path.resolve(cwd, pattern);
|
|
3022
3023
|
if (fs.existsSync(dir))
|
|
3023
3024
|
wsDirs.push(dir);
|
|
3024
3025
|
}
|
|
3025
3026
|
}
|
|
3026
|
-
// Collect
|
|
3027
|
-
const
|
|
3027
|
+
// Collect workspace package names and their relative paths
|
|
3028
|
+
const wsPackages = new Map(); // name -> relative dir
|
|
3028
3029
|
for (const dir of wsDirs) {
|
|
3029
3030
|
const pkgJsonPath = path.join(dir, 'package.json');
|
|
3030
3031
|
if (!fs.existsSync(pkgJsonPath))
|
|
@@ -3032,11 +3033,11 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3032
3033
|
try {
|
|
3033
3034
|
const subPkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
3034
3035
|
if (subPkg.name)
|
|
3035
|
-
|
|
3036
|
+
wsPackages.set(subPkg.name, path.relative(cwd, dir).replace(/\\/g, '/'));
|
|
3036
3037
|
}
|
|
3037
3038
|
catch { /* skip */ }
|
|
3038
3039
|
}
|
|
3039
|
-
// Find deps in sub-packages not present in root
|
|
3040
|
+
// Find third-party deps in sub-packages not present in root
|
|
3040
3041
|
const rootDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
3041
3042
|
const hoisted = [];
|
|
3042
3043
|
for (const dir of wsDirs) {
|
|
@@ -3052,8 +3053,8 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3052
3053
|
}
|
|
3053
3054
|
const deps = subPkg.dependencies || {};
|
|
3054
3055
|
for (const [dep, ver] of Object.entries(deps)) {
|
|
3055
|
-
if (
|
|
3056
|
-
continue; // sibling workspace —
|
|
3056
|
+
if (wsPackages.has(dep))
|
|
3057
|
+
continue; // sibling workspace — handled via bundledDependencies
|
|
3057
3058
|
if (dep in rootDeps)
|
|
3058
3059
|
continue; // already in root
|
|
3059
3060
|
if (hoisted.some(m => m.dep === dep))
|
|
@@ -3061,7 +3062,8 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3061
3062
|
hoisted.push({ dep, version: ver, from: subPkg.name || path.basename(dir) });
|
|
3062
3063
|
}
|
|
3063
3064
|
}
|
|
3064
|
-
|
|
3065
|
+
const needsUpdate = hoisted.length > 0 || wsPackages.size > 0;
|
|
3066
|
+
if (needsUpdate) {
|
|
3065
3067
|
// Ensure .dependencies backup exists so restoreDeps will remove hoisted deps
|
|
3066
3068
|
if (!pkg['.dependencies']) {
|
|
3067
3069
|
pkg['.dependencies'] = { ...(pkg.dependencies || {}) };
|
|
@@ -3069,6 +3071,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3069
3071
|
}
|
|
3070
3072
|
if (!pkg.dependencies)
|
|
3071
3073
|
pkg.dependencies = {};
|
|
3074
|
+
// Hoist third-party deps
|
|
3072
3075
|
for (const m of hoisted) {
|
|
3073
3076
|
let version = m.version;
|
|
3074
3077
|
if (typeof version === 'string' && version.startsWith('file:')) {
|
|
@@ -3225,40 +3228,56 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3225
3228
|
}
|
|
3226
3229
|
}
|
|
3227
3230
|
else if (install) {
|
|
3228
|
-
//
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
if (vOnNpm) {
|
|
3236
|
-
console.log(`Installing ${pkgName}@${pkgVersion} globally from registry...`);
|
|
3237
|
-
const registryInstallResult = installGlobalWithRetry(`${pkgName}@${pkgVersion}`, cwd);
|
|
3238
|
-
if (registryInstallResult.success) {
|
|
3231
|
+
// Workspace packages must install from local — npm install -g from
|
|
3232
|
+
// registry doesn't process workspaces, so sub-packages can't resolve
|
|
3233
|
+
// sibling imports. Local install handles workspace linking correctly.
|
|
3234
|
+
if (pkg.workspaces) {
|
|
3235
|
+
console.log(`Installing ${pkgName}@${pkgVersion} globally from local (workspace)...`);
|
|
3236
|
+
const localResult = runCommand('npm', ['install', '-g', '.'], { cwd, silent: false, showCommand: true });
|
|
3237
|
+
if (localResult.success) {
|
|
3239
3238
|
console.log(colors.green(`✓ Installed globally: ${pkgName}@${pkgVersion}`));
|
|
3240
3239
|
}
|
|
3241
3240
|
else {
|
|
3242
3241
|
console.error(colors.red(`✗ Global install failed`));
|
|
3243
|
-
console.error(colors.yellow(
|
|
3242
|
+
console.error(colors.yellow(' Try running manually: npm install -g .'));
|
|
3244
3243
|
}
|
|
3245
3244
|
}
|
|
3246
3245
|
else {
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3246
|
+
// Quick check: does this version actually exist on npm?
|
|
3247
|
+
const vCheck = spawnSafe('npm', ['view', `${pkgName}@${pkgVersion}`, 'version'], {
|
|
3248
|
+
shell: process.platform === 'win32',
|
|
3249
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
3250
|
+
encoding: 'utf-8'
|
|
3251
|
+
});
|
|
3252
|
+
const vOnNpm = vCheck.status === 0 && vCheck.stdout?.trim() === pkgVersion;
|
|
3253
|
+
if (vOnNpm) {
|
|
3254
|
+
console.log(`Installing ${pkgName}@${pkgVersion} globally from registry...`);
|
|
3255
|
+
const registryInstallResult = installGlobalWithRetry(`${pkgName}@${pkgVersion}`, cwd);
|
|
3256
|
+
if (registryInstallResult.success) {
|
|
3257
|
+
console.log(colors.green(`✓ Installed globally: ${pkgName}@${pkgVersion}`));
|
|
3258
|
+
}
|
|
3259
|
+
else {
|
|
3260
|
+
console.error(colors.red(`✗ Global install failed`));
|
|
3261
|
+
console.error(colors.yellow(` Try running manually: npm install -g ${pkgName}@${pkgVersion}`));
|
|
3262
|
+
}
|
|
3252
3263
|
}
|
|
3253
3264
|
else {
|
|
3254
|
-
console.
|
|
3255
|
-
console.
|
|
3265
|
+
console.log(colors.yellow(`${pkgName}@${pkgVersion} not found on npm — installing from local directory.`));
|
|
3266
|
+
console.log(colors.dim(' Use -m "message" to publish this version to npm.'));
|
|
3267
|
+
const localResult = runCommand('npm', ['install', '-g', '.'], { cwd, silent: false, showCommand: true });
|
|
3268
|
+
if (localResult.success) {
|
|
3269
|
+
console.log(colors.green(`✓ Installed globally from local: ${pkgName}@${pkgVersion}`));
|
|
3270
|
+
}
|
|
3271
|
+
else {
|
|
3272
|
+
console.error(colors.red(`✗ Local install failed`));
|
|
3273
|
+
console.error(colors.yellow(' Try running manually: npm install -g .'));
|
|
3274
|
+
}
|
|
3256
3275
|
}
|
|
3257
3276
|
}
|
|
3258
3277
|
}
|
|
3259
3278
|
if (wsl) {
|
|
3260
|
-
//
|
|
3261
|
-
const useLocal = link || (() => {
|
|
3279
|
+
// Workspace packages must install from local (see above)
|
|
3280
|
+
const useLocal = link || !!pkg.workspaces || (() => {
|
|
3262
3281
|
const vc = spawnSafe('npm', ['view', `${pkgName}@${pkgVersion}`, 'version'], {
|
|
3263
3282
|
shell: process.platform === 'win32',
|
|
3264
3283
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -3837,28 +3856,49 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3837
3856
|
}
|
|
3838
3857
|
}
|
|
3839
3858
|
else if (install) {
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3859
|
+
if (updatedPkg.workspaces) {
|
|
3860
|
+
// Workspace packages: install from local for proper workspace linking
|
|
3861
|
+
console.log(`Installing ${pkgName}@${pkgVersion} globally from local (workspace)...`);
|
|
3862
|
+
if (!dryRun) {
|
|
3863
|
+
const installResult = runCommand('npm', ['install', '-g', '.'], { cwd, silent: false, showCommand: true });
|
|
3864
|
+
if (installResult.success) {
|
|
3865
|
+
globalInstallOk = true;
|
|
3866
|
+
console.log(colors.green(`✓ Installed globally: ${pkgName}@${pkgVersion}`));
|
|
3867
|
+
}
|
|
3868
|
+
else {
|
|
3869
|
+
console.error(colors.red(`✗ Global install failed`));
|
|
3870
|
+
console.error(colors.yellow(' Try running manually: npm install -g .'));
|
|
3871
|
+
}
|
|
3847
3872
|
}
|
|
3848
3873
|
else {
|
|
3849
|
-
console.
|
|
3850
|
-
console.error(colors.yellow(` Try running manually: npm install -g ${pkgName}@${pkgVersion}`));
|
|
3874
|
+
console.log(` [dry-run] Would run: npm install -g .`);
|
|
3851
3875
|
}
|
|
3852
3876
|
}
|
|
3853
3877
|
else {
|
|
3854
|
-
console.log(`
|
|
3878
|
+
console.log(`Installing globally from registry: ${pkgName}@${pkgVersion}...`);
|
|
3879
|
+
if (!dryRun) {
|
|
3880
|
+
waitForNpmVersion(pkgName, pkgVersion);
|
|
3881
|
+
const installResult = installGlobalWithRetry(`${pkgName}@${pkgVersion}`, cwd);
|
|
3882
|
+
if (installResult.success) {
|
|
3883
|
+
globalInstallOk = true;
|
|
3884
|
+
console.log(colors.green(`✓ Installed globally: ${pkgName}@${pkgVersion}`));
|
|
3885
|
+
}
|
|
3886
|
+
else {
|
|
3887
|
+
console.error(colors.red(`✗ Global install failed`));
|
|
3888
|
+
console.error(colors.yellow(` Try running manually: npm install -g ${pkgName}@${pkgVersion}`));
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
else {
|
|
3892
|
+
console.log(` [dry-run] Would run: npm install -g ${pkgName}@${pkgVersion}`);
|
|
3893
|
+
}
|
|
3855
3894
|
}
|
|
3856
3895
|
}
|
|
3857
3896
|
if (wsl) {
|
|
3858
|
-
const
|
|
3859
|
-
|
|
3897
|
+
const useLocalWsl = link || !!updatedPkg.workspaces;
|
|
3898
|
+
const wslArgs = useLocalWsl ? ['npm', 'install', '-g', '.'] : ['npm', 'install', '-g', `${pkgName}@${pkgVersion}`];
|
|
3899
|
+
if (!useLocalWsl)
|
|
3860
3900
|
waitForNpmVersion(pkgName, pkgVersion);
|
|
3861
|
-
console.log(`Installing in WSL${
|
|
3901
|
+
console.log(`Installing in WSL${useLocalWsl ? ' (local)' : ' from registry'}: ${pkgName}@${pkgVersion}...`);
|
|
3862
3902
|
if (!dryRun) {
|
|
3863
3903
|
const wslResult = runCommand('wsl', wslArgs, { cwd, silent: false, showCommand: true });
|
|
3864
3904
|
if (wslResult.success) {
|