@bobfrankston/npmglobalize 1.0.110 → 1.0.112

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 +3 -1
  2. package/cli.js +1 -0
  3. package/lib.js +54 -9
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -179,7 +179,8 @@ When initializing a new repository with `--init`, npmglobalize automatically set
179
179
 
180
180
  **File structure** (per programming.md standards):
181
181
  - `.gitignore` - Node.js best practices (node_modules, secrets, certificates, etc.)
182
- - `.npmignore` - Publishing filters (excludes .git, tests, source files, etc.)
182
+ - `.npmignore` - Publishing filters (excludes .git, tests, source files, etc.)
183
+ - **noEmit projects:** `*.ts`, `*.map`, and `tsconfig.json` are kept (not ignored) since TS files are the runtime files
183
184
  - `.gitattributes` - Forces LF line endings for all text files
184
185
 
185
186
  **Git configuration** (ensures cross-platform compatibility):
@@ -298,6 +299,7 @@ Workspace mode is auto-detected when run from a root with `"private": true` and
298
299
  -verbose Show detailed output
299
300
  -conform Update .gitignore/.npmignore/.gitattributes to best practices
300
301
  and configure git for LF line endings (fixes existing repos)
302
+ For noEmit projects: removes *.ts/*.map/tsconfig.json from .npmignore
301
303
  -asis Skip ignore file checks (or set "asis": true in .globalize.json5)
302
304
  -fix-tags Automatically fix version/tag mismatches
303
305
  -rebase Automatically rebase if local is behind remote
package/cli.js CHANGED
@@ -67,6 +67,7 @@ Other Options:
67
67
  -quiet Suppress npm warnings (default)
68
68
  -verbose Show detailed output
69
69
  -conform Update .gitignore/.npmignore to best practices
70
+ (noEmit projects: removes TS ignores from .npmignore)
70
71
  -asis Skip ignore file checks (or set "asis": true in .globalize.json5)
71
72
  -rebase Automatically rebase if local is behind remote
72
73
  -show Show package.json dependency changes
package/lib.js CHANGED
@@ -1338,6 +1338,29 @@ const IGNORE_PATTERNS = loadIgnorePatterns();
1338
1338
  const ALL_GITIGNORE = [...IGNORE_PATTERNS.gitignore.security, ...IGNORE_PATTERNS.gitignore.recommended, ...(IGNORE_PATTERNS.gitignore.presenceOnly ?? [])];
1339
1339
  /** All .npmignore patterns (security + recommended) */
1340
1340
  const ALL_NPMIGNORE = [...IGNORE_PATTERNS.npmignore.security, ...IGNORE_PATTERNS.npmignore.recommended];
1341
+ /** Patterns that should NOT be in .npmignore for noEmit projects (TS files are the runtime files) */
1342
+ const TS_NPMIGNORE_PATTERNS = new Set(['*.ts', '!*.d.ts', '*.map', 'tsconfig.json']);
1343
+ /** Check if target project uses noEmit (TS files run directly, no compilation) */
1344
+ function isNoEmitProject(cwd) {
1345
+ const tsconfigPath = path.join(cwd, 'tsconfig.json');
1346
+ if (!fs.existsSync(tsconfigPath))
1347
+ return false;
1348
+ try {
1349
+ const content = fs.readFileSync(tsconfigPath, 'utf-8');
1350
+ const tsconfig = JSON5.parse(content);
1351
+ return tsconfig.compilerOptions?.noEmit === true;
1352
+ }
1353
+ catch {
1354
+ return false;
1355
+ }
1356
+ }
1357
+ /** Get applicable npmignore patterns, excluding TS patterns for noEmit projects */
1358
+ function getApplicableNpmignorePatterns(cwd) {
1359
+ if (isNoEmitProject(cwd)) {
1360
+ return ALL_NPMIGNORE.filter(p => !TS_NPMIGNORE_PATTERNS.has(p));
1361
+ }
1362
+ return ALL_NPMIGNORE;
1363
+ }
1341
1364
  /** Presence-only extensions derived from data file */
