@bobfrankston/npmglobalize 1.0.119 → 1.0.120

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.
Files changed (2) hide show
  1. package/lib.js +92 -0
  2. package/package.json +1 -1
package/lib.js CHANGED
@@ -2997,6 +2997,98 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2997
2997
  else if (!alreadyTransformed && verbose) {
2998
2998
  console.log(' No file: dependencies found.');
2999
2999
  }
3000
+ // Hoist workspace sub-package deps into root for publishing/global install.
3001
+ // npm install -g only installs root-level dependencies, so sub-package deps
3002
+ // like express must be present in the root package.json.
3003
+ // These are added temporarily — restoreDeps removes them via .dependencies backup.
3004
+ if (pkg.workspaces) {
3005
+ const wsPatterns = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces.packages || [];
3006
+ // Collect all workspace sub-package dirs
3007
+ const wsDirs = [];
3008
+ for (const pattern of wsPatterns) {
3009
+ if (pattern.includes('*')) {
3010
+ // Glob pattern like "packages/*" — enumerate subdirectories
3011
+ const baseDir = path.resolve(cwd, pattern.replace(/\/?\*$/, ''));
3012
+ if (!fs.existsSync(baseDir))
3013
+ continue;
3014
+ for (const entry of fs.readdirSync(baseDir, { withFileTypes: true })) {
3015
+ if (entry.isDirectory())
3016
+ wsDirs.push(path.join(baseDir, entry.name));
3017
+ }
3018
+ }
3019
+ else {
3020
+ // Direct directory like "client"
3021
+ const dir = path.resolve(cwd, pattern);
3022
+ if (fs.existsSync(dir))
3023
+ wsDirs.push(dir);
3024
+ }
3025
+ }
3026
+ // Collect all workspace package names (siblings to skip)
3027
+ const wsNames = new Set();
3028
+ for (const dir of wsDirs) {
3029
+ const pkgJsonPath = path.join(dir, 'package.json');
3030
+ if (!fs.existsSync(pkgJsonPath))
3031
+ continue;
3032
+ try {
3033
+ const subPkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
3034
+ if (subPkg.name)
3035
+ wsNames.add(subPkg.name);
3036
+ }
3037
+ catch { /* skip */ }
3038
+ }
3039
+ // Find deps in sub-packages not present in root
3040
+ const rootDeps = { ...pkg.dependencies, ...pkg.devDependencies };
3041
+ const hoisted = [];
3042
+ for (const dir of wsDirs) {
3043
+ const pkgJsonPath = path.join(dir, 'package.json');
3044
+ if (!fs.existsSync(pkgJsonPath))
3045
+ continue;
3046
+ let subPkg;
3047
+ try {
3048
+ subPkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
3049
+ }
3050
+ catch {
3051
+ continue;
3052
+ }
3053
+ const deps = subPkg.dependencies || {};
3054
+ for (const [dep, ver] of Object.entries(deps)) {
3055
+ if (wsNames.has(dep))
3056
+ continue; // sibling workspace — bundled
3057
+ if (dep in rootDeps)
3058
+ continue; // already in root
3059
+ if (hoisted.some(m => m.dep === dep))
3060
+ continue;
3061
+ hoisted.push({ dep, version: ver, from: subPkg.name || path.basename(dir) });
3062
+ }
3063
+ }
3064
+ if (hoisted.length > 0) {
3065
+ // Ensure .dependencies backup exists so restoreDeps will remove hoisted deps
3066
+ if (!pkg['.dependencies']) {
3067
+ pkg['.dependencies'] = { ...(pkg.dependencies || {}) };
3068
+ transformResult.transformed = true;
3069
+ }
3070
+ if (!pkg.dependencies)
3071
+ pkg.dependencies = {};
3072
+ for (const m of hoisted) {
3073
+ let version = m.version;
3074
+ if (typeof version === 'string' && version.startsWith('file:')) {
3075
+ const depDir = path.resolve(cwd, version.replace('file:', ''));
3076
+ try {
3077
+ const depPkg = readPackageJson(depDir);
3078
+ version = '^' + depPkg.version;
3079
+ }
3080
+ catch {
3081
+ // keep original if unresolvable
3082
+ }
3083
+ }
3084
+ pkg.dependencies[m.dep] = version;
3085
+ console.log(colors.green(` + hoisted ${m.dep}: ${version} (from ${m.from})`));
3086
+ }
3087
+ if (!dryRun) {
3088
+ writePackageJson(cwd, pkg);
3089
+ }
3090
+ }
3091
+ }
3000
3092
  // Run npm audit if requested or if dependencies were transformed
3001
3093
  if ((fix || updateDeps) && (transformResult.transformed || alreadyTransformed || updateDeps)) {
3002
3094
  if (!dryRun) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.119",
3
+ "version": "1.0.120",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",