@bobfrankston/npmglobalize 1.0.154 → 1.0.156
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 +30 -3
- package/cli.js +37 -7
- package/lib/config.js +5 -1
- package/lib/types.d.ts +5 -0
- package/lib.d.ts +19 -1
- package/lib.js +93 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -301,6 +301,8 @@ Publishing requires being on a branch so commits and tags can be properly tracke
|
|
|
301
301
|
-force-publish Republish dependencies even if version exists
|
|
302
302
|
-fix Run npm audit fix after transformation
|
|
303
303
|
-no-fix Don't run npm audit
|
|
304
|
+
-no-use-paths, -nup Declare package standalone; do not resolve file: deps
|
|
305
|
+
from sibling checkouts (see Configuration File)
|
|
304
306
|
```
|
|
305
307
|
|
|
306
308
|
### Install Options
|
|
@@ -323,10 +325,21 @@ Publishing requires being on a branch so commits and tags can be properly tracke
|
|
|
323
325
|
-git private Set GitHub repo to private (default for new repos)
|
|
324
326
|
-git public Set GitHub repo to public (requires confirmation)
|
|
325
327
|
Works on both new and existing repos
|
|
326
|
-
-npm
|
|
327
|
-
|
|
328
|
+
-npm <values> Comma-separated list of npm options:
|
|
329
|
+
private (default) | public — package visibility
|
|
330
|
+
ts — keep .ts source (and *.map,
|
|
331
|
+
tsconfig.json) in npm tarball
|
|
332
|
+
nts — exclude .ts source
|
|
333
|
+
(default for non-noEmit projects)
|
|
334
|
+
Example: -npm public,ts
|
|
328
335
|
```
|
|
329
336
|
|
|
337
|
+
`ts` is already the default on git (source is tracked). Pass `-npm ts` to ship
|
|
338
|
+
the same files to npm — useful for debugging installed packages or "source on
|
|
339
|
+
demand" packages. `noEmit` projects automatically ship `.ts` files (they *are*
|
|
340
|
+
the runtime); pass `-npm nts` to override. `allowTs` persists to
|
|
341
|
+
`.globalize.json5`.
|
|
342
|
+
|
|
330
343
|
### Workspace Options
|
|
331
344
|
```
|
|
332
345
|
-w, -workspace <pkg> Filter to specific package (repeatable)
|
|
@@ -400,12 +413,26 @@ Settings can be saved in `.globalize.json5`:
|
|
|
400
413
|
"fix": true, // Auto-run npm audit fix
|
|
401
414
|
"verbose": false, // Show detailed output
|
|
402
415
|
"gitVisibility": "private",
|
|
403
|
-
"npmVisibility": "public"
|
|
416
|
+
"npmVisibility": "public",
|
|
417
|
+
"usePaths": true // Resolve file: deps from sibling checkouts (see below)
|
|
404
418
|
}
|
|
405
419
|
```
|
|
406
420
|
|
|
407
421
|
Configuration persists across runs. CLI flags override config file.
|
|
408
422
|
|
|
423
|
+
### `usePaths` — Standalone packages
|
|
424
|
+
|
|
425
|
+
Default: `true`. Set to `false` (or pass `-no-use-paths` / `-nup`) to mark a
|
|
426
|
+
package as **standalone** — one that should be publishable/installable on a
|
|
427
|
+
machine that does not have sibling `file:` dep checkouts available. Example:
|
|
428
|
+
a backup/recovery utility you want to `npm install -g` on any host.
|
|
429
|
+
|
|
430
|
+
Currently this setting is **declarative** — it is parsed, persisted to
|
|
431
|
+
`.globalize.json5`, and surfaced in the settings banner, but the tool does
|
|
432
|
+
not yet change its behavior based on it. Behavior wiring (e.g. resolving
|
|
433
|
+
`file:` deps to the latest published npm version instead of walking siblings)
|
|
434
|
+
is planned.
|
|
435
|
+
|
|
409
436
|
## Common Workflows
|
|
410
437
|
|
|
411
438
|
### Standard Release
|
package/cli.js
CHANGED
|
@@ -37,6 +37,9 @@ Dependency Options:
|
|
|
37
37
|
-no-prescan, -nps Skip upfront dep-graph prescan
|
|
38
38
|
-force-publish Republish dependencies even if version exists
|
|
39
39
|
-fix Run npm audit fix after transformation
|
|
40
|
+
-no-use-paths, -nup Declare this package standalone — file: deps shouldn't
|
|
41
|
+
be resolved from sibling checkouts (persisted as
|
|
42
|
+
usePaths:false in .globalize.json5; FYI for now)
|
|
40
43
|
|
|
41
44
|
Install Options:
|
|
42
45
|
-install, -i Global install after publish (from registry)
|
|
@@ -57,8 +60,12 @@ Git/npm Visibility:
|
|
|
57
60
|
-git private Set GitHub repo to private (default for new repos)
|
|
58
61
|
-git public Set GitHub repo to public (requires confirmation)
|
|
59
62
|
Works on both new and existing repos
|
|
60
|
-
-npm
|
|
61
|
-
|
|
63
|
+
-npm <values> Comma-separated list of npm options:
|
|
64
|
+
private (default) | public — package visibility
|
|
65
|
+
ts — keep .ts source in npm tarball
|
|
66
|
+
nts — exclude .ts source (default for
|
|
67
|
+
non-noEmit projects)
|
|
68
|
+
Example: -npm public,ts
|
|
62
69
|
|
|
63
70
|
Workspace Options:
|
|
64
71
|
-w, -workspace <pkg> Filter to specific package (repeatable)
|
|
@@ -214,12 +221,30 @@ function parseArgs(args) {
|
|
|
214
221
|
break;
|
|
215
222
|
case '-npm':
|
|
216
223
|
i++;
|
|
217
|
-
if (args[i]
|
|
218
|
-
options.
|
|
219
|
-
|
|
224
|
+
if (!args[i]) {
|
|
225
|
+
options.error = `-npm requires a value (private|public, ts, nts — comma-separated)`;
|
|
226
|
+
break;
|
|
220
227
|
}
|
|
221
|
-
|
|
222
|
-
|
|
228
|
+
{
|
|
229
|
+
const tokens = args[i].split(',').map(t => t.trim()).filter(t => t);
|
|
230
|
+
for (const tok of tokens) {
|
|
231
|
+
if (tok === 'private' || tok === 'public') {
|
|
232
|
+
options.npmVisibility = tok;
|
|
233
|
+
options.explicitKeys.add('npmVisibility');
|
|
234
|
+
}
|
|
235
|
+
else if (tok === 'ts') {
|
|
236
|
+
options.allowTs = true;
|
|
237
|
+
options.explicitKeys.add('allowTs');
|
|
238
|
+
}
|
|
239
|
+
else if (tok === 'nts') {
|
|
240
|
+
options.allowTs = false;
|
|
241
|
+
options.explicitKeys.add('allowTs');
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
options.error = `-npm: unknown value '${tok}' (expected private|public|ts|nts)`;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
223
248
|
}
|
|
224
249
|
break;
|
|
225
250
|
case '-message':
|
|
@@ -266,6 +291,11 @@ function parseArgs(args) {
|
|
|
266
291
|
case '-npd':
|
|
267
292
|
options.publishDeps = false; // Disable auto-publishing
|
|
268
293
|
break;
|
|
294
|
+
case '-no-use-paths':
|
|
295
|
+
case '-nup':
|
|
296
|
+
options.usePaths = false; // Skip sibling-path resolution; use latest npm version for file: deps
|
|
297
|
+
options.explicitKeys.add('usePaths');
|
|
298
|
+
break;
|
|
269
299
|
case '-no-prescan':
|
|
270
300
|
case '-nps':
|
|
271
301
|
options.noPrescan = true;
|
package/lib/config.js
CHANGED
|
@@ -58,7 +58,8 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
58
58
|
wsl: false,
|
|
59
59
|
force: false,
|
|
60
60
|
verbose: false,
|
|
61
|
-
freeze: false
|
|
61
|
+
freeze: false,
|
|
62
|
+
usePaths: true
|
|
62
63
|
};
|
|
63
64
|
// Read existing config to preserve values
|
|
64
65
|
const existing = readConfig(dir);
|
|
@@ -119,6 +120,8 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
119
120
|
comment = ' // Transform but don\'t publish';
|
|
120
121
|
else if (key === 'freeze')
|
|
121
122
|
comment = ' // Freeze node_modules (replace symlinks with real copies)';
|
|
123
|
+
else if (key === 'usePaths')
|
|
124
|
+
comment = ' // Resolve file: deps from sibling checkouts (set false for standalone packages)';
|
|
122
125
|
lines.push(` "${key}": ${jsonValue}${comma}${comment}`);
|
|
123
126
|
});
|
|
124
127
|
lines.push('');
|
|
@@ -139,6 +142,7 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
139
142
|
lines.push(' // "local": false // Local install only (skip transform/publish)');
|
|
140
143
|
lines.push(' // "noPublish": false // Transform but don\'t publish');
|
|
141
144
|
lines.push(' // "freeze": false // Freeze node_modules (replace symlinks with real copies)');
|
|
145
|
+
lines.push(' // "usePaths": true // Resolve file: deps from siblings; false = use latest npm version (standalone)');
|
|
142
146
|
lines.push('}');
|
|
143
147
|
fs.writeFileSync(configPath, lines.join('\n') + '\n');
|
|
144
148
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -78,6 +78,11 @@ export interface GlobalizeOptions {
|
|
|
78
78
|
once?: boolean;
|
|
79
79
|
/** Run importgen to update import maps before publishing */
|
|
80
80
|
importgen?: boolean;
|
|
81
|
+
/** Use filesystem paths for `file:` deps (default true). Set false to
|
|
82
|
+
* mark a package as publishable/installable even when sibling checkouts
|
|
83
|
+
* are absent. Currently declarative (recorded in config and displayed);
|
|
84
|
+
* the actual conversion path is TODO. */
|
|
85
|
+
usePaths?: boolean;
|
|
81
86
|
/** Local install only — skip transform/publish, just npm install -g . */
|
|
82
87
|
local?: boolean;
|
|
83
88
|
/** Freeze node_modules: replace symlinks/junctions with real copies for network share use */
|
package/lib.d.ts
CHANGED
|
@@ -55,6 +55,10 @@ export interface GlobalizeOptions {
|
|
|
55
55
|
gitVisibility?: 'private' | 'public';
|
|
56
56
|
/** npm visibility: private (default) or public */
|
|
57
57
|
npmVisibility?: 'private' | 'public';
|
|
58
|
+
/** Allow .ts source files (and *.map, tsconfig.json) in the published npm tarball.
|
|
59
|
+
* undefined: follow noEmit detection (noEmit → allow). true: always allow.
|
|
60
|
+
* false: always exclude via .npmignore. Set via `-npm ts` / `-npm nts`. */
|
|
61
|
+
allowTs?: boolean;
|
|
58
62
|
/** Custom commit message */
|
|
59
63
|
message?: string;
|
|
60
64
|
/** Check and update ignore files to conform to best practices */
|
|
@@ -91,6 +95,11 @@ export interface GlobalizeOptions {
|
|
|
91
95
|
once?: boolean;
|
|
92
96
|
/** Run importgen to update import maps before publishing */
|
|
93
97
|
importgen?: boolean;
|
|
98
|
+
/** Use filesystem paths for `file:` deps (default true). Set false to
|
|
99
|
+
* mark a package as publishable/installable even when sibling checkouts
|
|
100
|
+
* are absent. Currently declarative (recorded in config and displayed);
|
|
101
|
+
* the actual conversion path is TODO. */
|
|
102
|
+
usePaths?: boolean;
|
|
94
103
|
/** Local install only — skip transform/publish, just npm install -g . */
|
|
95
104
|
local?: boolean;
|
|
96
105
|
/** Freeze node_modules: replace symlinks/junctions with real copies for network share use */
|
|
@@ -251,6 +260,15 @@ export declare function runCommand(cmd: string, args: string[], options?: {
|
|
|
251
260
|
output: string;
|
|
252
261
|
stderr: string;
|
|
253
262
|
};
|
|
263
|
+
/** Install a package globally in WSL, auto-fixing the root-owned /usr/local/lib/node_modules
|
|
264
|
+
* EACCES case by switching npm to a user prefix (~/.npm-global) and retrying once.
|
|
265
|
+
* Output is captured (so we can scan for the error) and then mirrored to the terminal. */
|
|
266
|
+
export declare function installInWsl(wslArgs: string[], opts?: {
|
|
267
|
+
cwd?: string;
|
|
268
|
+
}): {
|
|
269
|
+
success: boolean;
|
|
270
|
+
fixed: boolean;
|
|
271
|
+
};
|
|
254
272
|
/** Run a command and throw on failure */
|
|
255
273
|
export declare function runCommandOrThrow(cmd: string, args: string[], options?: {
|
|
256
274
|
silent?: boolean;
|
|
@@ -278,7 +296,7 @@ export declare function promptText(message: string, defaultValue?: string): Prom
|
|
|
278
296
|
/** Prompt user for multiple choice */
|
|
279
297
|
export declare function promptChoice(message: string, choices: string[]): Promise<string | null>;
|
|
280
298
|
/** Initialize git repository */
|
|
281
|
-
export declare function initGit(cwd: string, visibility: 'private' | 'public', dryRun: boolean): Promise<boolean>;
|
|
299
|
+
export declare function initGit(cwd: string, visibility: 'private' | 'public', dryRun: boolean, allowTs?: boolean): Promise<boolean>;
|
|
282
300
|
/** Main globalize function */
|
|
283
301
|
/** Run npm audit and optionally fix vulnerabilities */
|
|
284
302
|
export declare function runNpmAudit(cwd: string, fix?: boolean, verbose?: boolean): {
|
package/lib.js
CHANGED
|
@@ -230,7 +230,8 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
230
230
|
wsl: false,
|
|
231
231
|
force: false,
|
|
232
232
|
verbose: false,
|
|
233
|
-
freeze: false
|
|
233
|
+
freeze: false,
|
|
234
|
+
usePaths: true
|
|
234
235
|
};
|
|
235
236
|
// Read existing config to preserve values
|
|
236
237
|
const existing = readConfig(dir);
|
|
@@ -291,6 +292,10 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
291
292
|
comment = ' // Transform but don\'t publish';
|
|
292
293
|
else if (key === 'freeze')
|
|
293
294
|
comment = ' // Freeze node_modules (replace symlinks with real copies)';
|
|
295
|
+
else if (key === 'usePaths')
|
|
296
|
+
comment = ' // Resolve file: deps from sibling checkouts (set false for standalone packages)';
|
|
297
|
+
else if (key === 'allowTs')
|
|
298
|
+
comment = ' // Keep .ts source (and *.map, tsconfig.json) in the published npm tarball';
|
|
294
299
|
lines.push(` "${key}": ${jsonValue}${comma}${comment}`);
|
|
295
300
|
});
|
|
296
301
|
lines.push('');
|
|
@@ -311,6 +316,8 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
311
316
|
lines.push(' // "local": false // Local install only (skip transform/publish)');
|
|
312
317
|
lines.push(' // "noPublish": false // Transform but don\'t publish');
|
|
313
318
|
lines.push(' // "freeze": false // Freeze node_modules (replace symlinks with real copies)');
|
|
319
|
+
lines.push(' // "usePaths": true // Resolve file: deps from siblings; false = use latest npm version (standalone)');
|
|
320
|
+
lines.push(' // "allowTs": false // Include .ts source in npm tarball (auto-true for noEmit projects)');
|
|
314
321
|
lines.push('}');
|
|
315
322
|
fs.writeFileSync(configPath, lines.join('\n') + '\n');
|
|
316
323
|
}
|
|
@@ -1413,6 +1420,40 @@ export function runCommand(cmd, args, options = {}) {
|
|
|
1413
1420
|
return { success: false, output: '', stderr: error.message };
|
|
1414
1421
|
}
|
|
1415
1422
|
}
|
|
1423
|
+
/** Install a package globally in WSL, auto-fixing the root-owned /usr/local/lib/node_modules
|
|
1424
|
+
* EACCES case by switching npm to a user prefix (~/.npm-global) and retrying once.
|
|
1425
|
+
* Output is captured (so we can scan for the error) and then mirrored to the terminal. */
|
|
1426
|
+
export function installInWsl(wslArgs, opts = {}) {
|
|
1427
|
+
console.log(colors.cyan(`> wsl ${wslArgs.join(' ')}`));
|
|
1428
|
+
let result = runCommand('wsl', wslArgs, { cwd: opts.cwd, silent: true });
|
|
1429
|
+
if (result.output)
|
|
1430
|
+
process.stdout.write(result.output);
|
|
1431
|
+
if (result.stderr)
|
|
1432
|
+
process.stderr.write(result.stderr);
|
|
1433
|
+
if (result.success)
|
|
1434
|
+
return { success: true, fixed: false };
|
|
1435
|
+
const combined = (result.output || '') + '\n' + (result.stderr || '');
|
|
1436
|
+
const permIssue = /EACCES/.test(combined) && /\/usr\/(?:local\/)?lib\/node_modules/.test(combined);
|
|
1437
|
+
if (!permIssue)
|
|
1438
|
+
return { success: false, fixed: false };
|
|
1439
|
+
console.log(colors.yellow('Detected root-owned npm prefix in WSL — switching to ~/.npm-global and retrying...'));
|
|
1440
|
+
const fix = `set -e; npm config set prefix "$HOME/.npm-global"; mkdir -p "$HOME/.npm-global/bin"; if ! grep -q '\\.npm-global/bin' "$HOME/.bashrc" 2>/dev/null; then printf '\\n# npm user-prefix bin (added by npmglobalize)\\nexport PATH="$HOME/.npm-global/bin:$PATH"\\n' >> "$HOME/.bashrc"; fi`;
|
|
1441
|
+
const fixResult = runCommand('wsl', ['bash', '-lc', fix], { silent: true });
|
|
1442
|
+
if (!fixResult.success) {
|
|
1443
|
+
console.error(colors.red('Failed to apply WSL npm prefix fix:'));
|
|
1444
|
+
if (fixResult.stderr)
|
|
1445
|
+
process.stderr.write(fixResult.stderr);
|
|
1446
|
+
return { success: false, fixed: false };
|
|
1447
|
+
}
|
|
1448
|
+
console.log(colors.green('✓ WSL npm prefix set to ~/.npm-global; PATH appended to ~/.bashrc'));
|
|
1449
|
+
console.log(colors.cyan(`> wsl ${wslArgs.join(' ')}`));
|
|
1450
|
+
result = runCommand('wsl', wslArgs, { cwd: opts.cwd, silent: true });
|
|
1451
|
+
if (result.output)
|
|
1452
|
+
process.stdout.write(result.output);
|
|
1453
|
+
if (result.stderr)
|
|
1454
|
+
process.stderr.write(result.stderr);
|
|
1455
|
+
return { success: result.success, fixed: result.success };
|
|
1456
|
+
}
|
|
1416
1457
|
/** Diagnose common build/version failure patterns and print actionable hints.
|
|
1417
1458
|
* Returns true if a diagnosis was printed. */
|
|
1418
1459
|
function diagnoseBuildFailure(errorText, cwd) {
|
|
@@ -1858,9 +1899,16 @@ function isNoEmitProject(cwd) {
|
|
|
1858
1899
|
return false;
|
|
1859
1900
|
}
|
|
1860
1901
|
}
|
|
1861
|
-
/**
|
|
1862
|
-
|
|
1863
|
-
|
|
1902
|
+
/** Resolve whether .ts source files should be kept in the published tarball.
|
|
1903
|
+
* Explicit allowTs wins; otherwise noEmit projects default to including .ts. */
|
|
1904
|
+
function resolveAllowTs(cwd, allowTs) {
|
|
1905
|
+
if (allowTs !== undefined)
|
|
1906
|
+
return allowTs;
|
|
1907
|
+
return isNoEmitProject(cwd);
|
|
1908
|
+
}
|
|
1909
|
+
/** Get applicable npmignore patterns, excluding TS patterns when .ts files should ship */
|
|
1910
|
+
function getApplicableNpmignorePatterns(cwd, allowTs) {
|
|
1911
|
+
if (resolveAllowTs(cwd, allowTs)) {
|
|
1864
1912
|
return ALL_NPMIGNORE.filter(p => !TS_NPMIGNORE_PATTERNS.has(p));
|
|
1865
1913
|
}
|
|
1866
1914
|
return ALL_NPMIGNORE;
|
|
@@ -2223,7 +2271,7 @@ function checkIgnoreFiles(cwd, options) {
|
|
|
2223
2271
|
if (fs.existsSync(npmignorePath)) {
|
|
2224
2272
|
const content = fs.readFileSync(npmignorePath, 'utf-8');
|
|
2225
2273
|
const lines = content.split('\n').map(l => l.trim());
|
|
2226
|
-
const applicableNpm = getApplicableNpmignorePatterns(cwd);
|
|
2274
|
+
const applicableNpm = getApplicableNpmignorePatterns(cwd, options.allowTs);
|
|
2227
2275
|
for (const pattern of applicableNpm) {
|
|
2228
2276
|
if (!lineHasPattern(lines, pattern)) {
|
|
2229
2277
|
if (securityNpm.has(pattern)) {
|
|
@@ -2234,13 +2282,21 @@ function checkIgnoreFiles(cwd, options) {
|
|
|
2234
2282
|
}
|
|
2235
2283
|
}
|
|
2236
2284
|
}
|
|
2285
|
+
// If .ts should ship, flag TS patterns already in .npmignore for removal
|
|
2286
|
+
if (resolveAllowTs(cwd, options.allowTs)) {
|
|
2287
|
+
for (const ts of TS_NPMIGNORE_PATTERNS) {
|
|
2288
|
+
if (lineHasPattern(lines, ts)) {
|
|
2289
|
+
changes.push(` .npmignore has (should remove): ${ts}`);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2237
2293
|
}
|
|
2238
2294
|
const needsUpdate = changes.length > 0 || securityChanges.length > 0;
|
|
2239
2295
|
return { needsUpdate, changes, securityChanges };
|
|
2240
2296
|
}
|
|
2241
2297
|
/** Update ignore files to conform to best practices.
|
|
2242
2298
|
* securityOnly: if true, only add security patterns (auto-fix without prompting). */
|
|
2243
|
-
function conformIgnoreFiles(cwd, securityOnly = false) {
|
|
2299
|
+
function conformIgnoreFiles(cwd, securityOnly = false, allowTs) {
|
|
2244
2300
|
if (!securityOnly) {
|
|
2245
2301
|
// Ensure .gitattributes for LF line endings (use proper helper)
|
|
2246
2302
|
ensureGitattributes(cwd);
|
|
@@ -2259,8 +2315,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
|
|
|
2259
2315
|
}
|
|
2260
2316
|
}
|
|
2261
2317
|
const patternsGit = securityOnly ? getSecurityGitignorePatterns() : getApplicableGitignorePatterns(cwd);
|
|
2262
|
-
const patternsNpm = securityOnly ? getSecurityNpmignorePatterns() : getApplicableNpmignorePatterns(cwd);
|
|
2263
|
-
const
|
|
2318
|
+
const patternsNpm = securityOnly ? getSecurityNpmignorePatterns() : getApplicableNpmignorePatterns(cwd, allowTs);
|
|
2319
|
+
const shipTs = resolveAllowTs(cwd, allowTs);
|
|
2264
2320
|
// Update .gitignore
|
|
2265
2321
|
const gitignorePath = path.join(cwd, '.gitignore');
|
|
2266
2322
|
if (fs.existsSync(gitignorePath)) {
|
|
@@ -2287,8 +2343,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
|
|
|
2287
2343
|
const lines = content.split('\n').map(l => l.trim());
|
|
2288
2344
|
const newLines = new Set(lines.filter(l => l));
|
|
2289
2345
|
let updated = false;
|
|
2290
|
-
if (!securityOnly && !
|
|
2291
|
-
// Add TypeScript exclusions (only in full conform, skip
|
|
2346
|
+
if (!securityOnly && !shipTs) {
|
|
2347
|
+
// Add TypeScript exclusions (only in full conform, skip when .ts should ship)
|
|
2292
2348
|
for (const ts of ['*.ts', '!*.d.ts', '*.map']) {
|
|
2293
2349
|
if (!newLines.has(ts)) {
|
|
2294
2350
|
newLines.add(ts);
|
|
@@ -2296,8 +2352,8 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
|
|
|
2296
2352
|
}
|
|
2297
2353
|
}
|
|
2298
2354
|
}
|
|
2299
|
-
//
|
|
2300
|
-
if (
|
|
2355
|
+
// When .ts should ship (noEmit or allowTs=true), remove TS patterns
|
|
2356
|
+
if (shipTs) {
|
|
2301
2357
|
for (const ts of TS_NPMIGNORE_PATTERNS) {
|
|
2302
2358
|
if (newLines.has(ts)) {
|
|
2303
2359
|
newLines.delete(ts);
|
|
@@ -2314,8 +2370,9 @@ function conformIgnoreFiles(cwd, securityOnly = false) {
|
|
|
2314
2370
|
if (updated) {
|
|
2315
2371
|
const newContent = Array.from(newLines).join('\n') + '\n';
|
|
2316
2372
|
fs.writeFileSync(npmignorePath, newContent);
|
|
2317
|
-
if (
|
|
2318
|
-
|
|
2373
|
+
if (shipTs) {
|
|
2374
|
+
const reason = allowTs === true ? 'allowTs' : 'noEmit';
|
|
2375
|
+
console.log(colors.cyan(` ✓ .npmignore updated (${reason}: kept *.ts files)`));
|
|
2319
2376
|
}
|
|
2320
2377
|
else {
|
|
2321
2378
|
console.log(colors.cyan(' ✓ Auto-added security patterns to .npmignore'));
|
|
@@ -2374,11 +2431,11 @@ function ensureGitignore(cwd) {
|
|
|
2374
2431
|
}
|
|
2375
2432
|
}
|
|
2376
2433
|
/** Ensure .npmignore exists with recommended patterns */
|
|
2377
|
-
function ensureNpmignore(cwd) {
|
|
2434
|
+
function ensureNpmignore(cwd, allowTs) {
|
|
2378
2435
|
const npmignorePath = path.join(cwd, '.npmignore');
|
|
2379
2436
|
if (!fs.existsSync(npmignorePath)) {
|
|
2380
2437
|
console.log(' Creating .npmignore...');
|
|
2381
|
-
const patterns = getApplicableNpmignorePatterns(cwd);
|
|
2438
|
+
const patterns = getApplicableNpmignorePatterns(cwd, allowTs);
|
|
2382
2439
|
const content = patterns.join('\n') + '\n';
|
|
2383
2440
|
fs.writeFileSync(npmignorePath, content);
|
|
2384
2441
|
console.log(colors.green(' ✓ .npmignore created'));
|
|
@@ -2405,7 +2462,7 @@ function ensureGitattributes(cwd) {
|
|
|
2405
2462
|
}
|
|
2406
2463
|
}
|
|
2407
2464
|
/** Initialize git repository */
|
|
2408
|
-
export async function initGit(cwd, visibility, dryRun) {
|
|
2465
|
+
export async function initGit(cwd, visibility, dryRun, allowTs) {
|
|
2409
2466
|
const pkg = readPackageJson(cwd);
|
|
2410
2467
|
const repoName = pkg.name.replace(/^@[^/]+\//, ''); // Remove scope
|
|
2411
2468
|
console.log('Initializing git repository...');
|
|
@@ -2428,7 +2485,7 @@ export async function initGit(cwd, visibility, dryRun) {
|
|
|
2428
2485
|
// Ensure .gitignore exists and includes node_modules
|
|
2429
2486
|
ensureGitignore(cwd);
|
|
2430
2487
|
// Ensure .npmignore exists with recommended patterns
|
|
2431
|
-
ensureNpmignore(cwd);
|
|
2488
|
+
ensureNpmignore(cwd, allowTs);
|
|
2432
2489
|
// Ensure .gitattributes exists for LF line endings
|
|
2433
2490
|
ensureGitattributes(cwd);
|
|
2434
2491
|
// git init
|
|
@@ -2693,7 +2750,7 @@ async function doLocalInstall(cwd, options) {
|
|
|
2693
2750
|
export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
2694
2751
|
const { bump = 'patch', noPublish = false, cleanup = false, install = false, link = false, wsl = false, force = false, files = true, dryRun = false, quiet = true, verbose = false, init = false, gitVisibility = 'private', npmVisibility = 'private', message, conform = false, asis = false, updateDeps = false, updateMajor = false, publishDeps = true, // Default to publishing deps for safety
|
|
2695
2752
|
publishDepsYes = false, // -pd: auto-yes to dep-cascade prompts (private only)
|
|
2696
|
-
noPrescan = false, forcePublish = false, fix = true, fixTags = false, rebase = false, show = false, local = false, freeze = false } = options;
|
|
2753
|
+
noPrescan = false, forcePublish = false, fix = true, fixTags = false, rebase = false, show = false, local = false, freeze = false, usePaths = true, allowTs } = options;
|
|
2697
2754
|
// Show tool version only for recursive dep calls (CLI already prints it at startup)
|
|
2698
2755
|
const toolVersion = getToolVersion();
|
|
2699
2756
|
if (!options._fromWorkspace && !options._fromCli) {
|
|
@@ -2752,6 +2809,12 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2752
2809
|
settings.push('-local');
|
|
2753
2810
|
if (configOptions.freeze)
|
|
2754
2811
|
settings.push('-freeze');
|
|
2812
|
+
if (configOptions.usePaths === false)
|
|
2813
|
+
settings.push('--no-use-paths');
|
|
2814
|
+
if (configOptions.allowTs === true)
|
|
2815
|
+
settings.push('-npm ts');
|
|
2816
|
+
if (configOptions.allowTs === false)
|
|
2817
|
+
settings.push('-npm nts');
|
|
2755
2818
|
if (settings.length > 0) {
|
|
2756
2819
|
console.log(colors.dim(`Settings from .globalize.json5: ${settings.join(', ')}`));
|
|
2757
2820
|
}
|
|
@@ -2832,7 +2895,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2832
2895
|
}
|
|
2833
2896
|
// Check ignore files first (unless cleanup mode)
|
|
2834
2897
|
if (!cleanup && !asis) {
|
|
2835
|
-
const checkResult = checkIgnoreFiles(cwd, { conform, asis, verbose });
|
|
2898
|
+
const checkResult = checkIgnoreFiles(cwd, { conform, asis, verbose, allowTs });
|
|
2836
2899
|
// Auto-add security patterns without prompting
|
|
2837
2900
|
if (checkResult.securityChanges.length > 0) {
|
|
2838
2901
|
const secGit = [];
|
|
@@ -2845,7 +2908,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2845
2908
|
secNpm.push(change.replace(' .npmignore missing: ', '').trim());
|
|
2846
2909
|
}
|
|
2847
2910
|
}
|
|
2848
|
-
conformIgnoreFiles(cwd, true);
|
|
2911
|
+
conformIgnoreFiles(cwd, true, allowTs);
|
|
2849
2912
|
if (secGit.length > 0) {
|
|
2850
2913
|
console.log(colors.cyan(' .gitignore: auto-added ') + secGit.join(', '));
|
|
2851
2914
|
}
|
|
@@ -2876,7 +2939,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2876
2939
|
console.log('');
|
|
2877
2940
|
if (conform) {
|
|
2878
2941
|
console.log('Applying changes (--conform)...');
|
|
2879
|
-
conformIgnoreFiles(cwd);
|
|
2942
|
+
conformIgnoreFiles(cwd, false, allowTs);
|
|
2880
2943
|
console.log('');
|
|
2881
2944
|
}
|
|
2882
2945
|
else {
|
|
@@ -2888,7 +2951,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2888
2951
|
const choice = await promptChoice('Your choice [ok/asis/abort]:', ['ok', 'asis', 'abort']);
|
|
2889
2952
|
if (choice === 'ok') {
|
|
2890
2953
|
console.log('Applying changes...');
|
|
2891
|
-
conformIgnoreFiles(cwd);
|
|
2954
|
+
conformIgnoreFiles(cwd, false, allowTs);
|
|
2892
2955
|
console.log(colors.green('✓ Ignore files updated'));
|
|
2893
2956
|
console.log('');
|
|
2894
2957
|
}
|
|
@@ -2946,13 +3009,13 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2946
3009
|
options.autoInit = true;
|
|
2947
3010
|
}
|
|
2948
3011
|
// choice is '1', 'a', or '' (default)
|
|
2949
|
-
const success = await initGit(cwd, gitVisibility, dryRun);
|
|
3012
|
+
const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
|
|
2950
3013
|
if (!success)
|
|
2951
3014
|
return false;
|
|
2952
3015
|
justInitialized = true;
|
|
2953
3016
|
}
|
|
2954
3017
|
else {
|
|
2955
|
-
const success = await initGit(cwd, gitVisibility, dryRun);
|
|
3018
|
+
const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
|
|
2956
3019
|
if (!success)
|
|
2957
3020
|
return false;
|
|
2958
3021
|
justInitialized = true;
|
|
@@ -2975,7 +3038,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2975
3038
|
options.autoInit = true;
|
|
2976
3039
|
}
|
|
2977
3040
|
}
|
|
2978
|
-
const success = await initGit(cwd, gitVisibility, dryRun);
|
|
3041
|
+
const success = await initGit(cwd, gitVisibility, dryRun, allowTs);
|
|
2979
3042
|
if (!success)
|
|
2980
3043
|
return false;
|
|
2981
3044
|
justInitialized = true;
|
|
@@ -4643,10 +4706,10 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
4643
4706
|
waitForNpmVersion(pkgName, pkgVersion);
|
|
4644
4707
|
console.log(`Installing in WSL${useLocalWsl ? ' (local)' : ' from registry'}: ${pkgName}@${pkgVersion}...`);
|
|
4645
4708
|
if (!dryRun) {
|
|
4646
|
-
const wslResult =
|
|
4709
|
+
const wslResult = installInWsl(wslArgs, { cwd });
|
|
4647
4710
|
if (wslResult.success) {
|
|
4648
4711
|
wslInstallOk = true;
|
|
4649
|
-
console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}`));
|
|
4712
|
+
console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}${wslResult.fixed ? ' (after prefix fix)' : ''}`));
|
|
4650
4713
|
}
|
|
4651
4714
|
else {
|
|
4652
4715
|
console.error(colors.yellow('✗ WSL install failed (is npm installed in WSL?)'));
|
|
@@ -5047,9 +5110,9 @@ export async function globalizeWorkspace(rootDir, options = {}, configOptions =
|
|
|
5047
5110
|
if (wsl) {
|
|
5048
5111
|
console.log(`Installing ${pkgName} in WSL (local)...`);
|
|
5049
5112
|
if (!dryRun) {
|
|
5050
|
-
const wslResult =
|
|
5113
|
+
const wslResult = installInWsl(['npm', 'install', '-g', '.'], { cwd: rootDir });
|
|
5051
5114
|
if (wslResult.success) {
|
|
5052
|
-
console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}`));
|
|
5115
|
+
console.log(colors.green(`✓ Installed in WSL: ${pkgName}@${pkgVersion}${wslResult.fixed ? ' (after prefix fix)' : ''}`));
|
|
5053
5116
|
}
|
|
5054
5117
|
else {
|
|
5055
5118
|
console.error(colors.yellow('✗ WSL install failed (is npm installed in WSL?)'));
|