1342
1365
  const PRESENCE_ONLY_EXTENSIONS = new Set((IGNORE_PATTERNS.gitignore.presenceOnly ?? [])
1343
1366
  .map(p => p.match(/^\*(\.\w+)$/)?.[1])
@@ -1417,7 +1440,8 @@ function checkIgnoreFiles(cwd, options) {
1417
1440
  if (fs.existsSync(npmignorePath)) {
1418
1441
  const content = fs.readFileSync(npmignorePath, 'utf-8');
1419
1442
  const lines = content.split('\n').map(l => l.trim());
1420
- for (const pattern of ALL_NPMIGNORE) {
1443
+ const applicableNpm = getApplicableNpmignorePatterns(cwd);
1444
+ for (const pattern of applicableNpm) {
1421
1445
  if (!lineHasPattern(lines, pattern)) {
1422
1446
  if (securityNpm.has(pattern)) {
1423
1447
  securityChanges.push(` .npmignore missing: ${pattern}`);
@@ -1452,7 +1476,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
1452
1476
  }
1453
1477
  }
1454
1478
  const patternsGit = securityOnly ? getSecurityGitignorePatterns() : getApplicableGitignorePatterns(cwd);
1455
- const patternsNpm = securityOnly ? getSecurityNpmignorePatterns() : ALL_NPMIGNORE;
1479
+ const patternsNpm = securityOnly ? getSecurityNpmignorePatterns() : getApplicableNpmignorePatterns(cwd);
1480
+ const noEmit = isNoEmitProject(cwd);
1456
1481
  // Update .gitignore
1457
1482
  const gitignorePath = path.join(cwd, '.gitignore');
1458
1483
  if (fs.existsSync(gitignorePath)) {
@@ -1479,8 +1504,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
1479
1504
  const lines = content.split('\n').map(l => l.trim());
1480
1505
  const newLines = new Set(lines.filter(l => l));
1481
1506
  let updated = false;
1482
- if (!securityOnly) {
1483
- // Add TypeScript exclusions (only in full conform)
1507
+ if (!securityOnly && !noEmit) {
1508
+ // Add TypeScript exclusions (only in full conform, skip for noEmit projects)
1484
1509
  for (const ts of ['*.ts', '!*.d.ts', '*.map']) {
1485
1510
  if (!newLines.has(ts)) {
1486
1511
  newLines.add(ts);
@@ -1488,6 +1513,15 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
1488
1513
  }
1489
1514
  }
1490
1515
  }
1516
+ // For noEmit projects, remove TS patterns that shouldn't be ignored
1517
+ if (noEmit) {
1518
+ for (const ts of TS_NPMIGNORE_PATTERNS) {
1519
+ if (newLines.has(ts)) {
1520
+ newLines.delete(ts);
1521
+ updated = true;
1522
+ }
1523
+ }
1524
+ }
1491
1525
  for (const pattern of patternsNpm) {
1492
1526
  if (!newLines.has(pattern)) {
1493
1527
  newLines.add(pattern);
@@ -1497,7 +1531,12 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
1497
1531
  if (updated) {
1498
1532
  const newContent = Array.from(newLines).join('\n') + '\n';
1499
1533
  fs.writeFileSync(npmignorePath, newContent);
1500
- console.log(colors.cyan(' ✓ Auto-added security patterns to .npmignore'));
1534
+ if (noEmit) {
1535
+ console.log(colors.cyan(' ✓ .npmignore updated (noEmit: kept *.ts files)'));
1536
+ }
1537
+ else {
1538
+ console.log(colors.cyan(' ✓ Auto-added security patterns to .npmignore'));
1539
+ }
1501
1540
  }
1502
1541
  }
1503
1542
  }
@@ -1547,7 +1586,8 @@ function ensureNpmignore(cwd) {
1547
1586
  const npmignorePath = path.join(cwd, '.npmignore');
1548
1587
  if (!fs.existsSync(npmignorePath)) {
1549
1588
  console.log(' Creating .npmignore...');
1550
- const content = ALL_NPMIGNORE.join('\n') + '\n';
1589
+ const patterns = getApplicableNpmignorePatterns(cwd);
1590
+ const content = patterns.join('\n') + '\n';
1551
1591
  fs.writeFileSync(npmignorePath, content);
1552
1592
  console.log(colors.green(' ✓ .npmignore created'));
1553
1593
  }
@@ -3310,6 +3350,8 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3310
3350
  const updatedPkg = readPackageJson(cwd); // Re-read to get updated version
3311
3351
  const pkgName = updatedPkg.name;
3312
3352
  const pkgVersion = updatedPkg.version;
3353
+ let globalInstallOk = false;
3354
+ let wslInstallOk = false;
3313
3355
  if (!updatedPkg.bin && (install || link || wsl)) {
3314
3356
  const proceed = await offerAddBin(cwd, updatedPkg);
3315
3357
  if (!proceed) {
@@ -3323,6 +3365,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3323
3365
  if (!dryRun) {
3324
3366
  const installResult = runCommand('npm', ['install', '-g', '.'], { cwd, silent: false, showCommand: true });
3325
3367
  if (installResult.success) {
3368
+ globalInstallOk = true;
3326
3369
  console.log(colors.green(`✓ Linked globally: ${pkgName}@${pkgVersion}`));
3327
3370
  }
3328
3371
  else {
@@ -3340,6 +3383,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3340
3383
  waitForNpmVersion(pkgName, pkgVersion);
3341
3384
  const installResult = installGlobalWithRetry(`${pkgName}@${pkgVersion}`, cwd);
3342
3385
  if (installResult.success) {
3386
+ globalInstallOk = true;
3343
3387
  console.log(colors.green(`✓ Installed globally: ${pkgName}@${pkgVersion}`));
3344
3388
  }
3345
3389
  else {
@@ -3359,6 +3403,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3359
3403
  if (!dryRun) {
3360
3404
  const wslResult = runCommand('wsl', wslArgs, { cwd, silent: false, showCommand: true });
3361
3405
  if (wslResult.success) {
3406
+ wslInstallOk = true;
3362
3407
  console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}`));
3363
3408
  }
3364
3409
  else {
@@ -3424,13 +3469,13 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
3424
3469
  console.log(` Git visibility: ${colors.green(gitVisibility.toUpperCase())}`);
3425
3470
  }
3426
3471
  if (link) {
3427
- console.log(` Linked globally: ${colors.green('✓')}`);
3472
+ console.log(` Linked globally: ${globalInstallOk ? colors.green('✓') : colors.red('✗')}`);
3428
3473
  }
3429
3474
  else if (install) {
3430
- console.log(` Installed globally: ${colors.green('✓')}`);
3475
+ console.log(` Installed globally: ${globalInstallOk ? colors.green('✓') : colors.red('✗')}`);
3431
3476
  }
3432
3477
  if (wsl) {
3433
- console.log(` Installed in WSL: ${colors.green('✓')}`);
3478
+ console.log(` Installed in WSL: ${wslInstallOk ? colors.green('✓') : colors.red('✗')}`);
3434
3479
  }
3435
3480
  if (freeze) {
3436
3481
  console.log(` Frozen node_modules: ${colors.green('✓')}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.110",
3
+ "version": "1.0.112",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",