tractor.dev/toolkit-go@v0.0.0-20241010005851-214d91207d07/engine/fs/xformfs/fs.go (about)

     1  package xformfs
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/fs"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"tractor.dev/toolkit-go/engine/fs/memfs"
    12  	"tractor.dev/toolkit-go/engine/fs/watchfs"
    13  )
    14  
    15  // This package is still experimental and was recently pulled from ui/webiew.go
    16  // so it has some hardcoded bits, but still not 100% on this idea in general
    17  
    18  func New(fsys fs.FS) *FS {
    19  	return &FS{FS: fsys}
    20  }
    21  
    22  type FS struct {
    23  	fs.FS
    24  	xforms []transform
    25  }
    26  
    27  type transform struct {
    28  	suffix string
    29  	fn     func(dst io.Writer, src io.Reader) error
    30  }
    31  
    32  func (xfs *FS) Transform(suffix string, fn func(dst io.Writer, src io.Reader) error) {
    33  	xfs.xforms = append(xfs.xforms, transform{
    34  		suffix: suffix,
    35  		fn:     fn,
    36  	})
    37  }
    38  
    39  func (xfs *FS) Stat(name string) (fs.FileInfo, error) {
    40  	return fs.Stat(xfs.FS, name)
    41  }
    42  
    43  func (xfs *FS) Watch(name string, cfg *watchfs.Config) (*watchfs.Watch, error) {
    44  	wfs, ok := xfs.FS.(watchfs.WatchFS)
    45  	if !ok {
    46  		return nil, fmt.Errorf("not supported")
    47  	}
    48  	w, err := wfs.Watch(name, cfg)
    49  	if filepath.Ext(name) == "" && os.IsNotExist(err) {
    50  		exts := []string{".js", ".ts", ".tsx", ".jsx"}
    51  		for _, ext := range exts {
    52  			w, err = xfs.Watch(name+ext, cfg)
    53  			if err == nil {
    54  				break
    55  			}
    56  		}
    57  	}
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	return w, err
    62  }
    63  
    64  func (xfs *FS) Open(name string) (fs.File, error) {
    65  	f, err := xfs.FS.Open(name)
    66  	if filepath.Ext(name) == "" && os.IsNotExist(err) {
    67  		exts := []string{".js", ".ts", ".tsx", ".jsx"}
    68  		for _, ext := range exts {
    69  			f, err = xfs.Open(name + ext)
    70  			if err == nil {
    71  				break
    72  			}
    73  		}
    74  	}
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  
    79  	for _, xform := range xfs.xforms {
    80  		if strings.HasSuffix(name, xform.suffix) {
    81  			ff := memfs.NewFileHandle(memfs.CreateFile(name))
    82  			if err := xform.fn(ff, f); err != nil {
    83  				return nil, err
    84  			}
    85  			ff.Seek(0, 0)
    86  			return ff, nil
    87  		}
    88  	}
    89  	return f, nil
    90  }