@bobfrankston/npmglobalize 1.0.153 → 1.0.154

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 (4) hide show
  1. package/cli.js +2 -1
  2. package/lib.d.ts +6 -0
  3. package/lib.js +52 -0
  4. package/package.json +4 -1
package/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * npmglobalize CLI - Transform file: dependencies to npm versions for publishing
4
4
  */
5
- import { globalize, globalizeWorkspace, installCleanupHandlers, readConfig, readPackageJson, readUserNpmConfig, writeConfig, writePackageJson, confirm, getBuildIssues, clearBuildIssues, recordBuildIssue, extractFirstTscError } from './lib.js';
5
+ import { globalize, globalizeWorkspace, installCleanupHandlers, readConfig, readPackageJson, readUserNpmConfig, writeConfig, writePackageJson, confirm, getBuildIssues, clearBuildIssues, recordBuildIssue, extractFirstTscError, ensureFileDepModules } from './lib.js';
6
6
  import fs from 'fs';
7
7
  import path from 'path';
8
8
  import { styleText } from 'util';
@@ -423,6 +423,7 @@ export async function main() {
423
423
  }
424
424
  }
425
425
  if (pkg.scripts?.build) {
426
+ ensureFileDepModules(cwd, !!cliOptions.verbose);
426
427
  const { spawnSync } = await import('child_process');
427
428
  console.log(`Building ${cwd}...`);
428
429
  const buildResult = spawnSync('npm', ['run', 'build'], {
package/lib.d.ts CHANGED
@@ -234,6 +234,12 @@ export declare function parseVersionTag(tag: string): number[] | null;
234
234
  export declare function compareVersions(a: number[], b: number[]): number;
235
235
  /** Fix version/tag mismatches */
236
236
  export declare function fixVersionTagMismatch(cwd: string, pkg: any, verbose?: boolean): boolean;
237
+ /** Walk `file:` deps transitively and run `npm install` in any target whose
238
+ * package.json declares deps but has no `node_modules/`. Recovers from prior
239
+ * aborted runs (or pre-1.0.153 `--clean-nested-modules` damage) so the
240
+ * upcoming build/pack can resolve transitive package imports.
241
+ * Cycle-safe via the shared `visited` set. */
242
+ export declare function ensureFileDepModules(cwd: string, verbose?: boolean, visited?: Set<string>): void;
237
243
  /** Run a command and return success status */
238
244
  export declare function runCommand(cmd: string, args: string[], options?: {
239
245
  silent?: boolean;
package/lib.js CHANGED
@@ -1315,6 +1315,56 @@ function restoreNestedDepModules(stashed, verbose) {
1315
1315
  }
1316
1316
  }
1317
1317
  }
1318
+ /** Walk `file:` deps transitively and run `npm install` in any target whose
1319
+ * package.json declares deps but has no `node_modules/`. Recovers from prior
1320
+ * aborted runs (or pre-1.0.153 `--clean-nested-modules` damage) so the
1321
+ * upcoming build/pack can resolve transitive package imports.
1322
+ * Cycle-safe via the shared `visited` set. */
1323
+ export function ensureFileDepModules(cwd, verbose = false, visited = new Set()) {
1324
+ const abs = path.resolve(cwd);
1325
+ if (visited.has(abs))
1326
+ return;
1327
+ visited.add(abs);
1328
+ let pkg;
1329
+ try {
1330
+ pkg = readPackageJson(cwd);
1331
+ }
1332
+ catch {
1333
+ return;
1334
+ }
1335
+ for (const key of ['dependencies', 'devDependencies']) {
1336
+ const deps = pkg?.[key];
1337
+ if (!deps || typeof deps !== 'object')
1338
+ continue;
1339
+ for (const [name, spec] of Object.entries(deps)) {
1340
+ if (typeof spec !== 'string' || !spec.startsWith('file:'))
1341
+ continue;
1342
+ const target = path.resolve(cwd, spec.slice('file:'.length));
1343
+ if (!fs.existsSync(path.join(target, 'package.json')))
1344
+ continue;
1345
+ let targetPkg;
1346
+ try {
1347
+ targetPkg = readPackageJson(target);
1348
+ }
1349
+ catch {
1350
+ continue;
1351
+ }
1352
+ const hasDeps = (targetPkg?.dependencies && Object.keys(targetPkg.dependencies).length > 0) ||
1353
+ (targetPkg?.devDependencies && Object.keys(targetPkg.devDependencies).length > 0);
1354
+ const nm = path.join(target, 'node_modules');
1355
+ if (hasDeps && !fs.existsSync(nm)) {
1356
+ console.log(colors.yellow(`↻ restoring node_modules in ${name} (${target})`));
1357
+ const r = runCommand('npm', ['install'], { cwd: target, silent: !verbose });
1358
+ if (!r.success) {
1359
+ console.error(colors.red(` ✗ npm install failed in ${target}`));
1360
+ if (r.stderr)
1361
+ console.error(colors.dim(r.stderr.split('\n').slice(0, 5).join('\n')));
1362
+ }
1363
+ }
1364
+ ensureFileDepModules(target, verbose, visited);
1365
+ }
1366
+ }
1367
+ }
1318
1368
  /** Run npm install -g with retries for registry propagation delay */
1319
1369
  function installGlobalWithRetry(pkgSpec, cwd, maxRetries = 3) {
1320
1370
  let result = runCommand('npm', ['install', '-g', pkgSpec], { cwd, silent: false, showCommand: true });
@@ -3061,6 +3111,8 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3061
3111
  const pkg = readPackageJson(cwd);
3062
3112
  // Run build step if package.json has a build script (skip if CLI already built)
3063
3113
  if (pkg.scripts?.build && !options._fromCli) {
3114
+ if (!dryRun)
3115
+ ensureFileDepModules(cwd, verbose);
3064
3116
  console.log(`${timestamp()} Running build...`);
3065
3117
  if (!dryRun) {
3066
3118
  // Always capture output so we can extract tsc errors for the summary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.153",
3
+ "version": "1.0.154",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -33,6 +33,7 @@
33
33
  "dependencies": {
34
34
  "@bobfrankston/freezepak": "^0.1.7",
35
35
  "@bobfrankston/importgen": "^0.1.34",
36
+ "@bobfrankston/npmglobalize": "^1.0.153",
36
37
  "@bobfrankston/themecolors": "^0.1.5",
37
38
  "@bobfrankston/userconfig": "^1.0.7",
38
39
  "@npmcli/package-json": "^7.0.4",
@@ -48,6 +49,7 @@
48
49
  ".dependencies": {
49
50
  "@bobfrankston/freezepak": "file:../freezepak",
50
51
  "@bobfrankston/importgen": "file:../importgen",
52
+ "@bobfrankston/npmglobalize": "^1.0.153",
51
53
  "@bobfrankston/themecolors": "file:../themecolors",
52
54
  "@bobfrankston/userconfig": "file:../userconfig",
53
55
  "@npmcli/package-json": "^7.0.4",
@@ -61,6 +63,7 @@
61
63
  "dependencies": {
62
64
  "@bobfrankston/freezepak": "^0.1.7",
63
65
  "@bobfrankston/importgen": "^0.1.34",
66
+ "@bobfrankston/npmglobalize": "^1.0.153",
64
67
  "@bobfrankston/themecolors": "^0.1.5",
65
68
  "@bobfrankston/userconfig": "^1.0.7",
66
69
  "@npmcli/package-json": "^7.0.4",