@ttsc/strip 0.16.7 → 0.16.9
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/driver/config.go +74 -2
- package/package.json +1 -1
package/driver/config.go
CHANGED
|
@@ -290,7 +290,7 @@ try {
|
|
|
290
290
|
// project's transform/check plugins would be wasteful and could fail the
|
|
291
291
|
// build against this deliberately lenient loader tsconfig.
|
|
292
292
|
func loadStripTypeScriptConfigFile(location string) (any, error) {
|
|
293
|
-
tempDir, err := os.MkdirTemp(
|
|
293
|
+
tempDir, err := os.MkdirTemp(stripLoaderTempBase(location, os.TempDir()), "ttsc-strip-config-")
|
|
294
294
|
if err != nil {
|
|
295
295
|
return nil, fmt.Errorf("@ttsc/strip: create config loader tempdir: %w", err)
|
|
296
296
|
}
|
|
@@ -366,7 +366,7 @@ func stripTypeScriptLoaderTsconfig(loader, location, outDir string) string {
|
|
|
366
366
|
"noImplicitAny": false,
|
|
367
367
|
"outDir": filepath.ToSlash(filepath.Join(outDir, "out")),
|
|
368
368
|
"rewriteRelativeImportExtensions": true,
|
|
369
|
-
"rootDir":
|
|
369
|
+
"rootDir": stripLoaderRootDir(outDir),
|
|
370
370
|
"skipLibCheck": true,
|
|
371
371
|
"strict": false,
|
|
372
372
|
"target": "ES2022",
|
|
@@ -383,6 +383,78 @@ func stripTypeScriptLoaderTsconfig(loader, location, outDir string) string {
|
|
|
383
383
|
return string(body)
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
// stripLoaderRootDir returns the widest rootDir that still contains the
|
|
387
|
+
// loader tsconfig's inputs: the volume root of the loader temp dir (`C:/` on
|
|
388
|
+
// Windows, `/` elsewhere). A literal "/" is not an ancestor of drive-letter
|
|
389
|
+
// paths, so tsgo rejects every input with TS6059 (#299, #304). The temp dir
|
|
390
|
+
// is created on the same volume as the config file (see stripLoaderTempBase),
|
|
391
|
+
// so its volume root spans both `files` entries.
|
|
392
|
+
func stripLoaderRootDir(outDir string) string {
|
|
393
|
+
vol := filepath.VolumeName(outDir)
|
|
394
|
+
if vol == "" {
|
|
395
|
+
return "/"
|
|
396
|
+
}
|
|
397
|
+
return filepath.ToSlash(vol + `\`)
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// stripLoaderTempBase picks the parent directory for the ephemeral
|
|
401
|
+
// config-loader tree. The system temp dir is the default, but when it sits on
|
|
402
|
+
// a different volume than the config file (Windows: TEMP on `C:`, project on
|
|
403
|
+
// `D:`) the loader cannot work from there — no single tsconfig rootDir spans
|
|
404
|
+
// two volumes and filepath.Rel cannot produce a relative import across drives
|
|
405
|
+
// (#305) — so the tree is created under the config's nearest
|
|
406
|
+
// node_modules/.cache instead, falling back to the config's own directory
|
|
407
|
+
// when no node_modules exists (or its .cache cannot be created): any location
|
|
408
|
+
// on the config's volume beats the system temp dir, which is guaranteed to
|
|
409
|
+
// fail. Returns "" (the os.MkdirTemp default) when the volumes already match.
|
|
410
|
+
func stripLoaderTempBase(location, systemTemp string) string {
|
|
411
|
+
// A relative location has no volume; "" must not be read as "a volume
|
|
412
|
+
// other than the system temp's" — it keeps the historical default (and
|
|
413
|
+
// the Rel-failure contract for relative config paths).
|
|
414
|
+
vol := filepath.VolumeName(location)
|
|
415
|
+
if vol == "" || strings.EqualFold(filepath.VolumeName(systemTemp), vol) {
|
|
416
|
+
return ""
|
|
417
|
+
}
|
|
418
|
+
nodeModules := stripFindNearestNodeModules(filepath.Dir(location))
|
|
419
|
+
if nodeModules == "" {
|
|
420
|
+
return filepath.Dir(location)
|
|
421
|
+
}
|
|
422
|
+
// Resolve a linked node_modules (junction/symlink — common in managed
|
|
423
|
+
// setups) before descending into it: the ESM runtime realpaths the loader
|
|
424
|
+
// module at import time, and a relative config specifier computed from the
|
|
425
|
+
// link-form path would resolve against the wrong directory. NTFS junctions
|
|
426
|
+
// defeat filepath.EvalSymlinks, so the link component is chased by hand
|
|
427
|
+
// first. Realpathing may also land on another volume, which defeats the
|
|
428
|
+
// whole point — fall back to the config's directory then.
|
|
429
|
+
base := filepath.Join(stripResolveDirLink(nodeModules), ".cache")
|
|
430
|
+
if err := os.MkdirAll(base, 0o755); err != nil {
|
|
431
|
+
return filepath.Dir(location)
|
|
432
|
+
}
|
|
433
|
+
real, err := filepath.EvalSymlinks(base)
|
|
434
|
+
if err != nil || !strings.EqualFold(filepath.VolumeName(real), filepath.VolumeName(location)) {
|
|
435
|
+
return filepath.Dir(location)
|
|
436
|
+
}
|
|
437
|
+
return real
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// stripResolveDirLink chases a directory that is itself a symlink or NTFS junction
|
|
441
|
+
// to its target (bounded against link cycles). os.Readlink is the probe:
|
|
442
|
+
// it resolves junctions, which report neither ModeSymlink nor an
|
|
443
|
+
// EvalSymlinks-traversable path.
|
|
444
|
+
func stripResolveDirLink(dir string) string {
|
|
445
|
+
for i := 0; i < 8; i++ {
|
|
446
|
+
target, err := os.Readlink(dir)
|
|
447
|
+
if err != nil {
|
|
448
|
+
return dir
|
|
449
|
+
}
|
|
450
|
+
if !filepath.IsAbs(target) {
|
|
451
|
+
target = filepath.Join(filepath.Dir(dir), target)
|
|
452
|
+
}
|
|
453
|
+
dir = target
|
|
454
|
+
}
|
|
455
|
+
return dir
|
|
456
|
+
}
|
|
457
|
+
|
|
386
458
|
// stripTtsxCommandContext returns an exec.Cmd that runs ttsx with the given
|
|
387
459
|
// arguments, routing through node when the resolved binary is a script file.
|
|
388
460
|
func stripTtsxCommandContext(ctx context.Context, args ...string) *exec.Cmd {
|
package/package.json
CHANGED