@bobfrankston/npmglobalize 1.0.218 → 1.0.220

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/README.md +1 -1
  2. package/lib.d.ts +15 -16
  3. package/lib.js +134 -69
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -756,7 +756,7 @@ As with import maps, these have historically been built only by a second `.vscod
756
756
  Before building, `npmglobalize` looks for sub-projects, in this order:
757
757
 
758
758
  1. `.vscode/tasks.json` has a task that runs `tsc` or `importgen` with `"options": { "cwd": "${workspaceFolder}/client" }`, or runs `tsc` with `-p`/`--project` naming a sub-directory (authoritative — it's how the project is actually built today; the task's `label` is quoted back in the prompt).
759
- 2. An immediate sub-directory containing its own `package.json` build script or `tsconfig.json`. Build output and vendored trees (`node_modules`, `prev`, `dist`, `built`, `out`, `wwwroot`, `coverage`, `temp`, `preflight`, dot-directories) are never scanned.
759
+ 2. An immediate sub-directory that is a build of its own: a `package.json` with a `build` script or an import map to regenerate (a sub-package gets its build script set up the same way the root does — importgen, `tsc`, its own sub-projects — before the root delegates to it), or a `tsconfig.json` the root `tsconfig.json` does not already compile. A `package.json` that only holds dependencies for files the root `tsc` compiles (`whts/pdfToImg`) is not a sub-project. Build output and vendored trees (`node_modules`, `prev`, `dist`, `built`, `out`, `wwwroot`, `coverage`, `temp`, `preflight`, dot-directories) are never scanned.
760
760
 
761
761
  Nothing is detected when the root `tsconfig.json` uses project `references` — that build graph belongs to `tsc -b` and isn't second-guessed.
762
762
 
package/lib.d.ts CHANGED
@@ -397,16 +397,6 @@ export declare function missingDeps(pkgDir: string, pkg: any): string[];
397
397
  * re-run" (partial-sync) cases. Also covers `cwd` itself on the first call.
398
398
  * Cycle-safe via the shared `visited` set. */
399
399
  export declare function ensureFileDepModules(cwd: string, verbose?: boolean, visited?: Set<string>): Promise<boolean>;
400
- /** Cheap freshness check so the build cascade can skip packages whose output is
401
- * already current. Returns true only when provably up to date:
402
- * - outDir projects: newest source (.ts/.tsx/.mts/.cts + tsconfig*.json) must
403
- * not be newer than the newest file under outDir.
404
- * - side-by-side projects: every source must have an emitted sibling
405
- * (.js/.jsx/.mjs/.cjs or declaration) at least as new.
406
- * Conservative: project references, allowJs, missing outputs, or unreadable
407
- * tsconfig all report stale (→ build). package.json mtime is deliberately
408
- * ignored — npmglobalize itself rewrites it around every publish, which would
409
- * otherwise force a rebuild on every run. */
410
400
  export declare function isBuildUpToDate(cwd: string): boolean;
411
401
  /** Detect whether a package is an importgen project — a browser app whose HTML
412
402
  * carries a generated `<script type="importmap">`. Signals, in order:
@@ -430,7 +420,7 @@ export declare function ensureImportgenInBuild(cwd: string): Promise<void>;
430
420
  /** A sub-directory the root build must build, and how. */
431
421
  interface SubProject {
432
422
  dir: string; /** Relative directory with its on-disk casing */
433
- kind: 'package' | 'tsconfig'; /** package: delegate to its build script; tsconfig: `tsc -p` */
423
+ kind: 'package' | 'tsconfig'; /** package: has its own package.json, delegate to its build script; tsconfig: `tsc -p` */
434
424
  reason: string; /** The signal that found it, quoted in prompts */
435
425
  }
436
426
  /** Sub-directories the root build must build itself. A package can hold more
@@ -452,11 +442,20 @@ export declare function detectSubProjects(cwd: string): SubProject[];
452
442
  * own idea of what to compile. Declining records `subProjects: false` in
453
443
  * .globalize.json5. */
454
444
  export declare function ensureSubProjectsInBuild(cwd: string): Promise<void>;
455
- /** Build a single project: detect tsconfig, prompt to add `build: tsc` if a
456
- * TypeScript project lacks a build script, run `npm run build`, record
457
- * failures. Returns true if build succeeded (or was skipped because no
458
- * tsconfig / noEmit / no build script after declining the prompt / output
459
- * already up to date). Pass `forceBuild` to skip the freshness check. */
445
+ /** Make sure `cwd`'s package.json has the build script it needs: importgen
446
+ * for an importgen project, `tsc` for a TypeScript project (prompted), and a
447
+ * step per sub-project. Returns the package plus whether the script runs
448
+ * importgen, or null when there is nothing to build here (no package.json, no
449
+ * tsconfig or `noEmit` and no importgen, or the user declined the prompt). */
450
+ export declare function ensureBuildScript(cwd: string): Promise<{
451
+ pkg: any;
452
+ runsImportgen: boolean;
453
+ } | null>;
454
+ /** Build a single project: set up its build script (see `ensureBuildScript`),
455
+ * run `npm run build`, record failures. Returns true if build succeeded (or
456
+ * was skipped because there was nothing to build / the user declined the
457
+ * build-script prompt / output already up to date). Pass `forceBuild` to
458
+ * skip the freshness check. */
460
459
  export declare function buildProject(cwd: string, opts?: {
461
460
  verbose?: boolean;
462
461
  force?: boolean;
package/lib.js CHANGED
@@ -2888,6 +2888,35 @@ function newestMtimeUnder(dir) {
2888
2888
  * tsconfig all report stale (→ build). package.json mtime is deliberately
2889
2889
  * ignored — npmglobalize itself rewrites it around every publish, which would
2890
2890
  * otherwise force a rebuild on every run. */
2891
+ /** The directories a parsed tsconfig's `exclude` keeps out of the compile, as
2892
+ * lower-cased relative paths. Matches on the literal path prefix (glob tails
2893
+ * like "tests/**" reduce to "tests"). */
2894
+ function tsconfigExcludedDirs(tsconfig) {
2895
+ return (Array.isArray(tsconfig?.exclude) ? tsconfig.exclude : [])
2896
+ .filter((x) => typeof x === 'string')
2897
+ .map((x) => x.replace(/^\.\//, '').replace(/[\\/]?\*.*$/, '').replace(/[\\/]+$/, '').toLowerCase())
2898
+ .filter((x) => x.length > 0 && !x.includes('*'));
2899
+ }
2900
+ /** True when the root tsconfig in `cwd` already compiles the sources under
2901
+ * `rel`: it exists, doesn't narrow the compile with `files`/`include`, and
2902
+ * doesn't `exclude` the directory. Conservative — a root that uses `include`
2903
+ * is treated as not covering the sub-directory. */
2904
+ function rootTsconfigCompiles(cwd, rel) {
2905
+ let tsconfig;
2906
+ try {
2907
+ tsconfig = JSON5.parse(fs.readFileSync(path.join(cwd, 'tsconfig.json'), 'utf-8'));
2908
+ }
2909
+ catch {
2910
+ return false;
2911
+ }
2912
+ if (Array.isArray(tsconfig.files) || Array.isArray(tsconfig.include))
2913
+ return false;
2914
+ const target = normalizeProjectPath(rel).toLowerCase();
2915
+ const parts = target.split('/');
2916
+ const excludes = tsconfigExcludedDirs(tsconfig);
2917
+ // Excluding a parent excludes everything under it.
2918
+ return !parts.some((_, i) => excludes.includes(parts.slice(0, i + 1).join('/')));
2919
+ }
2891
2920
  export function isBuildUpToDate(cwd) {
2892
2921
  let tsconfig;
2893
2922
  try {
@@ -2901,12 +2930,8 @@ export function isBuildUpToDate(cwd) {
2901
2930
  return false;
2902
2931
  const outDir = typeof co.outDir === 'string' ? path.resolve(cwd, co.outDir) : null;
2903
2932
  // tsconfig "exclude" dirs aren't compiled, so their .ts files never get
2904
- // outputs — don't count them as sources. Match on the literal path prefix
2905
- // (glob tails like "tests/**" reduce to "tests").
2906
- const excludes = (Array.isArray(tsconfig.exclude) ? tsconfig.exclude : [])
2907
- .filter((x) => typeof x === 'string')
2908
- .map((x) => x.replace(/^\.\//, '').replace(/[\\/]?\*.*$/, '').replace(/[\\/]+$/, '').toLowerCase())
2909
- .filter((x) => x.length > 0 && !x.includes('*'));
2933
+ // outputs — don't count them as sources.
2934
+ const excludes = tsconfigExcludedDirs(tsconfig);
2910
2935
  const sources = [];
2911
2936
  const collect = (dir, rel) => {
2912
2937
  let entries;
@@ -3198,18 +3223,31 @@ function resolveOnDiskCase(base, rel) {
3198
3223
  }
3199
3224
  return out.length ? out.join('/') : null;
3200
3225
  }
3201
- /** Classify `rel` under `cwd`: a package with its own build script, a plain
3202
- * tsconfig sub-project, or null when it's neither. */
3226
+ /** Classify `rel` under `cwd`: a package (its own package.json with a build
3227
+ * script, or an importgen project `ensureBuildScript` sets its script up),
3228
+ * a plain tsconfig sub-project the root tsc doesn't compile, or null when it
3229
+ * is neither.
3230
+ * 2026-09-06 — Claude Code (Fable 5.1), at Bob's direction. whts/pdfToImg has
3231
+ * a package.json that only holds puppeteer/sharp for a file the root tsc
3232
+ * already compiles; treating every package.json as a sub-package gave it a
3233
+ * `build: tsc` it never needed and a second compile under its stale tsconfig.
3234
+ * A package.json is a build of its own only when it has something the root
3235
+ * can't do — its own build script, or an import map to regenerate. */
3203
3236
  function subProjectKind(cwd, rel) {
3204
- try {
3205
- const pkg = readPackageJson(path.join(cwd, rel));
3206
- if (typeof pkg?.scripts?.build === 'string' && pkg.scripts.build.trim())
3237
+ const dir = path.join(cwd, rel);
3238
+ if (fs.existsSync(path.join(dir, 'package.json'))) {
3239
+ let pkg = {};
3240
+ try {
3241
+ pkg = readPackageJson(dir);
3242
+ }
3243
+ catch { /* unreadable — treat as having no build script */ }
3244
+ const hasBuild = typeof pkg?.scripts?.build === 'string' && pkg.scripts.build.trim();
3245
+ if (hasBuild || detectImportgen(dir))
3207
3246
  return 'package';
3208
3247
  }
3209
- catch {
3210
- // No package.json there — fall through to the tsconfig test
3211
- }
3212
- return fs.existsSync(path.join(cwd, rel, 'tsconfig.json')) ? 'tsconfig' : null;
3248
+ if (!fs.existsSync(path.join(dir, 'tsconfig.json')))
3249
+ return null;
3250
+ return rootTsconfigCompiles(cwd, rel) ? null : 'tsconfig';
3213
3251
  }
3214
3252
  /** The command the root build script runs for a sub-project. */
3215
3253
  function subProjectBuildCommand(s) {
@@ -3303,7 +3341,7 @@ export function detectSubProjects(cwd) {
3303
3341
  continue;
3304
3342
  const kind = subProjectKind(cwd, e.name);
3305
3343
  if (kind)
3306
- add(e.name, kind === 'package' ? `${e.name}/package.json has a build script` : `${e.name}/tsconfig.json`);
3344
+ add(e.name, kind === 'package' ? `${e.name}/package.json` : `${e.name}/tsconfig.json`);
3307
3345
  }
3308
3346
  }
3309
3347
  catch {
@@ -3328,6 +3366,20 @@ function configuredSubProjects(cwd, config) {
3328
3366
  }
3329
3367
  return detectSubProjects(cwd);
3330
3368
  }
3369
+ /** The sub-projects the root build should run, each ready to be run: a
3370
+ * sub-package gets its own build script set up first (importgen, tsc, its own
3371
+ * sub-projects — the same setup the root gets), and one that still has
3372
+ * nothing to build afterwards is left out, since delegating to it would only
3373
+ * fail with "missing script: build". */
3374
+ async function readySubProjects(cwd, config) {
3375
+ const ready = [];
3376
+ for (const s of configuredSubProjects(cwd, config)) {
3377
+ if (s.kind === 'package' && !(await ensureBuildScript(path.join(cwd, s.dir))))
3378
+ continue;
3379
+ ready.push(s);
3380
+ }
3381
+ return ready;
3382
+ }
3331
3383
  /** Quote a path for a package.json script only when it needs it. */
3332
3384
  function quoteScriptPath(p) {
3333
3385
  return /[\s&|<>]/.test(p) ? `"${p}"` : p;
@@ -3351,14 +3403,8 @@ export async function ensureSubProjectsInBuild(cwd) {
3351
3403
  const buildScript = typeof pkg.scripts?.build === 'string' ? pkg.scripts.build.trim() : '';
3352
3404
  if (!buildScript || !scriptRunsTsc(buildScript))
3353
3405
  return;
3354
- const subs = configuredSubProjects(cwd, config);
3355
- // A sub-package owns its own import map: give its build script the same
3356
- // importgen check the root gets, so delegating to it is enough.
3357
- for (const s of subs) {
3358
- if (s.kind === 'package')
3359
- await ensureImportgenInBuild(path.join(cwd, s.dir));
3360
- }
3361
- const missing = subs.filter(s => !scriptBuildsSubProject(buildScript, s.dir));
3406
+ const missing = (await readySubProjects(cwd, config))
3407
+ .filter(s => !scriptBuildsSubProject(buildScript, s.dir));
3362
3408
  if (missing.length === 0)
3363
3409
  return;
3364
3410
  const name = pkg.name || path.basename(cwd);
@@ -3367,7 +3413,7 @@ export async function ensureSubProjectsInBuild(cwd) {
3367
3413
  // — a bare nested tsconfig (tests, examples) is a weaker signal, and this
3368
3414
  // prompt rewrites a build script that currently works.
3369
3415
  const strong = missing.every(s => s.reason.startsWith('.vscode/tasks.json') || s.reason.startsWith('listed in'));
3370
- console.log(colors.yellow(`${name}'s build script doesn't compile ${missing.length === 1 ? 'a sub-project' : 'its sub-projects'}:`));
3416
+ console.log(colors.yellow(`${name}'s build script doesn't build ${missing.length === 1 ? 'a sub-project' : 'its sub-projects'}:`));
3371
3417
  for (const s of missing)
3372
3418
  console.log(colors.yellow(` ${s.dir}/ — ${s.reason}`));
3373
3419
  const addIt = await confirm(`Set "build": "${newScript}" in ${name}'s package.json?`, strong);
