@bobfrankston/npmglobalize 1.0.110 → 1.0.111
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.
- package/README.md +3 -1
- package/cli.js +1 -0
- package/lib.js +54 -9
- 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
|
-
|
|
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() :
|
|
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
|
-
|
|
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
|
|
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('✓')}`);
|