@bobfrankston/npmglobalize 1.0.140 → 1.0.141

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 +94 -0
  2. package/package.json +1 -1
package/lib.js CHANGED
@@ -1072,6 +1072,96 @@ export function runCommand(cmd, args, options = {}) {
1072
1072
  return { success: false, output: '', stderr: error.message };
1073
1073
  }
1074
1074
  }
1075
+ /** Diagnose common build/version failure patterns and print actionable hints.
1076
+ * Returns true if a diagnosis was printed. */
1077
+ function diagnoseBuildFailure(errorText, cwd) {
1078
+ let diagnosed = false;
1079
+ // Pattern: missing module / package not found
1080
+ const missingPkg = errorText.match(/Cannot find (?:package|module) ['"](@?[^'"\/]+(?:\/[^'"\/]+)?)/);
1081
+ if (missingPkg) {
1082
+ const pkgName = missingPkg[1];
1083
+ console.error(colors.yellow(`\n Hint: missing package "${pkgName}"`));
1084
+ // Check for broken symlinks in node_modules tree
1085
+ const searchDirs = [cwd];
1086
+ try {
1087
+ for (const entry of fs.readdirSync(cwd, { withFileTypes: true })) {
1088
+ if (entry.isDirectory() && entry.name !== 'node_modules' && entry.name !== '.git' && entry.name !== 'prev') {
1089
+ searchDirs.push(path.join(cwd, entry.name));
1090
+ }
1091
+ }
1092
+ }
1093
+ catch { /* ignore */ }
1094
+ for (const dir of searchDirs) {
1095
+ const nmPath = path.join(dir, 'node_modules', ...pkgName.split('/'));
1096
+ try {
1097
+ const stat = fs.lstatSync(nmPath);
1098
+ if (stat.isSymbolicLink()) {
1099
+ const target = fs.readlinkSync(nmPath);
1100
+ const resolved = path.resolve(path.dirname(nmPath), target);
1101
+ if (!fs.existsSync(resolved)) {
1102
+ console.error(colors.yellow(` Broken symlink: ${nmPath}`));
1103
+ console.error(colors.yellow(` → ${resolved} (target missing)`));
1104
+ console.error(colors.yellow(` Fix: cd "${dir}" && npm install`));
1105
+ diagnosed = true;
1106
+ }
1107
+ else {
1108
+ console.error(colors.yellow(` Symlink exists at ${nmPath} but module still failed to load.`));
1109
+ console.error(colors.yellow(` Check that the target package has been built (has .js files).`));
1110
+ diagnosed = true;
1111
+ }
1112
+ }
1113
+ }
1114
+ catch {
1115
+ // No symlink found at this location — check if it should exist
1116
+ const subPkgPath = path.join(dir, 'package.json');
1117
+ if (fs.existsSync(subPkgPath)) {
1118
+ try {
1119
+ const subPkg = JSON.parse(fs.readFileSync(subPkgPath, 'utf-8'));
1120
+ const allDeps = { ...subPkg.dependencies, ...subPkg.devDependencies };
1121
+ if (allDeps[pkgName]) {
1122
+ const depValue = allDeps[pkgName];
1123
+ if (typeof depValue === 'string' && depValue.startsWith('file:')) {
1124
+ const target = path.resolve(dir, depValue.replace('file:', ''));
1125
+ console.error(colors.yellow(` "${pkgName}" is a file: dep in ${path.relative(cwd, subPkgPath) || 'package.json'}`));
1126
+ console.error(colors.yellow(` → ${target}`));
1127
+ if (!fs.existsSync(target)) {
1128
+ console.error(colors.yellow(` Target directory does not exist!`));
1129
+ }
1130
+ else {
1131
+ console.error(colors.yellow(` Fix: cd "${dir}" && npm install`));
1132
+ }
1133
+ diagnosed = true;
1134
+ }
1135
+ else {
1136
+ console.error(colors.yellow(` "${pkgName}" is listed in ${path.relative(cwd, subPkgPath) || 'package.json'} but not installed.`));
1137
+ console.error(colors.yellow(` Fix: cd "${dir}" && npm install`));
1138
+ diagnosed = true;
1139
+ }
1140
+ }
1141
+ }
1142
+ catch { /* ignore parse errors */ }
1143
+ }
1144
+ }
1145
+ }
1146
+ if (!diagnosed) {
1147
+ console.error(colors.yellow(` "${pkgName}" is not installed and not listed as a dependency.`));
1148
+ console.error(colors.yellow(` If needed, add it: npm install ${pkgName}`));
1149
+ diagnosed = true;
1150
+ }
1151
+ }
1152
+ // Pattern: permission denied
1153
+ if (!diagnosed && /permission denied|EPERM|EACCES/.test(errorText)) {
1154
+ console.error(colors.yellow('\n Hint: permission error during build.'));
1155
+ console.error(colors.yellow(' Check file ownership and that no other process has files locked.'));
1156
+ diagnosed = true;
1157
+ }
1158
+ // Pattern: TypeScript compilation error
1159
+ if (!diagnosed && /error TS\d+/.test(errorText)) {
1160
+ console.error(colors.yellow('\n Hint: TypeScript compilation errors. Fix the type errors above before publishing.'));
1161
+ diagnosed = true;
1162
+ }
1163
+ return diagnosed;
1164
+ }
1075
1165
  /** Run git commit silently and print a compact summary (no per-file create/delete mode lines). */
1076
1166
  function gitCommit(msg, cwd) {
1077
1167
  const result = runCommand('git', ['commit', '-m', msg], { cwd, silent: true });
@@ -2646,6 +2736,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
2646
2736
  const buildResult = runCommand('npm', ['run', 'build'], { cwd, silent: !verbose });
2647
2737
  if (!buildResult.success) {
2648
2738
  console.error(colors.red('ERROR: Build failed:'), buildResult.stderr || buildResult.output);
2739
+ diagnoseBuildFailure(buildResult.stderr || buildResult.output || '', cwd);
2649
2740
  if (!force) {
2650
2741
  return false;
2651
2742
  }
@@ -3551,6 +3642,9 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3551
3642
  if (error.code)
3552
3643
  console.error(' exit code:', error.code);
3553
3644
  }
3645
+ // Diagnose common failures (missing modules, permissions, TS errors)
3646
+ const versionErrorText = [error.message, error.stderr, error.stdout].filter(Boolean).join('\n');
3647
+ diagnoseBuildFailure(versionErrorText, cwd);
3554
3648
  // Show the full error stack in verbose mode
3555
3649
  if (verbose && error.stack) {
3556
3650
  console.error(' Stack trace:', error.stack);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.140",
3
+ "version": "1.0.141",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",