@@ -3417,76 +3463,61 @@ function areSubProjectsUpToDate(cwd, subs) {
3417
3463
  }
3418
3464
  return true;
3419
3465
  }
3420
- /** Build a single project: detect tsconfig, prompt to add `build: tsc` if a
3421
- * TypeScript project lacks a build script, run `npm run build`, record
3422
- * failures. Returns true if build succeeded (or was skipped because no
3423
- * tsconfig / noEmit / no build script after declining the prompt / output
3424
- * already up to date). Pass `forceBuild` to skip the freshness check. */
3425
- export async function buildProject(cwd, opts = {}) {
3466
+ // 2026-09-06 Claude Code (Fable 5.1), at Bob's direction ("when you add
3467
+ // importgen for a client dir you should set up the proper package.json").
3468
+ // Factored out of buildProject so a sub-package (itemw/client) gets the SAME
3469
+ // build-script setup as the root importgen wired in, `tsc` added when it has
3470
+ // a tsconfig, its own sub-projects appended instead of a second recipe.
3471
+ /** Make sure `cwd`'s package.json has the build script it needs: importgen
3472
+ * for an importgen project, `tsc` for a TypeScript project (prompted), and a
3473
+ * step per sub-project. Returns the package plus whether the script runs
3474
+ * importgen, or null when there is nothing to build here (no package.json, no
3475
+ * tsconfig or `noEmit` and no importgen, or the user declined the prompt). */
3476
+ export async function ensureBuildScript(cwd) {
3426
3477
  // Do this before the tsconfig check: an importgen project may be plain JS
3427
3478
  // with no tsconfig at all, and still need its import map regenerated.
3428
3479
  await ensureImportgenInBuild(cwd);
3429
3480
  let shouldBuild = false;
3430
- let hasTsconfig = false;
3431
3481
  try {
3432
- const tsconfigPath = path.join(cwd, 'tsconfig.json');
3433
- const content = fs.readFileSync(tsconfigPath, 'utf-8');
3434
- const tsconfig = JSON5.parse(content);
3435
- hasTsconfig = true;
3482
+ const tsconfig = JSON5.parse(fs.readFileSync(path.join(cwd, 'tsconfig.json'), 'utf-8'));
3436
3483
  shouldBuild = tsconfig.compilerOptions?.noEmit !== true;
3437
3484
  }
3438
3485
  catch {
3439
- // No tsconfig — skip
3486
+ // No tsconfig — nothing for tsc to do
3440
3487
  }
3441
- // Fix removed-in-TS7 tsconfig settings up front rather than waiting for a
3442
- // build to fail on them. A deprecated `moduleResolution` is only a *hard*
3443
- // error under the tsc that flags it (TS6+, and the editor's bundled
3444
- // compiler), so a package pinned to an older tsc — or one that never gets
3445
- // to the build at all (noEmit, no build script, output already fresh) —
3446
- // would otherwise keep the deprecation until TS7 removes it outright.
3447
- // Deliberately ahead of every early return below: the tsconfig is worth
3448
- // fixing whether or not this package builds. Migrating also touches
3449
- // tsconfig.json, which makes the freshness check correctly read as stale.
3450
- const tsconfigSnapshot = new Map();
3451
- const issueMark = markBuildIssues();
3452
- const migratedUpFront = hasTsconfig && migrateTsconfigDeprecations(cwd, tsconfigSnapshot);
3453
- let earlyPkg;
3488
+ let pkg;
3454
3489
  try {
3455
- earlyPkg = readPackageJson(cwd);
3490
+ pkg = readPackageJson(cwd);
3456
3491
  }
3457
3492
  catch {
3458
- return true;
3493
+ return null;
3459
3494
  }
3460
- const runsImportgen = scriptRunsImportgen(typeof earlyPkg.scripts?.build === 'string' ? earlyPkg.scripts.build : '');
3495
+ const runsImportgen = scriptRunsImportgen(typeof pkg.scripts?.build === 'string' ? pkg.scripts.build : '');
3461
3496
  // A build script that regenerates the import map is worth running even when
3462
3497
  // there's nothing for tsc to emit.
3463
3498
  if (!shouldBuild && !runsImportgen)
3464
- return true;
3465
- const pkg = earlyPkg;
3499
+ return null;
3466
3500
  const existingBuild = typeof pkg.scripts?.build === 'string' ? pkg.scripts.build.trim() : '';
3467
3501
  // A build script ensureImportgenInBuild just created for a package that had
3468
3502
  // none still needs its tsc pass — treat importgen-only as "no build yet".
3469
3503
  const importgenOnly = !!existingBuild && existingBuild.split(/\s*&&\s*/).every(scriptRunsImportgen);
3470
3504
  if (shouldBuild && (!existingBuild || importgenOnly)) {
3471
- // Compile the sub-projects (service worker, …) in the same breath: the
3472
- // root tsc excludes them, so a bare "tsc" would leave them unbuilt.
3473
- const subs = configuredSubProjects(cwd, readConfig(cwd));
3505
+ // Build the sub-projects (service worker, client package, …) in the same
3506
+ // breath: the root tsc excludes them, so a bare "tsc" would leave them unbuilt.
3507
+ const subs = await readySubProjects(cwd, readConfig(cwd));
3474
3508
  const tscParts = ['tsc', ...subs.map(subProjectBuildCommand)];
3475
3509
  const newScript = [...(existingBuild ? [existingBuild] : []), ...tscParts].join(' && ');
3476
3510
  console.log(colors.yellow(`TypeScript project has no "build" script in ${pkg.name || cwd}`));
3477
3511
  for (const s of subs)
3478
3512
  console.log(colors.yellow(` sub-project ${s.dir}/ — ${s.reason}`));
3479
3513
  const addIt = await confirm(`Add "build": "${newScript}" to ${pkg.name || path.basename(cwd)}'s package.json?`, true);
3480
- if (addIt) {
3481
- if (!pkg.scripts)
3482
- pkg.scripts = {};
3483
- pkg.scripts.build = newScript;
3484
- writePackageJson(cwd, pkg);
3485
- console.log(colors.green(`✓ Added "build": "${newScript}" to ${pkg.name || path.basename(cwd)}`));
3486
- }
3487
- else {
3488
- return true;
3489
- }
3514
+ if (!addIt)
3515
+ return null;
3516
+ if (!pkg.scripts)
3517
+ pkg.scripts = {};
3518
+ pkg.scripts.build = newScript;
3519
+ writePackageJson(cwd, pkg);
3520
+ console.log(colors.green(`✓ Added "build": "${newScript}" to ${pkg.name || path.basename(cwd)}`));
3490
3521
  }
3491
3522
  else if (existingBuild) {
3492
3523
  await ensureSubProjectsInBuild(cwd);
@@ -3498,10 +3529,44 @@ export async function buildProject(cwd, opts = {}) {
3498
3529
  catch { /* keep the script we already have */ }
3499
3530
  }
3500
3531
  ensureTsconfigNodeTypes(cwd);
3532
+ return { pkg, runsImportgen };
3533
+ }
3534
+ /** Build a single project: set up its build script (see `ensureBuildScript`),
3535
+ * run `npm run build`, record failures. Returns true if build succeeded (or
3536
+ * was skipped because there was nothing to build / the user declined the
3537
+ * build-script prompt / output already up to date). Pass `forceBuild` to
3538
+ * skip the freshness check. */
3539
+ export async function buildProject(cwd, opts = {}) {
3540
+ // Fix removed-in-TS7 tsconfig settings up front rather than waiting for a
3541
+ // build to fail on them. A deprecated `moduleResolution` is only a *hard*
3542
+ // error under the tsc that flags it (TS6+, and the editor's bundled
3543
+ // compiler), so a package pinned to an older tsc — or one that never gets
3544
+ // to the build at all (noEmit, no build script, output already fresh) —
3545
+ // would otherwise keep the deprecation until TS7 removes it outright.
3546
+ // Deliberately ahead of every early return below: the tsconfig is worth
3547
+ // fixing whether or not this package builds. Migrating also touches
3548
+ // tsconfig.json, which makes the freshness check correctly read as stale.
3549
+ const tsconfigSnapshot = new Map();
3550
+ const issueMark = markBuildIssues();
3551
+ let migratedUpFront = fs.existsSync(path.join(cwd, 'tsconfig.json')) && migrateTsconfigDeprecations(cwd, tsconfigSnapshot);
3552
+ const setup = await ensureBuildScript(cwd);
3553
+ if (!setup)
3554
+ return true;
3555
+ const { pkg, runsImportgen } = setup;
3501
3556
  // Only the sub-projects the final build script really compiles count toward
3502
3557
  // freshness — one the user declined to wire in isn't this build's business.
3503
3558
  const finalBuild = typeof pkg.scripts?.build === 'string' ? pkg.scripts.build : '';
3504
3559
  const wiredSubs = detectSubProjects(cwd).filter(s => scriptBuildsSubProject(finalBuild, s.dir));
3560
+ // 2026-09-06 — Claude Code (Fable 5.1), at Bob's direction.
3561
+ // The sub-projects this build runs get the same TS7 migration as the root.
3562
+ // whts: `tsc -p pdfToImg` failed on pdfToImg/tsconfig.json's
3563
+ // `moduleResolution: node10` (TS5107) and the retry below re-migrated only
3564
+ // the root chain, which had nothing left to fix — so no retry ever happened.
3565
+ const migrateSubProjects = () => wiredSubs
3566
+ .map(s => migrateTsconfigDeprecations(path.join(cwd, s.dir), tsconfigSnapshot))
3567
+ .some(Boolean);
3568
+ if (migrateSubProjects())
3569
+ migratedUpFront = true;
3505
3570
  // A migration just changed how modules resolve — never report that as fresh;
3506
3571
  // the rebuild is what validates it (and what the revert path above needs).
3507
3572
  if (!opts.forceBuild && !migratedUpFront && isBuildUpToDate(cwd) && areSubProjectsUpToDate(cwd, wiredSubs)
@@ -3517,7 +3582,7 @@ export async function buildProject(cwd, opts = {}) {
3517
3582
  // We don't silence with ignoreDeprecations — the retry may now surface real
3518
3583
  // resolution errors, which are genuine bugs to fix, not deprecations.
3519
3584
  const out = (buildResult.stderr || '') + (buildResult.output || '');
3520
- if (/error TS510[17]\b/.test(out) && migrateTsconfigDeprecations(cwd, tsconfigSnapshot)) {
3585
+ if (/error TS510[17]\b/.test(out) && [migrateTsconfigDeprecations(cwd, tsconfigSnapshot), migrateSubProjects()].some(Boolean)) {
3521
3586
  buildResult = await runCommandAsync('npm', ['run', 'build'], { cwd, silent: true });
3522
3587
  }
3523
3588
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.218",
3
+ "version": "1.0.220",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",