Publish go-nc-files v1 with local/WebDAV Root, DefaultPathStore, and neutral Working Folder language; depends on go-nc-exapp v0.1.0. Co-authored-by: Cursor <cursoragent@cursor.com>
94 lines
2.5 KiB
Go
94 lines
2.5 KiB
Go
package goncfiles
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// Visit is one ExApp opening: Working Folder for this request plus the Saved Default.
|
|
type Visit struct {
|
|
SavedDefault string
|
|
WorkingRel string
|
|
VisitRelative string
|
|
FS Folder
|
|
defaults DefaultPathStore
|
|
root Root
|
|
}
|
|
|
|
// Open resolves the Working Folder for this visit.
|
|
// initialFolderName is used when no Saved Default is stored yet (app-icon first launch).
|
|
// visitRelative empty means app-icon launch (Saved Default, creating the initial folder empty if missing).
|
|
// A Files-view folder is used only for this visit and does not change the Saved Default.
|
|
// Missing or forbidden visit paths fail closed (no create, no fallback).
|
|
func Open(root Root, defaults DefaultPathStore, initialFolderName, visitRelative string) (*Visit, error) {
|
|
saved, err := defaults.GetDefault()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if saved == "" {
|
|
saved = initialFolderName
|
|
}
|
|
if CleanRel(saved) == "" {
|
|
return nil, fmt.Errorf("invalid saved Working Folder path")
|
|
}
|
|
|
|
raw := strings.Trim(strings.ReplaceAll(visitRelative, "\\", "/"), "/")
|
|
v := &Visit{
|
|
SavedDefault: saved,
|
|
defaults: defaults,
|
|
root: root,
|
|
}
|
|
|
|
if raw == "" {
|
|
fs, err := root.EnsureFolder(saved)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
v.WorkingRel = saved
|
|
v.FS = fs
|
|
return v, nil
|
|
}
|
|
|
|
rel := CleanRel(raw)
|
|
if rel == "" {
|
|
return nil, fmt.Errorf("invalid Working Folder path")
|
|
}
|
|
v.VisitRelative = rel
|
|
fs, err := root.OpenFolder(rel)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Working Folder %q: %w", rel, err)
|
|
}
|
|
v.WorkingRel = rel
|
|
v.FS = fs
|
|
return v, nil
|
|
}
|
|
|
|
// OpenLocal is the local-adapter convenience: files root + settings JSON.
|
|
func OpenLocal(filesRoot, settingsPath, initialFolderName, visitRelative string) (*Visit, error) {
|
|
return Open(Local{RootDir: filesRoot}, FileStore{Path: settingsPath}, initialFolderName, visitRelative)
|
|
}
|
|
|
|
// SetDefault persists a new Saved Default and ensures the folder exists.
|
|
func (v *Visit) SetDefault(relative string) error {
|
|
rel := CleanRel(relative)
|
|
if rel == "" {
|
|
return fmt.Errorf("invalid Saved Default path")
|
|
}
|
|
if _, err := v.root.EnsureFolder(rel); err != nil {
|
|
return err
|
|
}
|
|
if err := v.defaults.SetDefault(rel); err != nil {
|
|
return err
|
|
}
|
|
v.SavedDefault = rel
|
|
return nil
|
|
}
|
|
|
|
// WorkingDir returns a local absolute path when using the local adapter; otherwise WorkingRel.
|
|
func (v *Visit) WorkingDir() string {
|
|
if p, ok := LocalPath(v.FS); ok {
|
|
return p
|
|
}
|
|
return v.WorkingRel
|
|
}
|