package webbundler import ( "fmt" "os" "path/filepath" "strings" esbuild "github.com/evanw/esbuild/pkg/api" ) // aliasRoots maps the framework import prefixes to absolute filesystem roots: // // @ui/* -> kjol web kit (shared Solid components) // @kjol/* -> kjol web root (auth, utils, hooks, ssr, env.ts, ...) // @appgen/* -> the app's generated dir (faIcons registry etc. — app-owned) // // In single-tree mode @ui/@kjol resolve back under the app frontend. func aliasRoots() map[string]string { abs := func(p string) string { a, _ := filepath.Abs(p); return a } return map[string]string{ "@ui": abs(uikitDir()), "@kjol": abs(webRoot()), "@appgen": abs(genTSDir), } } // resolveAlias turns "/" into a concrete file, probing the usual // TS/JS extensions and index files when the specifier is extensionless. func resolveAlias(root, rest string) (string, bool) { base := filepath.Join(root, filepath.FromSlash(rest)) var cands []string if filepath.Ext(base) != "" { cands = append(cands, base) } else { for _, e := range []string{".tsx", ".ts", ".jsx", ".js"} { cands = append(cands, base+e) } for _, e := range []string{".tsx", ".ts", ".jsx", ".js"} { cands = append(cands, filepath.Join(base, "index"+e)) } } for _, c := range cands { if fi, err := os.Stat(c); err == nil && !fi.IsDir() { return c, true } } return "", false } // aliasPlugin resolves @ui / @kjol / @appgen imports to absolute paths across the // app and kjol web trees. It sits before the vendor resolvers; the Solid // compiler's OnLoad then compiles any .tsx/.jsx it points at. func aliasPlugin() esbuild.Plugin { roots := aliasRoots() return esbuild.Plugin{ Name: "kjol-alias", Setup: func(b esbuild.PluginBuild) { b.OnResolve(esbuild.OnResolveOptions{Filter: `^@(ui|kjol|appgen)/`}, func(a esbuild.OnResolveArgs) (esbuild.OnResolveResult, error) { slash := strings.IndexByte(a.Path, '/') if slash < 0 { return esbuild.OnResolveResult{}, nil } prefix, rest := a.Path[:slash], a.Path[slash+1:] root, ok := roots[prefix] if !ok { return esbuild.OnResolveResult{}, nil } if p, ok := resolveAlias(root, rest); ok { return esbuild.OnResolveResult{Path: p}, nil } return esbuild.OnResolveResult{}, fmt.Errorf("kjol-alias: cannot resolve %q under %s", a.Path, root) }) }, } }