WIP: stuff
This commit is contained in:
parent
93bc18022a
commit
dd0995b241
@ -1,13 +1,16 @@
|
||||
.direnv
|
||||
.env
|
||||
build
|
||||
result
|
||||
|
||||
/docker-compose.*
|
||||
|
||||
/.direnv/
|
||||
/build/
|
||||
/result/
|
||||
|
||||
# Client
|
||||
/client/node_modules
|
||||
/client/.svelte-kit
|
||||
/client/node_modules/
|
||||
/client/.svelte-kit/
|
||||
|
||||
# Server
|
||||
/server/client
|
||||
/server/tmp
|
||||
/server/internal/handlers/client/client
|
||||
/server/client/
|
||||
/server/tmp/
|
||||
/server/internal/handlers/client/client/
|
14
.gitignore
vendored
14
.gitignore
vendored
@ -1,13 +1,7 @@
|
||||
.direnv
|
||||
.env
|
||||
build
|
||||
result
|
||||
|
||||
# Client
|
||||
/client/node_modules
|
||||
/client/.svelte-kit
|
||||
/docker-compose.*
|
||||
|
||||
# Server
|
||||
/server/client
|
||||
/server/tmp
|
||||
/server/internal/handlers/client/client
|
||||
/.direnv/
|
||||
/build/
|
||||
/result/
|
89
cli/cmd/ts-run/ts-run.go
Normal file
89
cli/cmd/ts-run/ts-run.go
Normal file
@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/boyter/gocodewalker"
|
||||
)
|
||||
|
||||
type env struct {
|
||||
DBType string
|
||||
DBUser string
|
||||
DBPass string
|
||||
DBHost string
|
||||
DBPort string
|
||||
DBName string
|
||||
|
||||
RootDir string
|
||||
NodeDir string
|
||||
ProtoDir string
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Get pwd
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Current path: %s\n", path)
|
||||
|
||||
findApps(path)
|
||||
return
|
||||
|
||||
// c := make(chan apps.Msg, 10)
|
||||
|
||||
// // Create protobuf watcher
|
||||
// proto, err := apps.NewProto(env.ProtoDir, env.RootDir, c)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
// // Create node watcher
|
||||
// node := apps.NewNode(env.NodeDir, c)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
// apps := []*apps.App{
|
||||
// &proto.App,
|
||||
// &node.App,
|
||||
// }
|
||||
|
||||
// // Start tea
|
||||
// p := tea.NewProgram(
|
||||
// models.NewRunner(c, apps),
|
||||
// tea.WithAltScreen(),
|
||||
// tea.WithMouseCellMotion(),
|
||||
// )
|
||||
// if _, err := p.Run(); err != nil {
|
||||
// fmt.Printf("Alas, there's been an error: %v", err)
|
||||
// }
|
||||
|
||||
// // Cancel watchers
|
||||
// proto.Cancel()
|
||||
// proto.Wait()
|
||||
|
||||
// node.Cancel()
|
||||
// node.Wait()
|
||||
|
||||
// close(c)
|
||||
}
|
||||
|
||||
func findApps(path string) {
|
||||
fileListQueue := make(chan *gocodewalker.File, 100)
|
||||
fileWalker := gocodewalker.NewFileWalker(path, fileListQueue)
|
||||
|
||||
errorHandler := func(e error) bool {
|
||||
fmt.Println("ERR", e.Error())
|
||||
return true
|
||||
}
|
||||
fileWalker.SetErrorHandler(errorHandler)
|
||||
|
||||
go fileWalker.Start()
|
||||
|
||||
for f := range fileListQueue {
|
||||
fmt.Printf("%s, %s\n", f.Filename, f.Location)
|
||||
}
|
||||
}
|
31
cli/go.mod
Normal file
31
cli/go.mod
Normal file
@ -0,0 +1,31 @@
|
||||
module github.com/spotdemo4/trevstack/cli
|
||||
|
||||
go 1.23.6
|
||||
|
||||
require (
|
||||
github.com/charmbracelet/bubbles v0.20.0
|
||||
github.com/charmbracelet/bubbletea v1.3.4
|
||||
github.com/charmbracelet/lipgloss v1.0.0
|
||||
github.com/fsnotify/fsnotify v1.8.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/boyter/gocodewalker v1.4.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.8.0 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/termenv v0.16.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.3.8 // indirect
|
||||
)
|
47
cli/go.sum
Normal file
47
cli/go.sum
Normal file
@ -0,0 +1,47 @@
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/boyter/gocodewalker v1.4.0 h1:fVmFeQxKpj5tlpjPcyTtJ96btgaHYd9yn6m+T/66et4=
|
||||
github.com/boyter/gocodewalker v1.4.0/go.mod h1:hXG8xzR1uURS+99P5/3xh3uWHjaV2XfoMMmvPyhrCDg=
|
||||
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
|
||||
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
|
||||
github.com/charmbracelet/bubbletea v1.3.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI=
|
||||
github.com/charmbracelet/bubbletea v1.3.4/go.mod h1:dtcUCyCGEX3g9tosuYiut3MXgY/Jsv9nKVdibKKRRXo=
|
||||
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
|
||||
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
|
||||
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
|
||||
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
|
||||
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
||||
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
|
||||
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
|
||||
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
|
||||
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
|
||||
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
19
cli/internal/apps/msg.go
Normal file
19
cli/internal/apps/msg.go
Normal file
@ -0,0 +1,19 @@
|
||||
package apps
|
||||
|
||||
import "time"
|
||||
|
||||
type Msg struct {
|
||||
Text string
|
||||
Time time.Time
|
||||
Key *string
|
||||
Loading *bool
|
||||
Success *bool
|
||||
|
||||
App *App
|
||||
}
|
||||
|
||||
type App struct {
|
||||
Name string
|
||||
Color string
|
||||
Loading *bool
|
||||
}
|
118
cli/internal/apps/node.go
Normal file
118
cli/internal/apps/node.go
Normal file
@ -0,0 +1,118 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/spotdemo4/trevstack/cli/internal/utils"
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
App App
|
||||
c chan Msg
|
||||
ctx context.Context
|
||||
wg *sync.WaitGroup
|
||||
|
||||
dir string
|
||||
|
||||
Cancel context.CancelFunc
|
||||
Wait func()
|
||||
}
|
||||
|
||||
func NewNode(dir string, c chan Msg) *Node {
|
||||
|
||||
// Create new context
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
// Create wait group
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
node := Node{
|
||||
App: App{
|
||||
Name: "node",
|
||||
Color: "#fab387",
|
||||
},
|
||||
c: c,
|
||||
ctx: ctx,
|
||||
wg: &wg,
|
||||
|
||||
dir: dir,
|
||||
|
||||
Cancel: cancel,
|
||||
Wait: wg.Wait,
|
||||
}
|
||||
|
||||
// Start watching
|
||||
go node.dev()
|
||||
|
||||
return &node
|
||||
}
|
||||
|
||||
func (n *Node) msg(m Msg) {
|
||||
m.Time = time.Now()
|
||||
m.App = &n.App
|
||||
n.c <- m
|
||||
}
|
||||
|
||||
func (n *Node) dev() {
|
||||
n.wg.Add(1)
|
||||
defer n.wg.Done()
|
||||
|
||||
// Create cmd
|
||||
cmd := exec.Command("npm", "run", "dev")
|
||||
cmd.Dir = n.dir
|
||||
|
||||
// Stop cmd on exit
|
||||
n.wg.Add(1)
|
||||
go func() {
|
||||
defer n.wg.Done()
|
||||
<-n.ctx.Done()
|
||||
|
||||
if err := cmd.Process.Signal(os.Interrupt); err != nil {
|
||||
cmd.Process.Kill() // If the process is not responding to the interrupt signal, kill it
|
||||
}
|
||||
}()
|
||||
|
||||
// Start cmd
|
||||
out, err := utils.Run(cmd)
|
||||
if err != nil {
|
||||
n.msg(Msg{
|
||||
Text: err.Error(),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Watch for output
|
||||
for line := range out {
|
||||
switch line := line.(type) {
|
||||
case utils.Stdout:
|
||||
n.msg(Msg{
|
||||
Text: string(line),
|
||||
})
|
||||
|
||||
case utils.Stderr:
|
||||
n.msg(Msg{
|
||||
Text: string(line),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
|
||||
case utils.ExitCode:
|
||||
if line == 0 {
|
||||
n.msg(Msg{
|
||||
Text: "Node stopped",
|
||||
Success: utils.BoolPointer(true),
|
||||
})
|
||||
} else {
|
||||
n.msg(Msg{
|
||||
Text: fmt.Sprintf("Node failed with exit code %d", out),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
269
cli/internal/apps/proto.go
Normal file
269
cli/internal/apps/proto.go
Normal file
@ -0,0 +1,269 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/spotdemo4/trevstack/cli/internal/utils"
|
||||
)
|
||||
|
||||
type Proto struct {
|
||||
App App
|
||||
c chan Msg
|
||||
ctx context.Context
|
||||
wg *sync.WaitGroup
|
||||
watcher *fsnotify.Watcher
|
||||
|
||||
dir string
|
||||
rootDir string
|
||||
|
||||
Cancel context.CancelFunc
|
||||
Wait func()
|
||||
}
|
||||
|
||||
func NewProto(dir string, rootDir string, c chan Msg) (*Proto, error) {
|
||||
|
||||
// Create new watcher
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add directory to watcher
|
||||
err = filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.IsDir() {
|
||||
if slices.Contains(watcher.WatchList(), path) {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := watcher.Add(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create new context
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
// Create wait group
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
proto := Proto{
|
||||
App: App{
|
||||
Name: "proto",
|
||||
Color: "#89dceb",
|
||||
},
|
||||
c: c,
|
||||
ctx: ctx,
|
||||
wg: &wg,
|
||||
watcher: watcher,
|
||||
|
||||
dir: dir,
|
||||
rootDir: rootDir,
|
||||
|
||||
Cancel: cancel,
|
||||
Wait: wg.Wait,
|
||||
}
|
||||
|
||||
// Start watching
|
||||
go proto.watch()
|
||||
|
||||
return &proto, nil
|
||||
}
|
||||
|
||||
func (p *Proto) msg(m Msg) {
|
||||
m.Time = time.Now()
|
||||
m.App = &p.App
|
||||
p.c <- m
|
||||
}
|
||||
|
||||
func (p *Proto) watch() {
|
||||
p.wg.Add(1)
|
||||
defer p.wg.Done()
|
||||
defer p.watcher.Close()
|
||||
|
||||
// Create new rate limit map
|
||||
rateLimit := make(map[string]time.Time)
|
||||
|
||||
p.lint()
|
||||
|
||||
p.msg(Msg{
|
||||
Text: "Watching for proto changes...",
|
||||
})
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-p.ctx.Done():
|
||||
return
|
||||
|
||||
case event, ok := <-p.watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Rate limit
|
||||
rl, ok := rateLimit[event.Name]
|
||||
if ok && time.Since(rl) < 1*time.Second {
|
||||
continue
|
||||
}
|
||||
rateLimit[event.Name] = time.Now()
|
||||
|
||||
p.msg(Msg{
|
||||
Text: "File changed: " + strings.TrimPrefix(event.Name, p.dir),
|
||||
})
|
||||
|
||||
ok, _ = p.lint()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
p.generate()
|
||||
|
||||
case err, ok := <-p.watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
p.msg(Msg{
|
||||
Text: err.Error(),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Proto) lint() (bool, error) {
|
||||
p.msg(Msg{
|
||||
Text: "Linting",
|
||||
Loading: utils.BoolPointer(true),
|
||||
Key: utils.StringPointer("lint"),
|
||||
})
|
||||
|
||||
// Run buf lint
|
||||
cmd := exec.Command("buf", "lint")
|
||||
cmd.Dir = p.rootDir
|
||||
out, err := utils.Run(cmd)
|
||||
if err != nil {
|
||||
p.msg(Msg{
|
||||
Text: err.Error(),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Watch for output
|
||||
for line := range out {
|
||||
switch line := line.(type) {
|
||||
case utils.Stdout:
|
||||
p.msg(Msg{
|
||||
Text: string(line),
|
||||
})
|
||||
|
||||
case utils.Stderr:
|
||||
p.msg(Msg{
|
||||
Text: string(line),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
|
||||
case utils.ExitCode:
|
||||
if line == 0 {
|
||||
p.msg(Msg{
|
||||
Text: "Buf lint successful",
|
||||
Success: utils.BoolPointer(true),
|
||||
Loading: utils.BoolPointer(false),
|
||||
Key: utils.StringPointer("lint"),
|
||||
})
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
p.msg(Msg{
|
||||
Text: fmt.Sprintf("Buf lint failed with exit code %d", out),
|
||||
Success: utils.BoolPointer(false),
|
||||
Loading: utils.BoolPointer(false),
|
||||
Key: utils.StringPointer("lint"),
|
||||
})
|
||||
|
||||
return false, fmt.Errorf("buf lint failed with exit code %d", line)
|
||||
}
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("buf lint failed")
|
||||
}
|
||||
|
||||
func (p *Proto) generate() error {
|
||||
p.msg(Msg{
|
||||
Text: "Generating proto files",
|
||||
Loading: utils.BoolPointer(true),
|
||||
Key: utils.StringPointer("generate"),
|
||||
})
|
||||
|
||||
// Run buf gen
|
||||
cmd := exec.Command("buf", "generate")
|
||||
cmd.Dir = p.rootDir
|
||||
out, err := utils.Run(cmd)
|
||||
if err != nil {
|
||||
p.msg(Msg{
|
||||
Text: err.Error(),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Watch for output
|
||||
for line := range out {
|
||||
switch line := line.(type) {
|
||||
case utils.Stdout:
|
||||
p.msg(Msg{
|
||||
Text: string(line),
|
||||
})
|
||||
|
||||
case utils.Stderr:
|
||||
p.msg(Msg{
|
||||
Text: string(line),
|
||||
Success: utils.BoolPointer(false),
|
||||
})
|
||||
|
||||
case utils.ExitCode:
|
||||
if line == 0 {
|
||||
p.msg(Msg{
|
||||
Text: "Buf generate successful",
|
||||
Success: utils.BoolPointer(true),
|
||||
Loading: utils.BoolPointer(false),
|
||||
Key: utils.StringPointer("generate"),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
p.msg(Msg{
|
||||
Text: fmt.Sprintf("Buf generate failed with exit code %d", out),
|
||||
Success: utils.BoolPointer(false),
|
||||
Loading: utils.BoolPointer(false),
|
||||
Key: utils.StringPointer("generate"),
|
||||
})
|
||||
|
||||
return fmt.Errorf("generate failed with exit code %d", line)
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("generate failed")
|
||||
}
|
82
cli/internal/models/cbox.go
Normal file
82
cli/internal/models/cbox.go
Normal file
@ -0,0 +1,82 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/bubbles/viewport"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
type Cbox struct {
|
||||
style lipgloss.Style
|
||||
Viewport *viewport.Model
|
||||
maxPrefixLen int
|
||||
}
|
||||
|
||||
func NewCbox(maxPrefixLen int) *Cbox {
|
||||
s := lipgloss.NewStyle().
|
||||
BorderStyle(lipgloss.NormalBorder()).
|
||||
BorderForeground(lipgloss.Color("#45475a")).
|
||||
BorderTop(true).
|
||||
BorderBottom(true).
|
||||
Margin(1, 0, 0)
|
||||
|
||||
return &Cbox{
|
||||
style: s,
|
||||
Viewport: nil,
|
||||
maxPrefixLen: maxPrefixLen,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cbox) Gen(text string, width int, height int, mtop int, mbottom int) string {
|
||||
if c.Viewport == nil {
|
||||
vp := viewport.New(width, height-(mtop+mbottom))
|
||||
c.Viewport = &vp
|
||||
c.Viewport.YPosition = mtop
|
||||
c.Viewport.Style = c.style
|
||||
} else {
|
||||
c.Viewport.Width = width
|
||||
c.Viewport.Height = height - (mtop + mbottom)
|
||||
c.Viewport.YPosition = mtop
|
||||
}
|
||||
|
||||
atBottom := c.Viewport.AtBottom()
|
||||
|
||||
// Need to add extra lines because of https://github.com/charmbracelet/bubbles/pull/731
|
||||
c.Viewport.SetContent(text + "\n\n\n")
|
||||
|
||||
if atBottom {
|
||||
c.Viewport.GotoBottom()
|
||||
}
|
||||
|
||||
return c.Viewport.View()
|
||||
}
|
||||
|
||||
func (c *Cbox) GenItem(ti time.Time, prefix string, text string, color string, width int) string {
|
||||
t := lipgloss.NewStyle().
|
||||
Padding(0, 1, 0, 1).
|
||||
Foreground(lipgloss.Color("#a6adc8")).
|
||||
Render(ti.Format(time.Kitchen))
|
||||
|
||||
p := lipgloss.NewStyle().
|
||||
Padding(0, 1, 0, 0).
|
||||
Width(c.maxPrefixLen).
|
||||
Foreground(lipgloss.Color(color)).
|
||||
BorderStyle(lipgloss.NormalBorder()).
|
||||
BorderRight(true).
|
||||
BorderForeground(lipgloss.Color(color))
|
||||
|
||||
m := lipgloss.NewStyle().
|
||||
Padding(0, 1, 0, 1).
|
||||
Foreground(lipgloss.Color("#cdd6f4")).
|
||||
Width(width - lipgloss.Width(t) - lipgloss.Width(p.Render(prefix))).
|
||||
Render(text)
|
||||
|
||||
p = p.Height(lipgloss.Height(m))
|
||||
|
||||
combine := lipgloss.JoinHorizontal(lipgloss.Top, t, p.Render(prefix), m)
|
||||
|
||||
return lipgloss.NewStyle().
|
||||
Width(width).
|
||||
Render(combine)
|
||||
}
|
33
cli/internal/models/header.go
Normal file
33
cli/internal/models/header.go
Normal file
@ -0,0 +1,33 @@
|
||||
package models
|
||||
|
||||
import "github.com/charmbracelet/lipgloss"
|
||||
|
||||
type Header struct {
|
||||
style lipgloss.Style
|
||||
}
|
||||
|
||||
func NewHeader() *Header {
|
||||
s := lipgloss.NewStyle().
|
||||
AlignHorizontal(lipgloss.Center).
|
||||
AlignVertical(lipgloss.Bottom).
|
||||
MarginTop(1)
|
||||
|
||||
return &Header{
|
||||
style: s,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Header) Gen(width int, items ...string) string {
|
||||
s := h.style.Width(width)
|
||||
|
||||
pp := lipgloss.JoinHorizontal(lipgloss.Center, items...)
|
||||
|
||||
return s.Render(pp)
|
||||
}
|
||||
|
||||
func (h *Header) GenItem(text string) string {
|
||||
return lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#cdd6f4")).
|
||||
Margin(0, 1).
|
||||
Render(text)
|
||||
}
|
84
cli/internal/models/help.go
Normal file
84
cli/internal/models/help.go
Normal file
@ -0,0 +1,84 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/bubbles/help"
|
||||
"github.com/charmbracelet/bubbles/key"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
// keyMap defines a set of keybindings. To work for help it must satisfy
|
||||
// key.Map. It could also very easily be a map[string]key.Binding.
|
||||
type keyMap struct {
|
||||
Up key.Binding
|
||||
Down key.Binding
|
||||
Left key.Binding
|
||||
Right key.Binding
|
||||
Help key.Binding
|
||||
Quit key.Binding
|
||||
}
|
||||
|
||||
// ShortHelp returns keybindings to be shown in the mini help view. It's part
|
||||
// of the key.Map interface.
|
||||
func (k keyMap) ShortHelp() []key.Binding {
|
||||
return []key.Binding{k.Help, k.Quit}
|
||||
}
|
||||
|
||||
// FullHelp returns keybindings for the expanded help view. It's part of the
|
||||
// key.Map interface.
|
||||
func (k keyMap) FullHelp() [][]key.Binding {
|
||||
return [][]key.Binding{
|
||||
{k.Up, k.Down, k.Left, k.Right}, // first column
|
||||
{k.Help, k.Quit}, // second column
|
||||
}
|
||||
}
|
||||
|
||||
type Help struct {
|
||||
keys keyMap
|
||||
style lipgloss.Style
|
||||
help help.Model
|
||||
}
|
||||
|
||||
func NewHelp() *Help {
|
||||
keys := keyMap{
|
||||
Up: key.NewBinding(
|
||||
key.WithKeys("up", "k"),
|
||||
key.WithHelp("↑/k", "move up"),
|
||||
),
|
||||
Down: key.NewBinding(
|
||||
key.WithKeys("down", "j"),
|
||||
key.WithHelp("↓/j", "move down"),
|
||||
),
|
||||
Left: key.NewBinding(
|
||||
key.WithKeys("left", "h"),
|
||||
key.WithHelp("←/h", "move left"),
|
||||
),
|
||||
Right: key.NewBinding(
|
||||
key.WithKeys("right", "l"),
|
||||
key.WithHelp("→/l", "move right"),
|
||||
),
|
||||
Help: key.NewBinding(
|
||||
key.WithKeys("?"),
|
||||
key.WithHelp("?", "toggle help"),
|
||||
),
|
||||
Quit: key.NewBinding(
|
||||
key.WithKeys("q", "esc", "ctrl+c"),
|
||||
key.WithHelp("q", "quit"),
|
||||
),
|
||||
}
|
||||
|
||||
return &Help{
|
||||
keys: keys,
|
||||
style: lipgloss.NewStyle().Padding(1, 2),
|
||||
help: help.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Help) Gen(width int) string {
|
||||
h.help.Width = width
|
||||
render := h.help.View(h.keys)
|
||||
return h.style.Render(render)
|
||||
}
|
||||
|
||||
func (h *Help) Toggle() {
|
||||
h.help.ShowAll = !h.help.ShowAll
|
||||
}
|
220
cli/internal/models/runner.go
Normal file
220
cli/internal/models/runner.go
Normal file
@ -0,0 +1,220 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/bubbles/key"
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/spotdemo4/trevstack/cli/internal/apps"
|
||||
"github.com/spotdemo4/trevstack/cli/internal/utils"
|
||||
)
|
||||
|
||||
type runner struct {
|
||||
width *int
|
||||
height *int
|
||||
|
||||
prefix lipgloss.Style
|
||||
checkmark string
|
||||
xmark string
|
||||
|
||||
header *Header
|
||||
cbox *Cbox
|
||||
help *Help
|
||||
spinner spinner.Model
|
||||
|
||||
msgChan chan apps.Msg
|
||||
msgs []apps.Msg
|
||||
apps []*apps.App
|
||||
}
|
||||
|
||||
func NewRunner(msgChan chan apps.Msg, applications []*apps.App) *runner {
|
||||
|
||||
prefix := lipgloss.NewStyle().
|
||||
Padding(0, 1, 0, 1).
|
||||
Margin(0, 1, 0, 1).
|
||||
Background(lipgloss.Color("#89dceb")).
|
||||
Foreground(lipgloss.Color("#11111b"))
|
||||
|
||||
checkmark := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#a6e3a1")).
|
||||
Bold(true).
|
||||
Render("✓")
|
||||
|
||||
xmark := lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#f38ba8")).
|
||||
Bold(true).
|
||||
Render("✕")
|
||||
|
||||
mpl := 0
|
||||
for _, app := range applications {
|
||||
if len(app.Name) > mpl {
|
||||
mpl = len(app.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return &runner{
|
||||
width: nil,
|
||||
height: nil,
|
||||
|
||||
prefix: prefix,
|
||||
checkmark: checkmark,
|
||||
xmark: xmark,
|
||||
|
||||
header: NewHeader(),
|
||||
cbox: NewCbox(mpl + 1),
|
||||
help: NewHelp(),
|
||||
spinner: spinner.New(spinner.WithSpinner(spinner.MiniDot), spinner.WithStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("#a6adc8")))),
|
||||
|
||||
msgChan: msgChan,
|
||||
msgs: []apps.Msg{},
|
||||
apps: applications,
|
||||
}
|
||||
}
|
||||
|
||||
func (m runner) Init() tea.Cmd {
|
||||
return tea.Batch(
|
||||
m.spinner.Tick,
|
||||
func() tea.Msg {
|
||||
return apps.Msg(<-m.msgChan)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (m runner) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
var cmds []tea.Cmd
|
||||
|
||||
switch msg := msg.(type) {
|
||||
|
||||
case apps.Msg:
|
||||
// Remove old message with the same key
|
||||
if msg.Key != nil && msg.Loading != nil && !*msg.Loading {
|
||||
for i, prev := range m.msgs {
|
||||
if prev.Key != nil && prev.Loading != nil && *prev.Key == *msg.Key && *prev.Loading {
|
||||
m.msgs = append(m.msgs[:i], m.msgs[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set current state
|
||||
if msg.Loading != nil {
|
||||
if *msg.Loading {
|
||||
msg.App.Loading = nil
|
||||
} else {
|
||||
msg.App.Loading = msg.Success
|
||||
}
|
||||
}
|
||||
|
||||
// Append new message
|
||||
m.msgs = append(m.msgs, msg)
|
||||
|
||||
return m, func() tea.Msg {
|
||||
return apps.Msg(<-m.msgChan)
|
||||
}
|
||||
|
||||
case spinner.TickMsg:
|
||||
m.spinner, cmd = m.spinner.Update(msg)
|
||||
return m, cmd
|
||||
|
||||
case tea.WindowSizeMsg:
|
||||
m.width = utils.IntPointer(msg.Width)
|
||||
m.height = utils.IntPointer(msg.Height)
|
||||
|
||||
case tea.KeyMsg:
|
||||
switch {
|
||||
case key.Matches(msg, m.help.keys.Help):
|
||||
m.help.Toggle()
|
||||
|
||||
case key.Matches(msg, m.help.keys.Quit):
|
||||
return m, tea.Quit
|
||||
}
|
||||
|
||||
case tea.MouseMsg:
|
||||
switch msg.Button {
|
||||
case tea.MouseButtonWheelDown:
|
||||
m.cbox.Viewport.LineDown(1)
|
||||
|
||||
case tea.MouseButtonWheelUp:
|
||||
m.cbox.Viewport.LineUp(1)
|
||||
}
|
||||
}
|
||||
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
func (m runner) term() (rows []string) {
|
||||
if m.width == nil {
|
||||
return rows
|
||||
}
|
||||
|
||||
for _, msg := range m.msgs {
|
||||
item := []string{}
|
||||
|
||||
if msg.Loading != nil && *msg.Loading {
|
||||
item = append(item, m.spinner.View())
|
||||
}
|
||||
|
||||
if msg.Success != nil {
|
||||
if *msg.Success {
|
||||
item = append(item, m.checkmark)
|
||||
} else {
|
||||
item = append(item, m.xmark)
|
||||
}
|
||||
}
|
||||
|
||||
item = append(item, msg.Text)
|
||||
itemStr := strings.Join(item, " ")
|
||||
|
||||
// Render the row
|
||||
rows = append(rows, m.cbox.GenItem(msg.Time, msg.App.Name, itemStr, msg.App.Color, *m.width))
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
func (m runner) head() (items []string) {
|
||||
for _, app := range m.apps {
|
||||
item := []string{}
|
||||
|
||||
if app.Loading == nil {
|
||||
item = append(item, m.spinner.View())
|
||||
} else if *app.Loading {
|
||||
item = append(item, m.checkmark)
|
||||
} else {
|
||||
item = append(item, m.xmark)
|
||||
}
|
||||
|
||||
item = append(item, app.Name)
|
||||
items = append(items, m.header.GenItem(strings.Join(item, " ")))
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func (m runner) View() string {
|
||||
if m.width == nil || m.height == nil {
|
||||
return fmt.Sprintf("\n %s Loading...", m.spinner.View())
|
||||
}
|
||||
|
||||
// Generate the UI
|
||||
header := m.header.Gen(*m.width, m.head()...)
|
||||
footer := m.help.Gen(*m.width)
|
||||
main := m.cbox.Gen(
|
||||
strings.Join(m.term(), "\n"),
|
||||
*m.width,
|
||||
*m.height,
|
||||
lipgloss.Height(header),
|
||||
lipgloss.Height(footer),
|
||||
)
|
||||
|
||||
s := header
|
||||
s += main
|
||||
s += footer
|
||||
|
||||
// Send the UI for rendering
|
||||
return s
|
||||
}
|
13
cli/internal/utils/pointers.go
Normal file
13
cli/internal/utils/pointers.go
Normal file
@ -0,0 +1,13 @@
|
||||
package utils
|
||||
|
||||
func BoolPointer(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
func StringPointer(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
func IntPointer(i int) *int {
|
||||
return &i
|
||||
}
|
55
cli/internal/utils/run.go
Normal file
55
cli/internal/utils/run.go
Normal file
@ -0,0 +1,55 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
type Stdout string
|
||||
type Stderr string
|
||||
type ExitCode int
|
||||
|
||||
func Run(cmd *exec.Cmd) (chan interface{}, error) {
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := make(chan interface{}, 10)
|
||||
|
||||
go func() {
|
||||
scan := bufio.NewScanner(stdout)
|
||||
for scan.Scan() {
|
||||
c <- Stdout(scan.Text())
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
scan := bufio.NewScanner(stderr)
|
||||
for scan.Scan() {
|
||||
c <- Stderr(scan.Text())
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer close(c)
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
c <- ExitCode(exitError.ExitCode())
|
||||
} else {
|
||||
c <- ExitCode(1)
|
||||
}
|
||||
} else {
|
||||
c <- ExitCode(0)
|
||||
}
|
||||
}()
|
||||
|
||||
return c, nil
|
||||
}
|
2
client/.gitignore
vendored
Normal file
2
client/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/node_modules/
|
||||
/.svelte-kit/
|
@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf";
|
||||
* Describes the file user/v1/auth.proto.
|
||||
*/
|
||||
export const file_user_v1_auth: GenFile = /*@__PURE__*/
|
||||
fileDesc("ChJ1c2VyL3YxL2F1dGgucHJvdG8SB3VzZXIudjEiMgoMTG9naW5SZXF1ZXN0EhAKCHVzZXJuYW1lGAEgASgJEhAKCHBhc3N3b3JkGAIgASgJIh4KDUxvZ2luUmVzcG9uc2USDQoFdG9rZW4YASABKAkiTQoNU2lnblVwUmVxdWVzdBIQCgh1c2VybmFtZRgBIAEoCRIQCghwYXNzd29yZBgCIAEoCRIYChBjb25maXJtX3Bhc3N3b3JkGAMgASgJIhAKDlNpZ25VcFJlc3BvbnNlIg8KDUxvZ291dFJlcXVlc3QiEAoOTG9nb3V0UmVzcG9uc2UiKAoUR2V0UGFzc2tleUlEc1JlcXVlc3QSEAoIdXNlcm5hbWUYASABKAkiLAoVR2V0UGFzc2tleUlEc1Jlc3BvbnNlEhMKC3Bhc3NrZXlfaWRzGAEgAygJIkcKE1Bhc3NrZXlMb2dpblJlcXVlc3QSCgoCaWQYASABKAkSEQoJc2lnbmF0dXJlGAIgASgMEhEKCWFsZ29yaXRobRgDIAEoBSIlChRQYXNza2V5TG9naW5SZXNwb25zZRINCgV0b2tlbhgBIAEoCTLiAgoLQXV0aFNlcnZpY2USOAoFTG9naW4SFS51c2VyLnYxLkxvZ2luUmVxdWVzdBoWLnVzZXIudjEuTG9naW5SZXNwb25zZSIAEjsKBlNpZ25VcBIWLnVzZXIudjEuU2lnblVwUmVxdWVzdBoXLnVzZXIudjEuU2lnblVwUmVzcG9uc2UiABI7CgZMb2dvdXQSFi51c2VyLnYxLkxvZ291dFJlcXVlc3QaFy51c2VyLnYxLkxvZ291dFJlc3BvbnNlIgASUAoNR2V0UGFzc2tleUlEcxIdLnVzZXIudjEuR2V0UGFzc2tleUlEc1JlcXVlc3QaHi51c2VyLnYxLkdldFBhc3NrZXlJRHNSZXNwb25zZSIAEk0KDFBhc3NrZXlMb2dpbhIcLnVzZXIudjEuUGFzc2tleUxvZ2luUmVxdWVzdBodLnVzZXIudjEuUGFzc2tleUxvZ2luUmVzcG9uc2UiAEKdAQoLY29tLnVzZXIudjFCCUF1dGhQcm90b1ABWkZnaXRodWIuY29tL3Nwb3RkZW1vNC90cmV2c3RhY2svc2VydmVyL2ludGVybmFsL3NlcnZpY2VzL3VzZXIvdjE7dXNlcnYxogIDVVhYqgIHVXNlci5WMcoCB1VzZXJcVjHiAhNVc2VyXFYxXEdQQk1ldGFkYXRh6gIIVXNlcjo6VjFiBnByb3RvMw");
|
||||
fileDesc("ChJ1c2VyL3YxL2F1dGgucHJvdG8SB3VzZXIudjEiMgoMTG9naW5SZXF1ZXN0EhAKCHVzZXJuYW1lGAEgASgJEhAKCHBhc3N3b3JkGAIgASgJIh4KDUxvZ2luUmVzcG9uc2USDQoFdG9rZW4YASABKAkiTQoNU2lnblVwUmVxdWVzdBIQCgh1c2VybmFtZRgBIAEoCRIQCghwYXNzd29yZBgCIAEoCRIYChBjb25maXJtX3Bhc3N3b3JkGAMgASgJIhAKDlNpZ25VcFJlc3BvbnNlIg8KDUxvZ291dFJlcXVlc3QiEAoOTG9nb3V0UmVzcG9uc2UiKAoUR2V0UGFzc2tleUlEc1JlcXVlc3QSEAoIdXNlcm5hbWUYASABKAkiLAoVR2V0UGFzc2tleUlEc1Jlc3BvbnNlEhMKC3Bhc3NrZXlfaWRzGAEgAygJIhoKGEJlZ2luUGFzc2tleUxvZ2luUmVxdWVzdCIbChlCZWdpblBhc3NrZXlMb2dpblJlc3BvbnNlIhsKGUZpbmlzaFBhc3NrZXlMb2dpblJlcXVlc3QiHAoaRmluaXNoUGFzc2tleUxvZ2luUmVzcG9uc2Uy0gMKC0F1dGhTZXJ2aWNlEjgKBUxvZ2luEhUudXNlci52MS5Mb2dpblJlcXVlc3QaFi51c2VyLnYxLkxvZ2luUmVzcG9uc2UiABI7CgZTaWduVXASFi51c2VyLnYxLlNpZ25VcFJlcXVlc3QaFy51c2VyLnYxLlNpZ25VcFJlc3BvbnNlIgASOwoGTG9nb3V0EhYudXNlci52MS5Mb2dvdXRSZXF1ZXN0GhcudXNlci52MS5Mb2dvdXRSZXNwb25zZSIAElAKDUdldFBhc3NrZXlJRHMSHS51c2VyLnYxLkdldFBhc3NrZXlJRHNSZXF1ZXN0Gh4udXNlci52MS5HZXRQYXNza2V5SURzUmVzcG9uc2UiABJcChFCZWdpblBhc3NrZXlMb2dpbhIhLnVzZXIudjEuQmVnaW5QYXNza2V5TG9naW5SZXF1ZXN0GiIudXNlci52MS5CZWdpblBhc3NrZXlMb2dpblJlc3BvbnNlIgASXwoSRmluaXNoUGFzc2tleUxvZ2luEiIudXNlci52MS5GaW5pc2hQYXNza2V5TG9naW5SZXF1ZXN0GiMudXNlci52MS5GaW5pc2hQYXNza2V5TG9naW5SZXNwb25zZSIAQp0BCgtjb20udXNlci52MUIJQXV0aFByb3RvUAFaRmdpdGh1Yi5jb20vc3BvdGRlbW80L3RyZXZzdGFjay9zZXJ2ZXIvaW50ZXJuYWwvc2VydmljZXMvdXNlci92MTt1c2VydjGiAgNVWFiqAgdVc2VyLlYxygIHVXNlclxWMeICE1VzZXJcVjFcR1BCTWV0YWRhdGHqAghVc2VyOjpWMWIGcHJvdG8z");
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.LoginRequest
|
||||
@ -152,49 +152,57 @@ export const GetPasskeyIDsResponseSchema: GenMessage<GetPasskeyIDsResponse> = /*
|
||||
messageDesc(file_user_v1_auth, 7);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.PasskeyLoginRequest
|
||||
* @generated from message user.v1.BeginPasskeyLoginRequest
|
||||
*/
|
||||
export type PasskeyLoginRequest = Message<"user.v1.PasskeyLoginRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* @generated from field: bytes signature = 2;
|
||||
*/
|
||||
signature: Uint8Array;
|
||||
|
||||
/**
|
||||
* @generated from field: int32 algorithm = 3;
|
||||
*/
|
||||
algorithm: number;
|
||||
export type BeginPasskeyLoginRequest = Message<"user.v1.BeginPasskeyLoginRequest"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.PasskeyLoginRequest.
|
||||
* Use `create(PasskeyLoginRequestSchema)` to create a new message.
|
||||
* Describes the message user.v1.BeginPasskeyLoginRequest.
|
||||
* Use `create(BeginPasskeyLoginRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const PasskeyLoginRequestSchema: GenMessage<PasskeyLoginRequest> = /*@__PURE__*/
|
||||
export const BeginPasskeyLoginRequestSchema: GenMessage<BeginPasskeyLoginRequest> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_auth, 8);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.PasskeyLoginResponse
|
||||
* @generated from message user.v1.BeginPasskeyLoginResponse
|
||||
*/
|
||||
export type PasskeyLoginResponse = Message<"user.v1.PasskeyLoginResponse"> & {
|
||||
/**
|
||||
* @generated from field: string token = 1;
|
||||
*/
|
||||
token: string;
|
||||
export type BeginPasskeyLoginResponse = Message<"user.v1.BeginPasskeyLoginResponse"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.PasskeyLoginResponse.
|
||||
* Use `create(PasskeyLoginResponseSchema)` to create a new message.
|
||||
* Describes the message user.v1.BeginPasskeyLoginResponse.
|
||||
* Use `create(BeginPasskeyLoginResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const PasskeyLoginResponseSchema: GenMessage<PasskeyLoginResponse> = /*@__PURE__*/
|
||||
export const BeginPasskeyLoginResponseSchema: GenMessage<BeginPasskeyLoginResponse> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_auth, 9);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.FinishPasskeyLoginRequest
|
||||
*/
|
||||
export type FinishPasskeyLoginRequest = Message<"user.v1.FinishPasskeyLoginRequest"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.FinishPasskeyLoginRequest.
|
||||
* Use `create(FinishPasskeyLoginRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const FinishPasskeyLoginRequestSchema: GenMessage<FinishPasskeyLoginRequest> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_auth, 10);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.FinishPasskeyLoginResponse
|
||||
*/
|
||||
export type FinishPasskeyLoginResponse = Message<"user.v1.FinishPasskeyLoginResponse"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.FinishPasskeyLoginResponse.
|
||||
* Use `create(FinishPasskeyLoginResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const FinishPasskeyLoginResponseSchema: GenMessage<FinishPasskeyLoginResponse> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_auth, 11);
|
||||
|
||||
/**
|
||||
* @generated from service user.v1.AuthService
|
||||
*/
|
||||
@ -232,12 +240,20 @@ export const AuthService: GenService<{
|
||||
output: typeof GetPasskeyIDsResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc user.v1.AuthService.PasskeyLogin
|
||||
* @generated from rpc user.v1.AuthService.BeginPasskeyLogin
|
||||
*/
|
||||
passkeyLogin: {
|
||||
beginPasskeyLogin: {
|
||||
methodKind: "unary";
|
||||
input: typeof PasskeyLoginRequestSchema;
|
||||
output: typeof PasskeyLoginResponseSchema;
|
||||
input: typeof BeginPasskeyLoginRequestSchema;
|
||||
output: typeof BeginPasskeyLoginResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc user.v1.AuthService.FinishPasskeyLogin
|
||||
*/
|
||||
finishPasskeyLogin: {
|
||||
methodKind: "unary";
|
||||
input: typeof FinishPasskeyLoginRequestSchema;
|
||||
output: typeof FinishPasskeyLoginResponseSchema;
|
||||
},
|
||||
}> = /*@__PURE__*/
|
||||
serviceDesc(file_user_v1_auth, 0);
|
||||
|
@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf";
|
||||
* Describes the file user/v1/user.proto.
|
||||
*/
|
||||
export const file_user_v1_user: GenFile = /*@__PURE__*/
|
||||
fileDesc("ChJ1c2VyL3YxL3VzZXIucHJvdG8SB3VzZXIudjEiVgoEVXNlchIKCgJpZBgBIAEoDRIQCgh1c2VybmFtZRgCIAEoCRIcCg9wcm9maWxlX3BpY3R1cmUYAyABKAlIAIgBAUISChBfcHJvZmlsZV9waWN0dXJlIhAKDkdldFVzZXJSZXF1ZXN0Ii4KD0dldFVzZXJSZXNwb25zZRIbCgR1c2VyGAEgASgLMg0udXNlci52MS5Vc2VyIl0KFVVwZGF0ZVBhc3N3b3JkUmVxdWVzdBIUCgxvbGRfcGFzc3dvcmQYASABKAkSFAoMbmV3X3Bhc3N3b3JkGAIgASgJEhgKEGNvbmZpcm1fcGFzc3dvcmQYAyABKAkiNQoWVXBkYXRlUGFzc3dvcmRSZXNwb25zZRIbCgR1c2VyGAEgASgLMg0udXNlci52MS5Vc2VyIj4KEEdldEFQSUtleVJlcXVlc3QSEAoIcGFzc3dvcmQYASABKAkSGAoQY29uZmlybV9wYXNzd29yZBgCIAEoCSIgChFHZXRBUElLZXlSZXNwb25zZRILCgNrZXkYASABKAkiPgobVXBkYXRlUHJvZmlsZVBpY3R1cmVSZXF1ZXN0EhEKCWZpbGVfbmFtZRgBIAEoCRIMCgRkYXRhGAIgASgMIjsKHFVwZGF0ZVByb2ZpbGVQaWN0dXJlUmVzcG9uc2USGwoEdXNlchgBIAEoCzINLnVzZXIudjEuVXNlciI2ChRDcmVhdGVQYXNza2V5UmVxdWVzdBIKCgJpZBgBIAEoCRISCgpwdWJsaWNfa2V5GAIgASgMIhcKFUNyZWF0ZVBhc3NrZXlSZXNwb25zZTKhAwoLVXNlclNlcnZpY2USPgoHR2V0VXNlchIXLnVzZXIudjEuR2V0VXNlclJlcXVlc3QaGC51c2VyLnYxLkdldFVzZXJSZXNwb25zZSIAElMKDlVwZGF0ZVBhc3N3b3JkEh4udXNlci52MS5VcGRhdGVQYXNzd29yZFJlcXVlc3QaHy51c2VyLnYxLlVwZGF0ZVBhc3N3b3JkUmVzcG9uc2UiABJECglHZXRBUElLZXkSGS51c2VyLnYxLkdldEFQSUtleVJlcXVlc3QaGi51c2VyLnYxLkdldEFQSUtleVJlc3BvbnNlIgASZQoUVXBkYXRlUHJvZmlsZVBpY3R1cmUSJC51c2VyLnYxLlVwZGF0ZVByb2ZpbGVQaWN0dXJlUmVxdWVzdBolLnVzZXIudjEuVXBkYXRlUHJvZmlsZVBpY3R1cmVSZXNwb25zZSIAElAKDUNyZWF0ZVBhc3NrZXkSHS51c2VyLnYxLkNyZWF0ZVBhc3NrZXlSZXF1ZXN0Gh4udXNlci52MS5DcmVhdGVQYXNza2V5UmVzcG9uc2UiAEKdAQoLY29tLnVzZXIudjFCCVVzZXJQcm90b1ABWkZnaXRodWIuY29tL3Nwb3RkZW1vNC90cmV2c3RhY2svc2VydmVyL2ludGVybmFsL3NlcnZpY2VzL3VzZXIvdjE7dXNlcnYxogIDVVhYqgIHVXNlci5WMcoCB1VzZXJcVjHiAhNVc2VyXFYxXEdQQk1ldGFkYXRh6gIIVXNlcjo6VjFiBnByb3RvMw");
|
||||
fileDesc("ChJ1c2VyL3YxL3VzZXIucHJvdG8SB3VzZXIudjEiVgoEVXNlchIKCgJpZBgBIAEoDRIQCgh1c2VybmFtZRgCIAEoCRIcCg9wcm9maWxlX3BpY3R1cmUYAyABKAlIAIgBAUISChBfcHJvZmlsZV9waWN0dXJlIhAKDkdldFVzZXJSZXF1ZXN0Ii4KD0dldFVzZXJSZXNwb25zZRIbCgR1c2VyGAEgASgLMg0udXNlci52MS5Vc2VyIl0KFVVwZGF0ZVBhc3N3b3JkUmVxdWVzdBIUCgxvbGRfcGFzc3dvcmQYASABKAkSFAoMbmV3X3Bhc3N3b3JkGAIgASgJEhgKEGNvbmZpcm1fcGFzc3dvcmQYAyABKAkiNQoWVXBkYXRlUGFzc3dvcmRSZXNwb25zZRIbCgR1c2VyGAEgASgLMg0udXNlci52MS5Vc2VyIj4KEEdldEFQSUtleVJlcXVlc3QSEAoIcGFzc3dvcmQYASABKAkSGAoQY29uZmlybV9wYXNzd29yZBgCIAEoCSIgChFHZXRBUElLZXlSZXNwb25zZRILCgNrZXkYASABKAkiPgobVXBkYXRlUHJvZmlsZVBpY3R1cmVSZXF1ZXN0EhEKCWZpbGVfbmFtZRgBIAEoCRIMCgRkYXRhGAIgASgMIjsKHFVwZGF0ZVByb2ZpbGVQaWN0dXJlUmVzcG9uc2USGwoEdXNlchgBIAEoCzINLnVzZXIudjEuVXNlciIhCh9CZWdpblBhc3NrZXlSZWdpc3RyYXRpb25SZXF1ZXN0IiIKIEJlZ2luUGFzc2tleVJlZ2lzdHJhdGlvblJlc3BvbnNlIiIKIEZpbmlzaFBhc3NrZXlSZWdpc3RyYXRpb25SZXF1ZXN0IiMKIUZpbmlzaFBhc3NrZXlSZWdpc3RyYXRpb25SZXNwb25zZTK4BAoLVXNlclNlcnZpY2USPgoHR2V0VXNlchIXLnVzZXIudjEuR2V0VXNlclJlcXVlc3QaGC51c2VyLnYxLkdldFVzZXJSZXNwb25zZSIAElMKDlVwZGF0ZVBhc3N3b3JkEh4udXNlci52MS5VcGRhdGVQYXNzd29yZFJlcXVlc3QaHy51c2VyLnYxLlVwZGF0ZVBhc3N3b3JkUmVzcG9uc2UiABJECglHZXRBUElLZXkSGS51c2VyLnYxLkdldEFQSUtleVJlcXVlc3QaGi51c2VyLnYxLkdldEFQSUtleVJlc3BvbnNlIgASZQoUVXBkYXRlUHJvZmlsZVBpY3R1cmUSJC51c2VyLnYxLlVwZGF0ZVByb2ZpbGVQaWN0dXJlUmVxdWVzdBolLnVzZXIudjEuVXBkYXRlUHJvZmlsZVBpY3R1cmVSZXNwb25zZSIAEnEKGEJlZ2luUGFzc2tleVJlZ2lzdHJhdGlvbhIoLnVzZXIudjEuQmVnaW5QYXNza2V5UmVnaXN0cmF0aW9uUmVxdWVzdBopLnVzZXIudjEuQmVnaW5QYXNza2V5UmVnaXN0cmF0aW9uUmVzcG9uc2UiABJ0ChlGaW5pc2hQYXNza2V5UmVnaXN0cmF0aW9uEikudXNlci52MS5GaW5pc2hQYXNza2V5UmVnaXN0cmF0aW9uUmVxdWVzdBoqLnVzZXIudjEuRmluaXNoUGFzc2tleVJlZ2lzdHJhdGlvblJlc3BvbnNlIgBCnQEKC2NvbS51c2VyLnYxQglVc2VyUHJvdG9QAVpGZ2l0aHViLmNvbS9zcG90ZGVtbzQvdHJldnN0YWNrL3NlcnZlci9pbnRlcm5hbC9zZXJ2aWNlcy91c2VyL3YxO3VzZXJ2MaICA1VYWKoCB1VzZXIuVjHKAgdVc2VyXFYx4gITVXNlclxWMVxHUEJNZXRhZGF0YeoCCFVzZXI6OlYxYgZwcm90bzM");
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.User
|
||||
@ -192,40 +192,57 @@ export const UpdateProfilePictureResponseSchema: GenMessage<UpdateProfilePicture
|
||||
messageDesc(file_user_v1_user, 8);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.CreatePasskeyRequest
|
||||
* @generated from message user.v1.BeginPasskeyRegistrationRequest
|
||||
*/
|
||||
export type CreatePasskeyRequest = Message<"user.v1.CreatePasskeyRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* @generated from field: bytes public_key = 2;
|
||||
*/
|
||||
publicKey: Uint8Array;
|
||||
export type BeginPasskeyRegistrationRequest = Message<"user.v1.BeginPasskeyRegistrationRequest"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.CreatePasskeyRequest.
|
||||
* Use `create(CreatePasskeyRequestSchema)` to create a new message.
|
||||
* Describes the message user.v1.BeginPasskeyRegistrationRequest.
|
||||
* Use `create(BeginPasskeyRegistrationRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const CreatePasskeyRequestSchema: GenMessage<CreatePasskeyRequest> = /*@__PURE__*/
|
||||
export const BeginPasskeyRegistrationRequestSchema: GenMessage<BeginPasskeyRegistrationRequest> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_user, 9);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.CreatePasskeyResponse
|
||||
* @generated from message user.v1.BeginPasskeyRegistrationResponse
|
||||
*/
|
||||
export type CreatePasskeyResponse = Message<"user.v1.CreatePasskeyResponse"> & {
|
||||
export type BeginPasskeyRegistrationResponse = Message<"user.v1.BeginPasskeyRegistrationResponse"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.CreatePasskeyResponse.
|
||||
* Use `create(CreatePasskeyResponseSchema)` to create a new message.
|
||||
* Describes the message user.v1.BeginPasskeyRegistrationResponse.
|
||||
* Use `create(BeginPasskeyRegistrationResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const CreatePasskeyResponseSchema: GenMessage<CreatePasskeyResponse> = /*@__PURE__*/
|
||||
export const BeginPasskeyRegistrationResponseSchema: GenMessage<BeginPasskeyRegistrationResponse> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_user, 10);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.FinishPasskeyRegistrationRequest
|
||||
*/
|
||||
export type FinishPasskeyRegistrationRequest = Message<"user.v1.FinishPasskeyRegistrationRequest"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.FinishPasskeyRegistrationRequest.
|
||||
* Use `create(FinishPasskeyRegistrationRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const FinishPasskeyRegistrationRequestSchema: GenMessage<FinishPasskeyRegistrationRequest> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_user, 11);
|
||||
|
||||
/**
|
||||
* @generated from message user.v1.FinishPasskeyRegistrationResponse
|
||||
*/
|
||||
export type FinishPasskeyRegistrationResponse = Message<"user.v1.FinishPasskeyRegistrationResponse"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message user.v1.FinishPasskeyRegistrationResponse.
|
||||
* Use `create(FinishPasskeyRegistrationResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const FinishPasskeyRegistrationResponseSchema: GenMessage<FinishPasskeyRegistrationResponse> = /*@__PURE__*/
|
||||
messageDesc(file_user_v1_user, 12);
|
||||
|
||||
/**
|
||||
* @generated from service user.v1.UserService
|
||||
*/
|
||||
@ -263,12 +280,20 @@ export const UserService: GenService<{
|
||||
output: typeof UpdateProfilePictureResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc user.v1.UserService.CreatePasskey
|
||||
* @generated from rpc user.v1.UserService.BeginPasskeyRegistration
|
||||
*/
|
||||
createPasskey: {
|
||||
beginPasskeyRegistration: {
|
||||
methodKind: "unary";
|
||||
input: typeof CreatePasskeyRequestSchema;
|
||||
output: typeof CreatePasskeyResponseSchema;
|
||||
input: typeof BeginPasskeyRegistrationRequestSchema;
|
||||
output: typeof BeginPasskeyRegistrationResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc user.v1.UserService.FinishPasskeyRegistration
|
||||
*/
|
||||
finishPasskeyRegistration: {
|
||||
methodKind: "unary";
|
||||
input: typeof FinishPasskeyRegistrationRequestSchema;
|
||||
output: typeof FinishPasskeyRegistrationResponseSchema;
|
||||
},
|
||||
}> = /*@__PURE__*/
|
||||
serviceDesc(file_user_v1_user, 0);
|
||||
|
@ -292,6 +292,22 @@ components:
|
||||
additionalProperties: true
|
||||
additionalProperties: true
|
||||
description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
|
||||
user.v1.BeginPasskeyLoginRequest:
|
||||
type: object
|
||||
title: BeginPasskeyLoginRequest
|
||||
additionalProperties: false
|
||||
user.v1.BeginPasskeyLoginResponse:
|
||||
type: object
|
||||
title: BeginPasskeyLoginResponse
|
||||
additionalProperties: false
|
||||
user.v1.FinishPasskeyLoginRequest:
|
||||
type: object
|
||||
title: FinishPasskeyLoginRequest
|
||||
additionalProperties: false
|
||||
user.v1.FinishPasskeyLoginResponse:
|
||||
type: object
|
||||
title: FinishPasskeyLoginResponse
|
||||
additionalProperties: false
|
||||
user.v1.GetPasskeyIDsRequest:
|
||||
type: object
|
||||
properties:
|
||||
@ -337,30 +353,6 @@ components:
|
||||
type: object
|
||||
title: LogoutResponse
|
||||
additionalProperties: false
|
||||
user.v1.PasskeyLoginRequest:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
title: id
|
||||
signature:
|
||||
type: string
|
||||
title: signature
|
||||
format: byte
|
||||
algorithm:
|
||||
type: integer
|
||||
title: algorithm
|
||||
format: int32
|
||||
title: PasskeyLoginRequest
|
||||
additionalProperties: false
|
||||
user.v1.PasskeyLoginResponse:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
title: PasskeyLoginResponse
|
||||
additionalProperties: false
|
||||
user.v1.SignUpRequest:
|
||||
type: object
|
||||
properties:
|
||||
@ -379,21 +371,21 @@ components:
|
||||
type: object
|
||||
title: SignUpResponse
|
||||
additionalProperties: false
|
||||
user.v1.CreatePasskeyRequest:
|
||||
user.v1.BeginPasskeyRegistrationRequest:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
title: id
|
||||
publicKey:
|
||||
type: string
|
||||
title: public_key
|
||||
format: byte
|
||||
title: CreatePasskeyRequest
|
||||
title: BeginPasskeyRegistrationRequest
|
||||
additionalProperties: false
|
||||
user.v1.CreatePasskeyResponse:
|
||||
user.v1.BeginPasskeyRegistrationResponse:
|
||||
type: object
|
||||
title: CreatePasskeyResponse
|
||||
title: BeginPasskeyRegistrationResponse
|
||||
additionalProperties: false
|
||||
user.v1.FinishPasskeyRegistrationRequest:
|
||||
type: object
|
||||
title: FinishPasskeyRegistrationRequest
|
||||
additionalProperties: false
|
||||
user.v1.FinishPasskeyRegistrationResponse:
|
||||
type: object
|
||||
title: FinishPasskeyRegistrationResponse
|
||||
additionalProperties: false
|
||||
user.v1.GetAPIKeyRequest:
|
||||
type: object
|
||||
@ -801,12 +793,12 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.GetPasskeyIDsResponse'
|
||||
/user.v1.AuthService/PasskeyLogin:
|
||||
/user.v1.AuthService/BeginPasskeyLogin:
|
||||
post:
|
||||
tags:
|
||||
- user.v1.AuthService
|
||||
summary: PasskeyLogin
|
||||
operationId: user.v1.AuthService.PasskeyLogin
|
||||
summary: BeginPasskeyLogin
|
||||
operationId: user.v1.AuthService.BeginPasskeyLogin
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@ -821,7 +813,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.PasskeyLoginRequest'
|
||||
$ref: '#/components/schemas/user.v1.BeginPasskeyLoginRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
@ -835,7 +827,42 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.PasskeyLoginResponse'
|
||||
$ref: '#/components/schemas/user.v1.BeginPasskeyLoginResponse'
|
||||
/user.v1.AuthService/FinishPasskeyLogin:
|
||||
post:
|
||||
tags:
|
||||
- user.v1.AuthService
|
||||
summary: FinishPasskeyLogin
|
||||
operationId: user.v1.AuthService.FinishPasskeyLogin
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-protocol-version'
|
||||
- name: Connect-Timeout-Ms
|
||||
in: header
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-timeout-header'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.FinishPasskeyLoginRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
description: Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect.error'
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.FinishPasskeyLoginResponse'
|
||||
/user.v1.UserService/GetUser:
|
||||
post:
|
||||
tags:
|
||||
@ -976,12 +1003,12 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.UpdateProfilePictureResponse'
|
||||
/user.v1.UserService/CreatePasskey:
|
||||
/user.v1.UserService/BeginPasskeyRegistration:
|
||||
post:
|
||||
tags:
|
||||
- user.v1.UserService
|
||||
summary: CreatePasskey
|
||||
operationId: user.v1.UserService.CreatePasskey
|
||||
summary: BeginPasskeyRegistration
|
||||
operationId: user.v1.UserService.BeginPasskeyRegistration
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@ -996,7 +1023,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.CreatePasskeyRequest'
|
||||
$ref: '#/components/schemas/user.v1.BeginPasskeyRegistrationRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
@ -1010,7 +1037,42 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.CreatePasskeyResponse'
|
||||
$ref: '#/components/schemas/user.v1.BeginPasskeyRegistrationResponse'
|
||||
/user.v1.UserService/FinishPasskeyRegistration:
|
||||
post:
|
||||
tags:
|
||||
- user.v1.UserService
|
||||
summary: FinishPasskeyRegistration
|
||||
operationId: user.v1.UserService.FinishPasskeyRegistration
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-protocol-version'
|
||||
- name: Connect-Timeout-Ms
|
||||
in: header
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-timeout-header'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.FinishPasskeyRegistrationRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
description: Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect.error'
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/user.v1.FinishPasskeyRegistrationResponse'
|
||||
tags:
|
||||
- name: item.v1.ItemService
|
||||
- name: user.v1.AuthService
|
||||
|
16
flake.nix
16
flake.nix
@ -34,6 +34,21 @@
|
||||
nativeCheckInputs = with pkgs; [ less ];
|
||||
};
|
||||
|
||||
bobgen = pkgs.buildGoModule {
|
||||
name = "bobgen";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "stephenafamo";
|
||||
repo = "bob";
|
||||
rev = "v0.31.0";
|
||||
sha256 = "sha256-APAckQ+EDAu459NTPXUISLIrcAcX3aQ5B/jrMUEW0EY=";
|
||||
};
|
||||
vendorHash = "sha256-3blGiSxlKpWH8k0acAXXks8nCdnoWmXLmzPStJmmGcM=";
|
||||
subPackages = [
|
||||
"gen/bobgen-sqlite"
|
||||
"gen/bobgen-psql"
|
||||
];
|
||||
};
|
||||
|
||||
client = pkgs.buildNpmPackage {
|
||||
pname = "${pname}-client";
|
||||
inherit version;
|
||||
@ -72,6 +87,7 @@
|
||||
gopls
|
||||
air
|
||||
revive
|
||||
bobgen
|
||||
|
||||
# Protobuf middleware
|
||||
buf
|
||||
|
@ -7,7 +7,8 @@ service AuthService {
|
||||
rpc SignUp (SignUpRequest) returns (SignUpResponse) {}
|
||||
rpc Logout (LogoutRequest) returns (LogoutResponse) {}
|
||||
rpc GetPasskeyIDs (GetPasskeyIDsRequest) returns (GetPasskeyIDsResponse) {}
|
||||
rpc PasskeyLogin (PasskeyLoginRequest) returns (PasskeyLoginResponse) {}
|
||||
rpc BeginPasskeyLogin (BeginPasskeyLoginRequest) returns (BeginPasskeyLoginResponse) {}
|
||||
rpc FinishPasskeyLogin (FinishPasskeyLoginRequest) returns (FinishPasskeyLoginResponse) {}
|
||||
}
|
||||
|
||||
message LoginRequest {
|
||||
@ -20,7 +21,7 @@ message LoginResponse {
|
||||
|
||||
message SignUpRequest {
|
||||
string username = 1;
|
||||
string password = 2;
|
||||
string password = 2;
|
||||
string confirm_password = 3;
|
||||
}
|
||||
message SignUpResponse {}
|
||||
@ -35,11 +36,8 @@ message GetPasskeyIDsResponse {
|
||||
repeated string passkey_ids = 1;
|
||||
}
|
||||
|
||||
message PasskeyLoginRequest {
|
||||
string id = 1;
|
||||
bytes signature = 2;
|
||||
int32 algorithm = 3;
|
||||
}
|
||||
message PasskeyLoginResponse {
|
||||
string token = 1;
|
||||
}
|
||||
message BeginPasskeyLoginRequest {}
|
||||
message BeginPasskeyLoginResponse {}
|
||||
|
||||
message FinishPasskeyLoginRequest {}
|
||||
message FinishPasskeyLoginResponse {}
|
@ -13,7 +13,8 @@ service UserService {
|
||||
rpc UpdatePassword (UpdatePasswordRequest) returns (UpdatePasswordResponse) {}
|
||||
rpc GetAPIKey (GetAPIKeyRequest) returns (GetAPIKeyResponse) {}
|
||||
rpc UpdateProfilePicture (UpdateProfilePictureRequest) returns (UpdateProfilePictureResponse) {}
|
||||
rpc CreatePasskey (CreatePasskeyRequest) returns (CreatePasskeyResponse) {}
|
||||
rpc BeginPasskeyRegistration (BeginPasskeyRegistrationRequest) returns (BeginPasskeyRegistrationResponse) {}
|
||||
rpc FinishPasskeyRegistration (FinishPasskeyRegistrationRequest) returns (FinishPasskeyRegistrationResponse) {}
|
||||
}
|
||||
|
||||
message GetUserRequest {}
|
||||
@ -34,7 +35,7 @@ message GetAPIKeyRequest {
|
||||
string password = 1;
|
||||
string confirm_password = 2;
|
||||
}
|
||||
message GetAPIKeyResponse {
|
||||
message GetAPIKeyResponse {
|
||||
string key = 1;
|
||||
}
|
||||
|
||||
@ -46,8 +47,8 @@ message UpdateProfilePictureResponse {
|
||||
User user = 1;
|
||||
}
|
||||
|
||||
message CreatePasskeyRequest {
|
||||
string id = 1;
|
||||
bytes public_key = 2;
|
||||
}
|
||||
message CreatePasskeyResponse {}
|
||||
message BeginPasskeyRegistrationRequest {}
|
||||
message BeginPasskeyRegistrationResponse {}
|
||||
|
||||
message FinishPasskeyRegistrationRequest {}
|
||||
message FinishPasskeyRegistrationResponse {}
|
3
server/.gitignore
vendored
Normal file
3
server/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/client/
|
||||
/tmp/
|
||||
/internal/handlers/client/client/
|
10
server/bobgen.yaml
Normal file
10
server/bobgen.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
wipe: true
|
||||
|
||||
sqlite:
|
||||
output: internal/models
|
||||
|
||||
psql:
|
||||
output: internal/models
|
||||
|
||||
mysql:
|
||||
output: internal/models
|
@ -169,6 +169,38 @@ func (h *Handler) UpdateProfilePicture(ctx context.Context, req *connect.Request
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (h *Handler) BeginPasskeyRegistration(ctx context.Context, req *connect.Request[userv1.BeginPasskeyRegistrationRequest]) (*connect.Response[userv1.BeginPasskeyRegistrationResponse], error) {
|
||||
// Get user ID from context
|
||||
userid, ok := interceptors.GetUserContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("user not authenticated"))
|
||||
}
|
||||
|
||||
// Get user
|
||||
user := models.User{}
|
||||
if err := h.db.First(&user, "id = ?", userid).Error; err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&userv1.BeginPasskeyRegistrationResponse{}), nil
|
||||
}
|
||||
|
||||
func (h *Handler) FinishPasskeyRegistration(ctx context.Context, req *connect.Request[userv1.FinishPasskeyRegistrationRequest]) (*connect.Response[userv1.FinishPasskeyRegistrationResponse], error) {
|
||||
// Get user ID from context
|
||||
userid, ok := interceptors.GetUserContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("user not authenticated"))
|
||||
}
|
||||
|
||||
// Get user
|
||||
user := models.User{}
|
||||
if err := h.db.First(&user, "id = ?", userid).Error; err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&userv1.FinishPasskeyRegistrationResponse{}), nil
|
||||
}
|
||||
|
||||
// func BeginRegistration(ctx context.Context) error {
|
||||
// userid, ok := interceptors.GetUserContext(ctx)
|
||||
// if !ok {
|
||||
|
162
server/internal/models/bob_main.bob.go
Normal file
162
server/internal/models/bob_main.bob.go
Normal file
@ -0,0 +1,162 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"hash/maphash"
|
||||
"strings"
|
||||
|
||||
"github.com/stephenafamo/bob"
|
||||
"github.com/stephenafamo/bob/clause"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/dialect"
|
||||
sqliteDriver "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
var TableNames = struct {
|
||||
Files string
|
||||
Items string
|
||||
Users string
|
||||
}{
|
||||
Files: "files",
|
||||
Items: "items",
|
||||
Users: "users",
|
||||
}
|
||||
|
||||
var ColumnNames = struct {
|
||||
Files fileColumnNames
|
||||
Items itemColumnNames
|
||||
Users userColumnNames
|
||||
}{
|
||||
Files: fileColumnNames{
|
||||
ID: "id",
|
||||
Name: "name",
|
||||
Data: "data",
|
||||
UserID: "user_id",
|
||||
},
|
||||
Items: itemColumnNames{
|
||||
ID: "id",
|
||||
Name: "name",
|
||||
Description: "description",
|
||||
Price: "price",
|
||||
Quantity: "quantity",
|
||||
Added: "added",
|
||||
UserID: "user_id",
|
||||
},
|
||||
Users: userColumnNames{
|
||||
ID: "id",
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
ProfilePictureID: "profile_picture_id",
|
||||
Challenge: "challenge",
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
SelectWhere = Where[*dialect.SelectQuery]()
|
||||
InsertWhere = Where[*dialect.InsertQuery]()
|
||||
UpdateWhere = Where[*dialect.UpdateQuery]()
|
||||
DeleteWhere = Where[*dialect.DeleteQuery]()
|
||||
)
|
||||
|
||||
func Where[Q sqlite.Filterable]() struct {
|
||||
Files fileWhere[Q]
|
||||
Items itemWhere[Q]
|
||||
Users userWhere[Q]
|
||||
} {
|
||||
return struct {
|
||||
Files fileWhere[Q]
|
||||
Items itemWhere[Q]
|
||||
Users userWhere[Q]
|
||||
}{
|
||||
Files: buildFileWhere[Q](FileColumns),
|
||||
Items: buildItemWhere[Q](ItemColumns),
|
||||
Users: buildUserWhere[Q](UserColumns),
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
SelectJoins = getJoins[*dialect.SelectQuery]
|
||||
UpdateJoins = getJoins[*dialect.UpdateQuery]
|
||||
)
|
||||
|
||||
type joinSet[Q interface{ aliasedAs(string) Q }] struct {
|
||||
InnerJoin Q
|
||||
LeftJoin Q
|
||||
RightJoin Q
|
||||
}
|
||||
|
||||
func (j joinSet[Q]) AliasedAs(alias string) joinSet[Q] {
|
||||
return joinSet[Q]{
|
||||
InnerJoin: j.InnerJoin.aliasedAs(alias),
|
||||
LeftJoin: j.LeftJoin.aliasedAs(alias),
|
||||
RightJoin: j.RightJoin.aliasedAs(alias),
|
||||
}
|
||||
}
|
||||
|
||||
type joins[Q dialect.Joinable] struct {
|
||||
Files joinSet[fileJoins[Q]]
|
||||
Items joinSet[itemJoins[Q]]
|
||||
Users joinSet[userJoins[Q]]
|
||||
}
|
||||
|
||||
func buildJoinSet[Q interface{ aliasedAs(string) Q }, C any, F func(C, string) Q](c C, f F) joinSet[Q] {
|
||||
return joinSet[Q]{
|
||||
InnerJoin: f(c, clause.InnerJoin),
|
||||
LeftJoin: f(c, clause.LeftJoin),
|
||||
RightJoin: f(c, clause.RightJoin),
|
||||
}
|
||||
}
|
||||
|
||||
func getJoins[Q dialect.Joinable]() joins[Q] {
|
||||
return joins[Q]{
|
||||
Files: buildJoinSet[fileJoins[Q]](FileColumns, buildFileJoins),
|
||||
Items: buildJoinSet[itemJoins[Q]](ItemColumns, buildItemJoins),
|
||||
Users: buildJoinSet[userJoins[Q]](UserColumns, buildUserJoins),
|
||||
}
|
||||
}
|
||||
|
||||
type modAs[Q any, C interface{ AliasedAs(string) C }] struct {
|
||||
c C
|
||||
f func(C) bob.Mod[Q]
|
||||
}
|
||||
|
||||
func (m modAs[Q, C]) Apply(q Q) {
|
||||
m.f(m.c).Apply(q)
|
||||
}
|
||||
|
||||
func (m modAs[Q, C]) AliasedAs(alias string) bob.Mod[Q] {
|
||||
m.c = m.c.AliasedAs(alias)
|
||||
return m
|
||||
}
|
||||
|
||||
func randInt() int64 {
|
||||
out := int64(new(maphash.Hash).Sum64())
|
||||
|
||||
if out < 0 {
|
||||
return -out % 10000
|
||||
}
|
||||
|
||||
return out % 10000
|
||||
}
|
||||
|
||||
// ErrUniqueConstraint captures all unique constraint errors by explicitly leaving `s` empty.
|
||||
var ErrUniqueConstraint = &UniqueConstraintError{s: ""}
|
||||
|
||||
type UniqueConstraintError struct {
|
||||
// s is a string uniquely identifying the constraint in the raw error message returned from the database.
|
||||
s string
|
||||
}
|
||||
|
||||
func (e *UniqueConstraintError) Error() string {
|
||||
return e.s
|
||||
}
|
||||
|
||||
func (e *UniqueConstraintError) Is(target error) bool {
|
||||
err, ok := target.(*sqliteDriver.Error)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return err.Code() == 2067 && strings.Contains(err.Error(), e.s)
|
||||
}
|
15
server/internal/models/bob_main_test.bob.go
Normal file
15
server/internal/models/bob_main_test.bob.go
Normal file
@ -0,0 +1,15 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package models
|
||||
|
||||
import "github.com/stephenafamo/bob"
|
||||
|
||||
// Make sure the type File runs hooks after queries
|
||||
var _ bob.HookableType = &File{}
|
||||
|
||||
// Make sure the type Item runs hooks after queries
|
||||
var _ bob.HookableType = &Item{}
|
||||
|
||||
// Make sure the type User runs hooks after queries
|
||||
var _ bob.HookableType = &User{}
|
36
server/internal/models/factory/bobfactory_context.bob.go
Normal file
36
server/internal/models/factory/bobfactory_context.bob.go
Normal file
@ -0,0 +1,36 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package factory
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
models "github.com/spotdemo4/trevstack/server/internal/models"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
var (
|
||||
fileCtx = newContextual[*models.File]("file")
|
||||
itemCtx = newContextual[*models.Item]("item")
|
||||
userCtx = newContextual[*models.User]("user")
|
||||
)
|
||||
|
||||
// Contextual is a convienience wrapper around context.WithValue and context.Value
|
||||
type contextual[V any] struct {
|
||||
key contextKey
|
||||
}
|
||||
|
||||
func newContextual[V any](key string) contextual[V] {
|
||||
return contextual[V]{key: contextKey(key)}
|
||||
}
|
||||
|
||||
func (k contextual[V]) WithValue(ctx context.Context, val V) context.Context {
|
||||
return context.WithValue(ctx, k.key, val)
|
||||
}
|
||||
|
||||
func (k contextual[V]) Value(ctx context.Context) (V, bool) {
|
||||
v, ok := ctx.Value(k.key).(V)
|
||||
return v, ok
|
||||
}
|
74
server/internal/models/factory/bobfactory_main.bob.go
Normal file
74
server/internal/models/factory/bobfactory_main.bob.go
Normal file
@ -0,0 +1,74 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package factory
|
||||
|
||||
type Factory struct {
|
||||
baseFileMods FileModSlice
|
||||
baseItemMods ItemModSlice
|
||||
baseUserMods UserModSlice
|
||||
}
|
||||
|
||||
func New() *Factory {
|
||||
return &Factory{}
|
||||
}
|
||||
|
||||
func (f *Factory) NewFile(mods ...FileMod) *FileTemplate {
|
||||
o := &FileTemplate{f: f}
|
||||
|
||||
if f != nil {
|
||||
f.baseFileMods.Apply(o)
|
||||
}
|
||||
|
||||
FileModSlice(mods).Apply(o)
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
func (f *Factory) NewItem(mods ...ItemMod) *ItemTemplate {
|
||||
o := &ItemTemplate{f: f}
|
||||
|
||||
if f != nil {
|
||||
f.baseItemMods.Apply(o)
|
||||
}
|
||||
|
||||
ItemModSlice(mods).Apply(o)
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
func (f *Factory) NewUser(mods ...UserMod) *UserTemplate {
|
||||
o := &UserTemplate{f: f}
|
||||
|
||||
if f != nil {
|
||||
f.baseUserMods.Apply(o)
|
||||
}
|
||||
|
||||
UserModSlice(mods).Apply(o)
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
func (f *Factory) ClearBaseFileMods() {
|
||||
f.baseFileMods = nil
|
||||
}
|
||||
|
||||
func (f *Factory) AddBaseFileMod(mods ...FileMod) {
|
||||
f.baseFileMods = append(f.baseFileMods, mods...)
|
||||
}
|
||||
|
||||
func (f *Factory) ClearBaseItemMods() {
|
||||
f.baseItemMods = nil
|
||||
}
|
||||
|
||||
func (f *Factory) AddBaseItemMod(mods ...ItemMod) {
|
||||
f.baseItemMods = append(f.baseItemMods, mods...)
|
||||
}
|
||||
|
||||
func (f *Factory) ClearBaseUserMods() {
|
||||
f.baseUserMods = nil
|
||||
}
|
||||
|
||||
func (f *Factory) AddBaseUserMod(mods ...UserMod) {
|
||||
f.baseUserMods = append(f.baseUserMods, mods...)
|
||||
}
|
56
server/internal/models/factory/bobfactory_random.bob.go
Normal file
56
server/internal/models/factory/bobfactory_random.bob.go
Normal file
@ -0,0 +1,56 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package factory
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jaswdr/faker/v2"
|
||||
)
|
||||
|
||||
var defaultFaker = faker.New()
|
||||
|
||||
func random___byte(f *faker.Faker) []byte {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
return []byte(random_string(f))
|
||||
}
|
||||
|
||||
func random_float32(f *faker.Faker) float32 {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
return f.Float32(10, -1_000_000, 1_000_000)
|
||||
}
|
||||
|
||||
func random_int32(f *faker.Faker) int32 {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
return f.Int32()
|
||||
}
|
||||
|
||||
func random_string(f *faker.Faker) string {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
return strings.Join(f.Lorem().Words(f.IntBetween(1, 5)), " ")
|
||||
}
|
||||
|
||||
func random_time_Time(f *faker.Faker) time.Time {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
year := time.Hour * 24 * 365
|
||||
min := time.Now().Add(-year)
|
||||
max := time.Now().Add(year)
|
||||
return f.Time().TimeBetween(min, max)
|
||||
}
|
64
server/internal/models/factory/bobfactory_random_test.bob.go
Normal file
64
server/internal/models/factory/bobfactory_random_test.bob.go
Normal file
@ -0,0 +1,64 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package factory
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRandom_int32(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
val1 := random_int32(nil)
|
||||
val2 := random_int32(nil)
|
||||
|
||||
if val1 == val2 {
|
||||
t.Fatalf("random_int32() returned the same value twice: %v", val1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandom_string(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
val1 := random_string(nil)
|
||||
val2 := random_string(nil)
|
||||
|
||||
if val1 == val2 {
|
||||
t.Fatalf("random_string() returned the same value twice: %v", val1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandom___byte(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
val1 := random___byte(nil)
|
||||
val2 := random___byte(nil)
|
||||
|
||||
if bytes.Equal(val1, val2) {
|
||||
t.Fatalf("random___byte() returned the same value twice: %v", val1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandom_float32(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
val1 := random_float32(nil)
|
||||
val2 := random_float32(nil)
|
||||
|
||||
if val1 == val2 {
|
||||
t.Fatalf("random_float32() returned the same value twice: %v", val1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandom_time_Time(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
val1 := random_time_Time(nil)
|
||||
val2 := random_time_Time(nil)
|
||||
|
||||
if val1.Equal(val2) {
|
||||
t.Fatalf("random_time_Time() returned the same value twice: %v", val1)
|
||||
}
|
||||
}
|
466
server/internal/models/factory/files.bob.go
Normal file
466
server/internal/models/factory/files.bob.go
Normal file
@ -0,0 +1,466 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package factory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/aarondl/opt/omitnull"
|
||||
"github.com/jaswdr/faker/v2"
|
||||
models "github.com/spotdemo4/trevstack/server/internal/models"
|
||||
"github.com/stephenafamo/bob"
|
||||
)
|
||||
|
||||
type FileMod interface {
|
||||
Apply(*FileTemplate)
|
||||
}
|
||||
|
||||
type FileModFunc func(*FileTemplate)
|
||||
|
||||
func (f FileModFunc) Apply(n *FileTemplate) {
|
||||
f(n)
|
||||
}
|
||||
|
||||
type FileModSlice []FileMod
|
||||
|
||||
func (mods FileModSlice) Apply(n *FileTemplate) {
|
||||
for _, f := range mods {
|
||||
f.Apply(n)
|
||||
}
|
||||
}
|
||||
|
||||
// FileTemplate is an object representing the database table.
|
||||
// all columns are optional and should be set by mods
|
||||
type FileTemplate struct {
|
||||
ID func() int32
|
||||
Name func() null.Val[string]
|
||||
Data func() null.Val[[]byte]
|
||||
UserID func() null.Val[int32]
|
||||
|
||||
r fileR
|
||||
f *Factory
|
||||
}
|
||||
|
||||
type fileR struct {
|
||||
User *fileRUserR
|
||||
}
|
||||
|
||||
type fileRUserR struct {
|
||||
o *UserTemplate
|
||||
}
|
||||
|
||||
// Apply mods to the FileTemplate
|
||||
func (o *FileTemplate) Apply(mods ...FileMod) {
|
||||
for _, mod := range mods {
|
||||
mod.Apply(o)
|
||||
}
|
||||
}
|
||||
|
||||
// toModel returns an *models.File
|
||||
// this does nothing with the relationship templates
|
||||
func (o FileTemplate) toModel() *models.File {
|
||||
m := &models.File{}
|
||||
|
||||
if o.ID != nil {
|
||||
m.ID = o.ID()
|
||||
}
|
||||
if o.Name != nil {
|
||||
m.Name = o.Name()
|
||||
}
|
||||
if o.Data != nil {
|
||||
m.Data = o.Data()
|
||||
}
|
||||
if o.UserID != nil {
|
||||
m.UserID = o.UserID()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// toModels returns an models.FileSlice
|
||||
// this does nothing with the relationship templates
|
||||
func (o FileTemplate) toModels(number int) models.FileSlice {
|
||||
m := make(models.FileSlice, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.toModel()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// setModelRels creates and sets the relationships on *models.File
|
||||
// according to the relationships in the template. Nothing is inserted into the db
|
||||
func (t FileTemplate) setModelRels(o *models.File) {
|
||||
if t.r.User != nil {
|
||||
rel := t.r.User.o.toModel()
|
||||
rel.R.Files = append(rel.R.Files, o)
|
||||
o.UserID = null.From(rel.ID)
|
||||
o.R.User = rel
|
||||
}
|
||||
}
|
||||
|
||||
// BuildSetter returns an *models.FileSetter
|
||||
// this does nothing with the relationship templates
|
||||
func (o FileTemplate) BuildSetter() *models.FileSetter {
|
||||
m := &models.FileSetter{}
|
||||
|
||||
if o.ID != nil {
|
||||
m.ID = omit.From(o.ID())
|
||||
}
|
||||
if o.Name != nil {
|
||||
m.Name = omitnull.FromNull(o.Name())
|
||||
}
|
||||
if o.Data != nil {
|
||||
m.Data = omitnull.FromNull(o.Data())
|
||||
}
|
||||
if o.UserID != nil {
|
||||
m.UserID = omitnull.FromNull(o.UserID())
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// BuildManySetter returns an []*models.FileSetter
|
||||
// this does nothing with the relationship templates
|
||||
func (o FileTemplate) BuildManySetter(number int) []*models.FileSetter {
|
||||
m := make([]*models.FileSetter, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.BuildSetter()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Build returns an *models.File
|
||||
// Related objects are also created and placed in the .R field
|
||||
// NOTE: Objects are not inserted into the database. Use FileTemplate.Create
|
||||
func (o FileTemplate) Build() *models.File {
|
||||
m := o.toModel()
|
||||
o.setModelRels(m)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// BuildMany returns an models.FileSlice
|
||||
// Related objects are also created and placed in the .R field
|
||||
// NOTE: Objects are not inserted into the database. Use FileTemplate.CreateMany
|
||||
func (o FileTemplate) BuildMany(number int) models.FileSlice {
|
||||
m := make(models.FileSlice, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.Build()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func ensureCreatableFile(m *models.FileSetter) {
|
||||
}
|
||||
|
||||
// insertOptRels creates and inserts any optional the relationships on *models.File
|
||||
// according to the relationships in the template.
|
||||
// any required relationship should have already exist on the model
|
||||
func (o *FileTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.File) (context.Context, error) {
|
||||
var err error
|
||||
|
||||
if o.r.User != nil {
|
||||
var rel0 *models.User
|
||||
ctx, rel0, err = o.r.User.o.create(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
err = m.AttachUser(ctx, exec, rel0)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// Create builds a file and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
func (o *FileTemplate) Create(ctx context.Context, exec bob.Executor) (*models.File, error) {
|
||||
_, m, err := o.create(ctx, exec)
|
||||
return m, err
|
||||
}
|
||||
|
||||
// MustCreate builds a file and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// panics if an error occurs
|
||||
func (o *FileTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.File {
|
||||
_, m, err := o.create(ctx, exec)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// CreateOrFail builds a file and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
|
||||
func (o *FileTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.File {
|
||||
tb.Helper()
|
||||
_, m, err := o.create(ctx, exec)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// create builds a file and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// this returns a context that includes the newly inserted model
|
||||
func (o *FileTemplate) create(ctx context.Context, exec bob.Executor) (context.Context, *models.File, error) {
|
||||
var err error
|
||||
opt := o.BuildSetter()
|
||||
ensureCreatableFile(opt)
|
||||
|
||||
m, err := models.Files.Insert(opt).One(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
ctx = fileCtx.WithValue(ctx, m)
|
||||
|
||||
ctx, err = o.insertOptRels(ctx, exec, m)
|
||||
return ctx, m, err
|
||||
}
|
||||
|
||||
// CreateMany builds multiple files and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
func (o FileTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.FileSlice, error) {
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
return m, err
|
||||
}
|
||||
|
||||
// MustCreateMany builds multiple files and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// panics if an error occurs
|
||||
func (o FileTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.FileSlice {
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// CreateManyOrFail builds multiple files and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
|
||||
func (o FileTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.FileSlice {
|
||||
tb.Helper()
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// createMany builds multiple files and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// this returns a context that includes the newly inserted models
|
||||
func (o FileTemplate) createMany(ctx context.Context, exec bob.Executor, number int) (context.Context, models.FileSlice, error) {
|
||||
var err error
|
||||
m := make(models.FileSlice, number)
|
||||
|
||||
for i := range m {
|
||||
ctx, m[i], err = o.create(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, m, nil
|
||||
}
|
||||
|
||||
// File has methods that act as mods for the FileTemplate
|
||||
var FileMods fileMods
|
||||
|
||||
type fileMods struct{}
|
||||
|
||||
func (m fileMods) RandomizeAllColumns(f *faker.Faker) FileMod {
|
||||
return FileModSlice{
|
||||
FileMods.RandomID(f),
|
||||
FileMods.RandomName(f),
|
||||
FileMods.RandomData(f),
|
||||
FileMods.RandomUserID(f),
|
||||
}
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m fileMods) ID(val int32) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.ID = func() int32 { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m fileMods) IDFunc(f func() int32) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.ID = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m fileMods) UnsetID() FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.ID = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m fileMods) RandomID(f *faker.Faker) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.ID = func() int32 {
|
||||
return random_int32(f)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m fileMods) Name(val null.Val[string]) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Name = func() null.Val[string] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m fileMods) NameFunc(f func() null.Val[string]) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Name = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m fileMods) UnsetName() FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Name = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m fileMods) RandomName(f *faker.Faker) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Name = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[string](nil)
|
||||
}
|
||||
|
||||
return null.From(random_string(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m fileMods) Data(val null.Val[[]byte]) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Data = func() null.Val[[]byte] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m fileMods) DataFunc(f func() null.Val[[]byte]) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Data = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m fileMods) UnsetData() FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Data = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m fileMods) RandomData(f *faker.Faker) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.Data = func() null.Val[[]byte] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[[]byte](nil)
|
||||
}
|
||||
|
||||
return null.From(random___byte(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m fileMods) UserID(val null.Val[int32]) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.UserID = func() null.Val[int32] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m fileMods) UserIDFunc(f func() null.Val[int32]) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.UserID = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m fileMods) UnsetUserID() FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.UserID = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m fileMods) RandomUserID(f *faker.Faker) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.UserID = func() null.Val[int32] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[int32](nil)
|
||||
}
|
||||
|
||||
return null.From(random_int32(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m fileMods) WithUser(rel *UserTemplate) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.r.User = &fileRUserR{
|
||||
o: rel,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m fileMods) WithNewUser(mods ...UserMod) FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
related := o.f.NewUser(mods...)
|
||||
|
||||
m.WithUser(related).Apply(o)
|
||||
})
|
||||
}
|
||||
|
||||
func (m fileMods) WithoutUser() FileMod {
|
||||
return FileModFunc(func(o *FileTemplate) {
|
||||
o.r.User = nil
|
||||
})
|
||||
}
|
608
server/internal/models/factory/items.bob.go
Normal file
608
server/internal/models/factory/items.bob.go
Normal file
@ -0,0 +1,608 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package factory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/aarondl/opt/omitnull"
|
||||
"github.com/jaswdr/faker/v2"
|
||||
models "github.com/spotdemo4/trevstack/server/internal/models"
|
||||
"github.com/stephenafamo/bob"
|
||||
)
|
||||
|
||||
type ItemMod interface {
|
||||
Apply(*ItemTemplate)
|
||||
}
|
||||
|
||||
type ItemModFunc func(*ItemTemplate)
|
||||
|
||||
func (f ItemModFunc) Apply(n *ItemTemplate) {
|
||||
f(n)
|
||||
}
|
||||
|
||||
type ItemModSlice []ItemMod
|
||||
|
||||
func (mods ItemModSlice) Apply(n *ItemTemplate) {
|
||||
for _, f := range mods {
|
||||
f.Apply(n)
|
||||
}
|
||||
}
|
||||
|
||||
// ItemTemplate is an object representing the database table.
|
||||
// all columns are optional and should be set by mods
|
||||
type ItemTemplate struct {
|
||||
ID func() int32
|
||||
Name func() null.Val[string]
|
||||
Description func() null.Val[string]
|
||||
Price func() null.Val[float32]
|
||||
Quantity func() null.Val[int32]
|
||||
Added func() null.Val[time.Time]
|
||||
UserID func() null.Val[int32]
|
||||
|
||||
r itemR
|
||||
f *Factory
|
||||
}
|
||||
|
||||
type itemR struct {
|
||||
User *itemRUserR
|
||||
}
|
||||
|
||||
type itemRUserR struct {
|
||||
o *UserTemplate
|
||||
}
|
||||
|
||||
// Apply mods to the ItemTemplate
|
||||
func (o *ItemTemplate) Apply(mods ...ItemMod) {
|
||||
for _, mod := range mods {
|
||||
mod.Apply(o)
|
||||
}
|
||||
}
|
||||
|
||||
// toModel returns an *models.Item
|
||||
// this does nothing with the relationship templates
|
||||
func (o ItemTemplate) toModel() *models.Item {
|
||||
m := &models.Item{}
|
||||
|
||||
if o.ID != nil {
|
||||
m.ID = o.ID()
|
||||
}
|
||||
if o.Name != nil {
|
||||
m.Name = o.Name()
|
||||
}
|
||||
if o.Description != nil {
|
||||
m.Description = o.Description()
|
||||
}
|
||||
if o.Price != nil {
|
||||
m.Price = o.Price()
|
||||
}
|
||||
if o.Quantity != nil {
|
||||
m.Quantity = o.Quantity()
|
||||
}
|
||||
if o.Added != nil {
|
||||
m.Added = o.Added()
|
||||
}
|
||||
if o.UserID != nil {
|
||||
m.UserID = o.UserID()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// toModels returns an models.ItemSlice
|
||||
// this does nothing with the relationship templates
|
||||
func (o ItemTemplate) toModels(number int) models.ItemSlice {
|
||||
m := make(models.ItemSlice, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.toModel()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// setModelRels creates and sets the relationships on *models.Item
|
||||
// according to the relationships in the template. Nothing is inserted into the db
|
||||
func (t ItemTemplate) setModelRels(o *models.Item) {
|
||||
if t.r.User != nil {
|
||||
rel := t.r.User.o.toModel()
|
||||
rel.R.Items = append(rel.R.Items, o)
|
||||
o.UserID = null.From(rel.ID)
|
||||
o.R.User = rel
|
||||
}
|
||||
}
|
||||
|
||||
// BuildSetter returns an *models.ItemSetter
|
||||
// this does nothing with the relationship templates
|
||||
func (o ItemTemplate) BuildSetter() *models.ItemSetter {
|
||||
m := &models.ItemSetter{}
|
||||
|
||||
if o.ID != nil {
|
||||
m.ID = omit.From(o.ID())
|
||||
}
|
||||
if o.Name != nil {
|
||||
m.Name = omitnull.FromNull(o.Name())
|
||||
}
|
||||
if o.Description != nil {
|
||||
m.Description = omitnull.FromNull(o.Description())
|
||||
}
|
||||
if o.Price != nil {
|
||||
m.Price = omitnull.FromNull(o.Price())
|
||||
}
|
||||
if o.Quantity != nil {
|
||||
m.Quantity = omitnull.FromNull(o.Quantity())
|
||||
}
|
||||
if o.Added != nil {
|
||||
m.Added = omitnull.FromNull(o.Added())
|
||||
}
|
||||
if o.UserID != nil {
|
||||
m.UserID = omitnull.FromNull(o.UserID())
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// BuildManySetter returns an []*models.ItemSetter
|
||||
// this does nothing with the relationship templates
|
||||
func (o ItemTemplate) BuildManySetter(number int) []*models.ItemSetter {
|
||||
m := make([]*models.ItemSetter, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.BuildSetter()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Build returns an *models.Item
|
||||
// Related objects are also created and placed in the .R field
|
||||
// NOTE: Objects are not inserted into the database. Use ItemTemplate.Create
|
||||
func (o ItemTemplate) Build() *models.Item {
|
||||
m := o.toModel()
|
||||
o.setModelRels(m)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// BuildMany returns an models.ItemSlice
|
||||
// Related objects are also created and placed in the .R field
|
||||
// NOTE: Objects are not inserted into the database. Use ItemTemplate.CreateMany
|
||||
func (o ItemTemplate) BuildMany(number int) models.ItemSlice {
|
||||
m := make(models.ItemSlice, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.Build()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func ensureCreatableItem(m *models.ItemSetter) {
|
||||
}
|
||||
|
||||
// insertOptRels creates and inserts any optional the relationships on *models.Item
|
||||
// according to the relationships in the template.
|
||||
// any required relationship should have already exist on the model
|
||||
func (o *ItemTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.Item) (context.Context, error) {
|
||||
var err error
|
||||
|
||||
if o.r.User != nil {
|
||||
var rel0 *models.User
|
||||
ctx, rel0, err = o.r.User.o.create(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
err = m.AttachUser(ctx, exec, rel0)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// Create builds a item and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
func (o *ItemTemplate) Create(ctx context.Context, exec bob.Executor) (*models.Item, error) {
|
||||
_, m, err := o.create(ctx, exec)
|
||||
return m, err
|
||||
}
|
||||
|
||||
// MustCreate builds a item and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// panics if an error occurs
|
||||
func (o *ItemTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.Item {
|
||||
_, m, err := o.create(ctx, exec)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// CreateOrFail builds a item and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
|
||||
func (o *ItemTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.Item {
|
||||
tb.Helper()
|
||||
_, m, err := o.create(ctx, exec)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// create builds a item and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// this returns a context that includes the newly inserted model
|
||||
func (o *ItemTemplate) create(ctx context.Context, exec bob.Executor) (context.Context, *models.Item, error) {
|
||||
var err error
|
||||
opt := o.BuildSetter()
|
||||
ensureCreatableItem(opt)
|
||||
|
||||
m, err := models.Items.Insert(opt).One(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
ctx = itemCtx.WithValue(ctx, m)
|
||||
|
||||
ctx, err = o.insertOptRels(ctx, exec, m)
|
||||
return ctx, m, err
|
||||
}
|
||||
|
||||
// CreateMany builds multiple items and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
func (o ItemTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.ItemSlice, error) {
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
return m, err
|
||||
}
|
||||
|
||||
// MustCreateMany builds multiple items and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// panics if an error occurs
|
||||
func (o ItemTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.ItemSlice {
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// CreateManyOrFail builds multiple items and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
|
||||
func (o ItemTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.ItemSlice {
|
||||
tb.Helper()
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// createMany builds multiple items and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// this returns a context that includes the newly inserted models
|
||||
func (o ItemTemplate) createMany(ctx context.Context, exec bob.Executor, number int) (context.Context, models.ItemSlice, error) {
|
||||
var err error
|
||||
m := make(models.ItemSlice, number)
|
||||
|
||||
for i := range m {
|
||||
ctx, m[i], err = o.create(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, m, nil
|
||||
}
|
||||
|
||||
// Item has methods that act as mods for the ItemTemplate
|
||||
var ItemMods itemMods
|
||||
|
||||
type itemMods struct{}
|
||||
|
||||
func (m itemMods) RandomizeAllColumns(f *faker.Faker) ItemMod {
|
||||
return ItemModSlice{
|
||||
ItemMods.RandomID(f),
|
||||
ItemMods.RandomName(f),
|
||||
ItemMods.RandomDescription(f),
|
||||
ItemMods.RandomPrice(f),
|
||||
ItemMods.RandomQuantity(f),
|
||||
ItemMods.RandomAdded(f),
|
||||
ItemMods.RandomUserID(f),
|
||||
}
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m itemMods) ID(val int32) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.ID = func() int32 { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m itemMods) IDFunc(f func() int32) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.ID = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m itemMods) UnsetID() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.ID = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m itemMods) RandomID(f *faker.Faker) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.ID = func() int32 {
|
||||
return random_int32(f)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m itemMods) Name(val null.Val[string]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Name = func() null.Val[string] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m itemMods) NameFunc(f func() null.Val[string]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Name = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m itemMods) UnsetName() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Name = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m itemMods) RandomName(f *faker.Faker) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Name = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[string](nil)
|
||||
}
|
||||
|
||||
return null.From(random_string(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m itemMods) Description(val null.Val[string]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Description = func() null.Val[string] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m itemMods) DescriptionFunc(f func() null.Val[string]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Description = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m itemMods) UnsetDescription() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Description = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m itemMods) RandomDescription(f *faker.Faker) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Description = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[string](nil)
|
||||
}
|
||||
|
||||
return null.From(random_string(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m itemMods) Price(val null.Val[float32]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Price = func() null.Val[float32] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m itemMods) PriceFunc(f func() null.Val[float32]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Price = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m itemMods) UnsetPrice() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Price = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m itemMods) RandomPrice(f *faker.Faker) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Price = func() null.Val[float32] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[float32](nil)
|
||||
}
|
||||
|
||||
return null.From(random_float32(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m itemMods) Quantity(val null.Val[int32]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Quantity = func() null.Val[int32] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m itemMods) QuantityFunc(f func() null.Val[int32]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Quantity = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m itemMods) UnsetQuantity() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Quantity = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m itemMods) RandomQuantity(f *faker.Faker) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Quantity = func() null.Val[int32] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[int32](nil)
|
||||
}
|
||||
|
||||
return null.From(random_int32(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m itemMods) Added(val null.Val[time.Time]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Added = func() null.Val[time.Time] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m itemMods) AddedFunc(f func() null.Val[time.Time]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Added = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m itemMods) UnsetAdded() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Added = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m itemMods) RandomAdded(f *faker.Faker) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.Added = func() null.Val[time.Time] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[time.Time](nil)
|
||||
}
|
||||
|
||||
return null.From(random_time_Time(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m itemMods) UserID(val null.Val[int32]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.UserID = func() null.Val[int32] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m itemMods) UserIDFunc(f func() null.Val[int32]) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.UserID = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m itemMods) UnsetUserID() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.UserID = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m itemMods) RandomUserID(f *faker.Faker) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.UserID = func() null.Val[int32] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[int32](nil)
|
||||
}
|
||||
|
||||
return null.From(random_int32(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m itemMods) WithUser(rel *UserTemplate) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.r.User = &itemRUserR{
|
||||
o: rel,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m itemMods) WithNewUser(mods ...UserMod) ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
related := o.f.NewUser(mods...)
|
||||
|
||||
m.WithUser(related).Apply(o)
|
||||
})
|
||||
}
|
||||
|
||||
func (m itemMods) WithoutUser() ItemMod {
|
||||
return ItemModFunc(func(o *ItemTemplate) {
|
||||
o.r.User = nil
|
||||
})
|
||||
}
|
610
server/internal/models/factory/users.bob.go
Normal file
610
server/internal/models/factory/users.bob.go
Normal file
@ -0,0 +1,610 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package factory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/aarondl/opt/omitnull"
|
||||
"github.com/jaswdr/faker/v2"
|
||||
models "github.com/spotdemo4/trevstack/server/internal/models"
|
||||
"github.com/stephenafamo/bob"
|
||||
)
|
||||
|
||||
type UserMod interface {
|
||||
Apply(*UserTemplate)
|
||||
}
|
||||
|
||||
type UserModFunc func(*UserTemplate)
|
||||
|
||||
func (f UserModFunc) Apply(n *UserTemplate) {
|
||||
f(n)
|
||||
}
|
||||
|
||||
type UserModSlice []UserMod
|
||||
|
||||
func (mods UserModSlice) Apply(n *UserTemplate) {
|
||||
for _, f := range mods {
|
||||
f.Apply(n)
|
||||
}
|
||||
}
|
||||
|
||||
// UserTemplate is an object representing the database table.
|
||||
// all columns are optional and should be set by mods
|
||||
type UserTemplate struct {
|
||||
ID func() int32
|
||||
Username func() null.Val[string]
|
||||
Password func() null.Val[string]
|
||||
ProfilePictureID func() null.Val[int32]
|
||||
Challenge func() null.Val[string]
|
||||
|
||||
r userR
|
||||
f *Factory
|
||||
}
|
||||
|
||||
type userR struct {
|
||||
Files []*userRFilesR
|
||||
Items []*userRItemsR
|
||||
}
|
||||
|
||||
type userRFilesR struct {
|
||||
number int
|
||||
o *FileTemplate
|
||||
}
|
||||
type userRItemsR struct {
|
||||
number int
|
||||
o *ItemTemplate
|
||||
}
|
||||
|
||||
// Apply mods to the UserTemplate
|
||||
func (o *UserTemplate) Apply(mods ...UserMod) {
|
||||
for _, mod := range mods {
|
||||
mod.Apply(o)
|
||||
}
|
||||
}
|
||||
|
||||
// toModel returns an *models.User
|
||||
// this does nothing with the relationship templates
|
||||
func (o UserTemplate) toModel() *models.User {
|
||||
m := &models.User{}
|
||||
|
||||
if o.ID != nil {
|
||||
m.ID = o.ID()
|
||||
}
|
||||
if o.Username != nil {
|
||||
m.Username = o.Username()
|
||||
}
|
||||
if o.Password != nil {
|
||||
m.Password = o.Password()
|
||||
}
|
||||
if o.ProfilePictureID != nil {
|
||||
m.ProfilePictureID = o.ProfilePictureID()
|
||||
}
|
||||
if o.Challenge != nil {
|
||||
m.Challenge = o.Challenge()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// toModels returns an models.UserSlice
|
||||
// this does nothing with the relationship templates
|
||||
func (o UserTemplate) toModels(number int) models.UserSlice {
|
||||
m := make(models.UserSlice, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.toModel()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// setModelRels creates and sets the relationships on *models.User
|
||||
// according to the relationships in the template. Nothing is inserted into the db
|
||||
func (t UserTemplate) setModelRels(o *models.User) {
|
||||
if t.r.Files != nil {
|
||||
rel := models.FileSlice{}
|
||||
for _, r := range t.r.Files {
|
||||
related := r.o.toModels(r.number)
|
||||
for _, rel := range related {
|
||||
rel.UserID = null.From(o.ID)
|
||||
rel.R.User = o
|
||||
}
|
||||
rel = append(rel, related...)
|
||||
}
|
||||
o.R.Files = rel
|
||||
}
|
||||
|
||||
if t.r.Items != nil {
|
||||
rel := models.ItemSlice{}
|
||||
for _, r := range t.r.Items {
|
||||
related := r.o.toModels(r.number)
|
||||
for _, rel := range related {
|
||||
rel.UserID = null.From(o.ID)
|
||||
rel.R.User = o
|
||||
}
|
||||
rel = append(rel, related...)
|
||||
}
|
||||
o.R.Items = rel
|
||||
}
|
||||
}
|
||||
|
||||
// BuildSetter returns an *models.UserSetter
|
||||
// this does nothing with the relationship templates
|
||||
func (o UserTemplate) BuildSetter() *models.UserSetter {
|
||||
m := &models.UserSetter{}
|
||||
|
||||
if o.ID != nil {
|
||||
m.ID = omit.From(o.ID())
|
||||
}
|
||||
if o.Username != nil {
|
||||
m.Username = omitnull.FromNull(o.Username())
|
||||
}
|
||||
if o.Password != nil {
|
||||
m.Password = omitnull.FromNull(o.Password())
|
||||
}
|
||||
if o.ProfilePictureID != nil {
|
||||
m.ProfilePictureID = omitnull.FromNull(o.ProfilePictureID())
|
||||
}
|
||||
if o.Challenge != nil {
|
||||
m.Challenge = omitnull.FromNull(o.Challenge())
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// BuildManySetter returns an []*models.UserSetter
|
||||
// this does nothing with the relationship templates
|
||||
func (o UserTemplate) BuildManySetter(number int) []*models.UserSetter {
|
||||
m := make([]*models.UserSetter, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.BuildSetter()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Build returns an *models.User
|
||||
// Related objects are also created and placed in the .R field
|
||||
// NOTE: Objects are not inserted into the database. Use UserTemplate.Create
|
||||
func (o UserTemplate) Build() *models.User {
|
||||
m := o.toModel()
|
||||
o.setModelRels(m)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// BuildMany returns an models.UserSlice
|
||||
// Related objects are also created and placed in the .R field
|
||||
// NOTE: Objects are not inserted into the database. Use UserTemplate.CreateMany
|
||||
func (o UserTemplate) BuildMany(number int) models.UserSlice {
|
||||
m := make(models.UserSlice, number)
|
||||
|
||||
for i := range m {
|
||||
m[i] = o.Build()
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func ensureCreatableUser(m *models.UserSetter) {
|
||||
}
|
||||
|
||||
// insertOptRels creates and inserts any optional the relationships on *models.User
|
||||
// according to the relationships in the template.
|
||||
// any required relationship should have already exist on the model
|
||||
func (o *UserTemplate) insertOptRels(ctx context.Context, exec bob.Executor, m *models.User) (context.Context, error) {
|
||||
var err error
|
||||
|
||||
if o.r.Files != nil {
|
||||
for _, r := range o.r.Files {
|
||||
var rel0 models.FileSlice
|
||||
ctx, rel0, err = r.o.createMany(ctx, exec, r.number)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
err = m.AttachFiles(ctx, exec, rel0...)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if o.r.Items != nil {
|
||||
for _, r := range o.r.Items {
|
||||
var rel1 models.ItemSlice
|
||||
ctx, rel1, err = r.o.createMany(ctx, exec, r.number)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
err = m.AttachItems(ctx, exec, rel1...)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
// Create builds a user and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
func (o *UserTemplate) Create(ctx context.Context, exec bob.Executor) (*models.User, error) {
|
||||
_, m, err := o.create(ctx, exec)
|
||||
return m, err
|
||||
}
|
||||
|
||||
// MustCreate builds a user and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// panics if an error occurs
|
||||
func (o *UserTemplate) MustCreate(ctx context.Context, exec bob.Executor) *models.User {
|
||||
_, m, err := o.create(ctx, exec)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// CreateOrFail builds a user and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
|
||||
func (o *UserTemplate) CreateOrFail(ctx context.Context, tb testing.TB, exec bob.Executor) *models.User {
|
||||
tb.Helper()
|
||||
_, m, err := o.create(ctx, exec)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// create builds a user and inserts it into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// this returns a context that includes the newly inserted model
|
||||
func (o *UserTemplate) create(ctx context.Context, exec bob.Executor) (context.Context, *models.User, error) {
|
||||
var err error
|
||||
opt := o.BuildSetter()
|
||||
ensureCreatableUser(opt)
|
||||
|
||||
m, err := models.Users.Insert(opt).One(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
ctx = userCtx.WithValue(ctx, m)
|
||||
|
||||
ctx, err = o.insertOptRels(ctx, exec, m)
|
||||
return ctx, m, err
|
||||
}
|
||||
|
||||
// CreateMany builds multiple users and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
func (o UserTemplate) CreateMany(ctx context.Context, exec bob.Executor, number int) (models.UserSlice, error) {
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
return m, err
|
||||
}
|
||||
|
||||
// MustCreateMany builds multiple users and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// panics if an error occurs
|
||||
func (o UserTemplate) MustCreateMany(ctx context.Context, exec bob.Executor, number int) models.UserSlice {
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// CreateManyOrFail builds multiple users and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// It calls `tb.Fatal(err)` on the test/benchmark if an error occurs
|
||||
func (o UserTemplate) CreateManyOrFail(ctx context.Context, tb testing.TB, exec bob.Executor, number int) models.UserSlice {
|
||||
tb.Helper()
|
||||
_, m, err := o.createMany(ctx, exec, number)
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// createMany builds multiple users and inserts them into the database
|
||||
// Relations objects are also inserted and placed in the .R field
|
||||
// this returns a context that includes the newly inserted models
|
||||
func (o UserTemplate) createMany(ctx context.Context, exec bob.Executor, number int) (context.Context, models.UserSlice, error) {
|
||||
var err error
|
||||
m := make(models.UserSlice, number)
|
||||
|
||||
for i := range m {
|
||||
ctx, m[i], err = o.create(ctx, exec)
|
||||
if err != nil {
|
||||
return ctx, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return ctx, m, nil
|
||||
}
|
||||
|
||||
// User has methods that act as mods for the UserTemplate
|
||||
var UserMods userMods
|
||||
|
||||
type userMods struct{}
|
||||
|
||||
func (m userMods) RandomizeAllColumns(f *faker.Faker) UserMod {
|
||||
return UserModSlice{
|
||||
UserMods.RandomID(f),
|
||||
UserMods.RandomUsername(f),
|
||||
UserMods.RandomPassword(f),
|
||||
UserMods.RandomProfilePictureID(f),
|
||||
UserMods.RandomChallenge(f),
|
||||
}
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m userMods) ID(val int32) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ID = func() int32 { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m userMods) IDFunc(f func() int32) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ID = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m userMods) UnsetID() UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ID = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m userMods) RandomID(f *faker.Faker) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ID = func() int32 {
|
||||
return random_int32(f)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m userMods) Username(val null.Val[string]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Username = func() null.Val[string] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m userMods) UsernameFunc(f func() null.Val[string]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Username = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m userMods) UnsetUsername() UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Username = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m userMods) RandomUsername(f *faker.Faker) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Username = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[string](nil)
|
||||
}
|
||||
|
||||
return null.From(random_string(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m userMods) Password(val null.Val[string]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Password = func() null.Val[string] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m userMods) PasswordFunc(f func() null.Val[string]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Password = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m userMods) UnsetPassword() UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Password = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m userMods) RandomPassword(f *faker.Faker) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Password = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[string](nil)
|
||||
}
|
||||
|
||||
return null.From(random_string(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m userMods) ProfilePictureID(val null.Val[int32]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ProfilePictureID = func() null.Val[int32] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m userMods) ProfilePictureIDFunc(f func() null.Val[int32]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ProfilePictureID = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m userMods) UnsetProfilePictureID() UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ProfilePictureID = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m userMods) RandomProfilePictureID(f *faker.Faker) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.ProfilePictureID = func() null.Val[int32] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[int32](nil)
|
||||
}
|
||||
|
||||
return null.From(random_int32(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m userMods) Challenge(val null.Val[string]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Challenge = func() null.Val[string] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m userMods) ChallengeFunc(f func() null.Val[string]) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Challenge = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m userMods) UnsetChallenge() UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Challenge = nil
|
||||
})
|
||||
}
|
||||
|
||||
// Generates a random value for the column using the given faker
|
||||
// if faker is nil, a default faker is used
|
||||
func (m userMods) RandomChallenge(f *faker.Faker) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.Challenge = func() null.Val[string] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
if f.Bool() {
|
||||
return null.FromPtr[string](nil)
|
||||
}
|
||||
|
||||
return null.From(random_string(f))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) WithFiles(number int, related *FileTemplate) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.r.Files = []*userRFilesR{{
|
||||
number: number,
|
||||
o: related,
|
||||
}}
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) WithNewFiles(number int, mods ...FileMod) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
related := o.f.NewFile(mods...)
|
||||
m.WithFiles(number, related).Apply(o)
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) AddFiles(number int, related *FileTemplate) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.r.Files = append(o.r.Files, &userRFilesR{
|
||||
number: number,
|
||||
o: related,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) AddNewFiles(number int, mods ...FileMod) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
related := o.f.NewFile(mods...)
|
||||
m.AddFiles(number, related).Apply(o)
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) WithoutFiles() UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.r.Files = nil
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) WithItems(number int, related *ItemTemplate) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.r.Items = []*userRItemsR{{
|
||||
number: number,
|
||||
o: related,
|
||||
}}
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) WithNewItems(number int, mods ...ItemMod) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
related := o.f.NewItem(mods...)
|
||||
m.WithItems(number, related).Apply(o)
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) AddItems(number int, related *ItemTemplate) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.r.Items = append(o.r.Items, &userRItemsR{
|
||||
number: number,
|
||||
o: related,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) AddNewItems(number int, mods ...ItemMod) UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
related := o.f.NewItem(mods...)
|
||||
m.AddItems(number, related).Apply(o)
|
||||
})
|
||||
}
|
||||
|
||||
func (m userMods) WithoutItems() UserMod {
|
||||
return UserModFunc(func(o *UserTemplate) {
|
||||
o.r.Items = nil
|
||||
})
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package models
|
||||
|
||||
type File struct {
|
||||
ID uint32 `gorm:"primaryKey"`
|
||||
|
||||
Name string
|
||||
Data []byte
|
||||
|
||||
// User
|
||||
UserID uint
|
||||
User User
|
||||
}
|
658
server/internal/models/files.bob.go
Normal file
658
server/internal/models/files.bob.go
Normal file
@ -0,0 +1,658 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/aarondl/opt/omitnull"
|
||||
"github.com/stephenafamo/bob"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/dialect"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/dm"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/sm"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/um"
|
||||
"github.com/stephenafamo/bob/expr"
|
||||
"github.com/stephenafamo/bob/mods"
|
||||
"github.com/stephenafamo/bob/orm"
|
||||
)
|
||||
|
||||
// File is an object representing the database table.
|
||||
type File struct {
|
||||
ID int32 `db:"id,pk" `
|
||||
Name null.Val[string] `db:"name" `
|
||||
Data null.Val[[]byte] `db:"data" `
|
||||
UserID null.Val[int32] `db:"user_id" `
|
||||
|
||||
R fileR `db:"-" `
|
||||
}
|
||||
|
||||
// FileSlice is an alias for a slice of pointers to File.
|
||||
// This should almost always be used instead of []*File.
|
||||
type FileSlice []*File
|
||||
|
||||
// Files contains methods to work with the files table
|
||||
var Files = sqlite.NewTablex[*File, FileSlice, *FileSetter]("", "files")
|
||||
|
||||
// FilesQuery is a query on the files table
|
||||
type FilesQuery = *sqlite.ViewQuery[*File, FileSlice]
|
||||
|
||||
// fileR is where relationships are stored.
|
||||
type fileR struct {
|
||||
User *User // fk_files_0
|
||||
}
|
||||
|
||||
type fileColumnNames struct {
|
||||
ID string
|
||||
Name string
|
||||
Data string
|
||||
UserID string
|
||||
}
|
||||
|
||||
var FileColumns = buildFileColumns("files")
|
||||
|
||||
type fileColumns struct {
|
||||
tableAlias string
|
||||
ID sqlite.Expression
|
||||
Name sqlite.Expression
|
||||
Data sqlite.Expression
|
||||
UserID sqlite.Expression
|
||||
}
|
||||
|
||||
func (c fileColumns) Alias() string {
|
||||
return c.tableAlias
|
||||
}
|
||||
|
||||
func (fileColumns) AliasedAs(alias string) fileColumns {
|
||||
return buildFileColumns(alias)
|
||||
}
|
||||
|
||||
func buildFileColumns(alias string) fileColumns {
|
||||
return fileColumns{
|
||||
tableAlias: alias,
|
||||
ID: sqlite.Quote(alias, "id"),
|
||||
Name: sqlite.Quote(alias, "name"),
|
||||
Data: sqlite.Quote(alias, "data"),
|
||||
UserID: sqlite.Quote(alias, "user_id"),
|
||||
}
|
||||
}
|
||||
|
||||
type fileWhere[Q sqlite.Filterable] struct {
|
||||
ID sqlite.WhereMod[Q, int32]
|
||||
Name sqlite.WhereNullMod[Q, string]
|
||||
Data sqlite.WhereNullMod[Q, []byte]
|
||||
UserID sqlite.WhereNullMod[Q, int32]
|
||||
}
|
||||
|
||||
func (fileWhere[Q]) AliasedAs(alias string) fileWhere[Q] {
|
||||
return buildFileWhere[Q](buildFileColumns(alias))
|
||||
}
|
||||
|
||||
func buildFileWhere[Q sqlite.Filterable](cols fileColumns) fileWhere[Q] {
|
||||
return fileWhere[Q]{
|
||||
ID: sqlite.Where[Q, int32](cols.ID),
|
||||
Name: sqlite.WhereNull[Q, string](cols.Name),
|
||||
Data: sqlite.WhereNull[Q, []byte](cols.Data),
|
||||
UserID: sqlite.WhereNull[Q, int32](cols.UserID),
|
||||
}
|
||||
}
|
||||
|
||||
var FileErrors = &fileErrors{
|
||||
ErrUniquePkMainFiles: &UniqueConstraintError{s: "pk_main_files"},
|
||||
}
|
||||
|
||||
type fileErrors struct {
|
||||
ErrUniquePkMainFiles *UniqueConstraintError
|
||||
}
|
||||
|
||||
// FileSetter is used for insert/upsert/update operations
|
||||
// All values are optional, and do not have to be set
|
||||
// Generated columns are not included
|
||||
type FileSetter struct {
|
||||
ID omit.Val[int32] `db:"id,pk" `
|
||||
Name omitnull.Val[string] `db:"name" `
|
||||
Data omitnull.Val[[]byte] `db:"data" `
|
||||
UserID omitnull.Val[int32] `db:"user_id" `
|
||||
}
|
||||
|
||||
func (s FileSetter) SetColumns() []string {
|
||||
vals := make([]string, 0, 4)
|
||||
if !s.ID.IsUnset() {
|
||||
vals = append(vals, "id")
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
vals = append(vals, "name")
|
||||
}
|
||||
|
||||
if !s.Data.IsUnset() {
|
||||
vals = append(vals, "data")
|
||||
}
|
||||
|
||||
if !s.UserID.IsUnset() {
|
||||
vals = append(vals, "user_id")
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
func (s FileSetter) Overwrite(t *File) {
|
||||
if !s.ID.IsUnset() {
|
||||
t.ID, _ = s.ID.Get()
|
||||
}
|
||||
if !s.Name.IsUnset() {
|
||||
t.Name, _ = s.Name.GetNull()
|
||||
}
|
||||
if !s.Data.IsUnset() {
|
||||
t.Data, _ = s.Data.GetNull()
|
||||
}
|
||||
if !s.UserID.IsUnset() {
|
||||
t.UserID, _ = s.UserID.GetNull()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileSetter) Apply(q *dialect.InsertQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Files.BeforeInsertHooks.RunHooks(ctx, exec, s)
|
||||
})
|
||||
|
||||
if len(q.Table.Columns) == 0 {
|
||||
q.Table.Columns = s.SetColumns()
|
||||
}
|
||||
|
||||
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
vals := make([]bob.Expression, 0, 4)
|
||||
if !s.ID.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.ID))
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Name))
|
||||
}
|
||||
|
||||
if !s.Data.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Data))
|
||||
}
|
||||
|
||||
if !s.UserID.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.UserID))
|
||||
}
|
||||
|
||||
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
|
||||
}))
|
||||
}
|
||||
|
||||
func (s FileSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
|
||||
return um.Set(s.Expressions()...)
|
||||
}
|
||||
|
||||
func (s FileSetter) Expressions(prefix ...string) []bob.Expression {
|
||||
exprs := make([]bob.Expression, 0, 4)
|
||||
|
||||
if !s.ID.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "id")...),
|
||||
sqlite.Arg(s.ID),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "name")...),
|
||||
sqlite.Arg(s.Name),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Data.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "data")...),
|
||||
sqlite.Arg(s.Data),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.UserID.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "user_id")...),
|
||||
sqlite.Arg(s.UserID),
|
||||
}})
|
||||
}
|
||||
|
||||
return exprs
|
||||
}
|
||||
|
||||
// FindFile retrieves a single record by primary key
|
||||
// If cols is empty Find will return all columns.
|
||||
func FindFile(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*File, error) {
|
||||
if len(cols) == 0 {
|
||||
return Files.Query(
|
||||
SelectWhere.Files.ID.EQ(IDPK),
|
||||
).One(ctx, exec)
|
||||
}
|
||||
|
||||
return Files.Query(
|
||||
SelectWhere.Files.ID.EQ(IDPK),
|
||||
sm.Columns(Files.Columns().Only(cols...)),
|
||||
).One(ctx, exec)
|
||||
}
|
||||
|
||||
// FileExists checks the presence of a single record by primary key
|
||||
func FileExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) {
|
||||
return Files.Query(
|
||||
SelectWhere.Files.ID.EQ(IDPK),
|
||||
).Exists(ctx, exec)
|
||||
}
|
||||
|
||||
// AfterQueryHook is called after File is retrieved from the database
|
||||
func (o *File) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
|
||||
var err error
|
||||
|
||||
switch queryType {
|
||||
case bob.QueryTypeSelect:
|
||||
ctx, err = Files.AfterSelectHooks.RunHooks(ctx, exec, FileSlice{o})
|
||||
case bob.QueryTypeInsert:
|
||||
ctx, err = Files.AfterInsertHooks.RunHooks(ctx, exec, FileSlice{o})
|
||||
case bob.QueryTypeUpdate:
|
||||
ctx, err = Files.AfterUpdateHooks.RunHooks(ctx, exec, FileSlice{o})
|
||||
case bob.QueryTypeDelete:
|
||||
ctx, err = Files.AfterDeleteHooks.RunHooks(ctx, exec, FileSlice{o})
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// PrimaryKeyVals returns the primary key values of the File
|
||||
func (o *File) PrimaryKeyVals() bob.Expression {
|
||||
return sqlite.Arg(o.ID)
|
||||
}
|
||||
|
||||
func (o *File) pkEQ() dialect.Expression {
|
||||
return sqlite.Quote("files", "id").EQ(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
return o.PrimaryKeyVals().WriteSQL(ctx, w, d, start)
|
||||
}))
|
||||
}
|
||||
|
||||
// Update uses an executor to update the File
|
||||
func (o *File) Update(ctx context.Context, exec bob.Executor, s *FileSetter) error {
|
||||
v, err := Files.Update(s.UpdateMod(), um.Where(o.pkEQ())).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.R = v.R
|
||||
*o = *v
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes a single File record with an executor
|
||||
func (o *File) Delete(ctx context.Context, exec bob.Executor) error {
|
||||
_, err := Files.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
// Reload refreshes the File using the executor
|
||||
func (o *File) Reload(ctx context.Context, exec bob.Executor) error {
|
||||
o2, err := Files.Query(
|
||||
SelectWhere.Files.ID.EQ(o.ID),
|
||||
).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o2.R = o.R
|
||||
*o = *o2
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AfterQueryHook is called after FileSlice is retrieved from the database
|
||||
func (o FileSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
|
||||
var err error
|
||||
|
||||
switch queryType {
|
||||
case bob.QueryTypeSelect:
|
||||
ctx, err = Files.AfterSelectHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeInsert:
|
||||
ctx, err = Files.AfterInsertHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeUpdate:
|
||||
ctx, err = Files.AfterUpdateHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeDelete:
|
||||
ctx, err = Files.AfterDeleteHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (o FileSlice) pkIN() dialect.Expression {
|
||||
if len(o) == 0 {
|
||||
return sqlite.Raw("NULL")
|
||||
}
|
||||
|
||||
return sqlite.Quote("files", "id").In(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
pkPairs := make([]bob.Expression, len(o))
|
||||
for i, row := range o {
|
||||
pkPairs[i] = row.PrimaryKeyVals()
|
||||
}
|
||||
return bob.ExpressSlice(ctx, w, d, start, pkPairs, "", ", ", "")
|
||||
}))
|
||||
}
|
||||
|
||||
// copyMatchingRows finds models in the given slice that have the same primary key
|
||||
// then it first copies the existing relationships from the old model to the new model
|
||||
// and then replaces the old model in the slice with the new model
|
||||
func (o FileSlice) copyMatchingRows(from ...*File) {
|
||||
for i, old := range o {
|
||||
for _, new := range from {
|
||||
if new.ID != old.ID {
|
||||
continue
|
||||
}
|
||||
new.R = old.R
|
||||
o[i] = new
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateMod modifies an update query with "WHERE primary_key IN (o...)"
|
||||
func (o FileSlice) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
|
||||
return bob.ModFunc[*dialect.UpdateQuery](func(q *dialect.UpdateQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Files.BeforeUpdateHooks.RunHooks(ctx, exec, o)
|
||||
})
|
||||
|
||||
q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
var err error
|
||||
switch retrieved := retrieved.(type) {
|
||||
case *File:
|
||||
o.copyMatchingRows(retrieved)
|
||||
case []*File:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
case FileSlice:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
default:
|
||||
// If the retrieved value is not a File or a slice of File
|
||||
// then run the AfterUpdateHooks on the slice
|
||||
_, err = Files.AfterUpdateHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}))
|
||||
|
||||
q.AppendWhere(o.pkIN())
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
|
||||
func (o FileSlice) DeleteMod() bob.Mod[*dialect.DeleteQuery] {
|
||||
return bob.ModFunc[*dialect.DeleteQuery](func(q *dialect.DeleteQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Files.BeforeDeleteHooks.RunHooks(ctx, exec, o)
|
||||
})
|
||||
|
||||
q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
var err error
|
||||
switch retrieved := retrieved.(type) {
|
||||
case *File:
|
||||
o.copyMatchingRows(retrieved)
|
||||
case []*File:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
case FileSlice:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
default:
|
||||
// If the retrieved value is not a File or a slice of File
|
||||
// then run the AfterDeleteHooks on the slice
|
||||
_, err = Files.AfterDeleteHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}))
|
||||
|
||||
q.AppendWhere(o.pkIN())
|
||||
})
|
||||
}
|
||||
|
||||
func (o FileSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals FileSetter) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := Files.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
func (o FileSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := Files.Delete(o.DeleteMod()).Exec(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
func (o FileSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
o2, err := Files.Query(sm.Where(o.pkIN())).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.copyMatchingRows(o2...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type fileJoins[Q dialect.Joinable] struct {
|
||||
typ string
|
||||
User func(context.Context) modAs[Q, userColumns]
|
||||
}
|
||||
|
||||
func (j fileJoins[Q]) aliasedAs(alias string) fileJoins[Q] {
|
||||
return buildFileJoins[Q](buildFileColumns(alias), j.typ)
|
||||
}
|
||||
|
||||
func buildFileJoins[Q dialect.Joinable](cols fileColumns, typ string) fileJoins[Q] {
|
||||
return fileJoins[Q]{
|
||||
typ: typ,
|
||||
User: filesJoinUser[Q](cols, typ),
|
||||
}
|
||||
}
|
||||
|
||||
func filesJoinUser[Q dialect.Joinable](from fileColumns, typ string) func(context.Context) modAs[Q, userColumns] {
|
||||
return func(ctx context.Context) modAs[Q, userColumns] {
|
||||
return modAs[Q, userColumns]{
|
||||
c: UserColumns,
|
||||
f: func(to userColumns) bob.Mod[Q] {
|
||||
mods := make(mods.QueryMods[Q], 0, 1)
|
||||
|
||||
{
|
||||
mods = append(mods, dialect.Join[Q](typ, Users.Name().As(to.Alias())).On(
|
||||
to.ID.EQ(from.UserID),
|
||||
))
|
||||
}
|
||||
|
||||
return mods
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User starts a query for related objects on users
|
||||
func (o *File) User(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery {
|
||||
return Users.Query(append(mods,
|
||||
sm.Where(UserColumns.ID.EQ(sqlite.Arg(o.UserID))),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (os FileSlice) User(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery {
|
||||
PKArgs := make([]bob.Expression, len(os))
|
||||
for i, o := range os {
|
||||
PKArgs[i] = sqlite.ArgGroup(o.UserID)
|
||||
}
|
||||
|
||||
return Users.Query(append(mods,
|
||||
sm.Where(sqlite.Group(UserColumns.ID).In(PKArgs...)),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (o *File) Preload(name string, retrieved any) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "User":
|
||||
rel, ok := retrieved.(*User)
|
||||
if !ok {
|
||||
return fmt.Errorf("file cannot load %T as %q", retrieved, name)
|
||||
}
|
||||
|
||||
o.R.User = rel
|
||||
|
||||
if rel != nil {
|
||||
rel.R.Files = FileSlice{o}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("file has no relationship %q", name)
|
||||
}
|
||||
}
|
||||
|
||||
func PreloadFileUser(opts ...sqlite.PreloadOption) sqlite.Preloader {
|
||||
return sqlite.Preload[*User, UserSlice](orm.Relationship{
|
||||
Name: "User",
|
||||
Sides: []orm.RelSide{
|
||||
{
|
||||
From: TableNames.Files,
|
||||
To: TableNames.Users,
|
||||
FromColumns: []string{
|
||||
ColumnNames.Files.UserID,
|
||||
},
|
||||
ToColumns: []string{
|
||||
ColumnNames.Users.ID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, Users.Columns().Names(), opts...)
|
||||
}
|
||||
|
||||
func ThenLoadFileUser(queryMods ...bob.Mod[*dialect.SelectQuery]) sqlite.Loader {
|
||||
return sqlite.Loader(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
loader, isLoader := retrieved.(interface {
|
||||
LoadFileUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
|
||||
})
|
||||
if !isLoader {
|
||||
return fmt.Errorf("object %T cannot load FileUser", retrieved)
|
||||
}
|
||||
|
||||
err := loader.LoadFileUser(ctx, exec, queryMods...)
|
||||
|
||||
// Don't cause an issue due to missing relationships
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// LoadFileUser loads the file's User into the .R struct
|
||||
func (o *File) LoadFileUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reset the relationship
|
||||
o.R.User = nil
|
||||
|
||||
related, err := o.User(mods...).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
related.R.Files = FileSlice{o}
|
||||
|
||||
o.R.User = related
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadFileUser loads the file's User into the .R struct
|
||||
func (os FileSlice) LoadFileUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if len(os) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
users, err := os.User(mods...).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
for _, rel := range users {
|
||||
if o.UserID.GetOrZero() != rel.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
rel.R.Files = append(rel.R.Files, o)
|
||||
|
||||
o.R.User = rel
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func attachFileUser0(ctx context.Context, exec bob.Executor, count int, file0 *File, user1 *User) (*File, error) {
|
||||
setter := &FileSetter{
|
||||
UserID: omitnull.From(user1.ID),
|
||||
}
|
||||
|
||||
err := file0.Update(ctx, exec, setter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("attachFileUser0: %w", err)
|
||||
}
|
||||
|
||||
return file0, nil
|
||||
}
|
||||
|
||||
func (file0 *File) InsertUser(ctx context.Context, exec bob.Executor, related *UserSetter) error {
|
||||
user1, err := Users.Insert(related).One(ctx, exec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("inserting related objects: %w", err)
|
||||
}
|
||||
|
||||
_, err = attachFileUser0(ctx, exec, 1, file0, user1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file0.R.User = user1
|
||||
|
||||
user1.R.Files = append(user1.R.Files, file0)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (file0 *File) AttachUser(ctx context.Context, exec bob.Executor, user1 *User) error {
|
||||
var err error
|
||||
|
||||
_, err = attachFileUser0(ctx, exec, 1, file0, user1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file0.R.User = user1
|
||||
|
||||
user1.R.Files = append(user1.R.Files, file0)
|
||||
|
||||
return nil
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
itemv1 "github.com/spotdemo4/trevstack/server/internal/services/item/v1"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
type Item struct {
|
||||
ID uint32 `gorm:"primaryKey"`
|
||||
|
||||
Name string
|
||||
Description string
|
||||
Price float32
|
||||
Quantity int
|
||||
Added time.Time
|
||||
|
||||
// User
|
||||
UserID uint
|
||||
User User
|
||||
}
|
||||
|
||||
func (i Item) ToConnectV1() *itemv1.Item {
|
||||
return &itemv1.Item{
|
||||
Id: &i.ID,
|
||||
Name: i.Name,
|
||||
Description: i.Description,
|
||||
Price: i.Price,
|
||||
Quantity: uint32(i.Quantity),
|
||||
Added: timestamppb.New(i.Added),
|
||||
}
|
||||
}
|
734
server/internal/models/items.bob.go
Normal file
734
server/internal/models/items.bob.go
Normal file
@ -0,0 +1,734 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/aarondl/opt/omitnull"
|
||||
"github.com/stephenafamo/bob"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/dialect"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/dm"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/sm"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/um"
|
||||
"github.com/stephenafamo/bob/expr"
|
||||
"github.com/stephenafamo/bob/mods"
|
||||
"github.com/stephenafamo/bob/orm"
|
||||
)
|
||||
|
||||
// Item is an object representing the database table.
|
||||
type Item struct {
|
||||
ID int32 `db:"id,pk" `
|
||||
Name null.Val[string] `db:"name" `
|
||||
Description null.Val[string] `db:"description" `
|
||||
Price null.Val[float32] `db:"price" `
|
||||
Quantity null.Val[int32] `db:"quantity" `
|
||||
Added null.Val[time.Time] `db:"added" `
|
||||
UserID null.Val[int32] `db:"user_id" `
|
||||
|
||||
R itemR `db:"-" `
|
||||
}
|
||||
|
||||
// ItemSlice is an alias for a slice of pointers to Item.
|
||||
// This should almost always be used instead of []*Item.
|
||||
type ItemSlice []*Item
|
||||
|
||||
// Items contains methods to work with the items table
|
||||
var Items = sqlite.NewTablex[*Item, ItemSlice, *ItemSetter]("", "items")
|
||||
|
||||
// ItemsQuery is a query on the items table
|
||||
type ItemsQuery = *sqlite.ViewQuery[*Item, ItemSlice]
|
||||
|
||||
// itemR is where relationships are stored.
|
||||
type itemR struct {
|
||||
User *User // fk_items_0
|
||||
}
|
||||
|
||||
type itemColumnNames struct {
|
||||
ID string
|
||||
Name string
|
||||
Description string
|
||||
Price string
|
||||
Quantity string
|
||||
Added string
|
||||
UserID string
|
||||
}
|
||||
|
||||
var ItemColumns = buildItemColumns("items")
|
||||
|
||||
type itemColumns struct {
|
||||
tableAlias string
|
||||
ID sqlite.Expression
|
||||
Name sqlite.Expression
|
||||
Description sqlite.Expression
|
||||
Price sqlite.Expression
|
||||
Quantity sqlite.Expression
|
||||
Added sqlite.Expression
|
||||
UserID sqlite.Expression
|
||||
}
|
||||
|
||||
func (c itemColumns) Alias() string {
|
||||
return c.tableAlias
|
||||
}
|
||||
|
||||
func (itemColumns) AliasedAs(alias string) itemColumns {
|
||||
return buildItemColumns(alias)
|
||||
}
|
||||
|
||||
func buildItemColumns(alias string) itemColumns {
|
||||
return itemColumns{
|
||||
tableAlias: alias,
|
||||
ID: sqlite.Quote(alias, "id"),
|
||||
Name: sqlite.Quote(alias, "name"),
|
||||
Description: sqlite.Quote(alias, "description"),
|
||||
Price: sqlite.Quote(alias, "price"),
|
||||
Quantity: sqlite.Quote(alias, "quantity"),
|
||||
Added: sqlite.Quote(alias, "added"),
|
||||
UserID: sqlite.Quote(alias, "user_id"),
|
||||
}
|
||||
}
|
||||
|
||||
type itemWhere[Q sqlite.Filterable] struct {
|
||||
ID sqlite.WhereMod[Q, int32]
|
||||
Name sqlite.WhereNullMod[Q, string]
|
||||
Description sqlite.WhereNullMod[Q, string]
|
||||
Price sqlite.WhereNullMod[Q, float32]
|
||||
Quantity sqlite.WhereNullMod[Q, int32]
|
||||
Added sqlite.WhereNullMod[Q, time.Time]
|
||||
UserID sqlite.WhereNullMod[Q, int32]
|
||||
}
|
||||
|
||||
func (itemWhere[Q]) AliasedAs(alias string) itemWhere[Q] {
|
||||
return buildItemWhere[Q](buildItemColumns(alias))
|
||||
}
|
||||
|
||||
func buildItemWhere[Q sqlite.Filterable](cols itemColumns) itemWhere[Q] {
|
||||
return itemWhere[Q]{
|
||||
ID: sqlite.Where[Q, int32](cols.ID),
|
||||
Name: sqlite.WhereNull[Q, string](cols.Name),
|
||||
Description: sqlite.WhereNull[Q, string](cols.Description),
|
||||
Price: sqlite.WhereNull[Q, float32](cols.Price),
|
||||
Quantity: sqlite.WhereNull[Q, int32](cols.Quantity),
|
||||
Added: sqlite.WhereNull[Q, time.Time](cols.Added),
|
||||
UserID: sqlite.WhereNull[Q, int32](cols.UserID),
|
||||
}
|
||||
}
|
||||
|
||||
var ItemErrors = &itemErrors{
|
||||
ErrUniquePkMainItems: &UniqueConstraintError{s: "pk_main_items"},
|
||||
}
|
||||
|
||||
type itemErrors struct {
|
||||
ErrUniquePkMainItems *UniqueConstraintError
|
||||
}
|
||||
|
||||
// ItemSetter is used for insert/upsert/update operations
|
||||
// All values are optional, and do not have to be set
|
||||
// Generated columns are not included
|
||||
type ItemSetter struct {
|
||||
ID omit.Val[int32] `db:"id,pk" `
|
||||
Name omitnull.Val[string] `db:"name" `
|
||||
Description omitnull.Val[string] `db:"description" `
|
||||
Price omitnull.Val[float32] `db:"price" `
|
||||
Quantity omitnull.Val[int32] `db:"quantity" `
|
||||
Added omitnull.Val[time.Time] `db:"added" `
|
||||
UserID omitnull.Val[int32] `db:"user_id" `
|
||||
}
|
||||
|
||||
func (s ItemSetter) SetColumns() []string {
|
||||
vals := make([]string, 0, 7)
|
||||
if !s.ID.IsUnset() {
|
||||
vals = append(vals, "id")
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
vals = append(vals, "name")
|
||||
}
|
||||
|
||||
if !s.Description.IsUnset() {
|
||||
vals = append(vals, "description")
|
||||
}
|
||||
|
||||
if !s.Price.IsUnset() {
|
||||
vals = append(vals, "price")
|
||||
}
|
||||
|
||||
if !s.Quantity.IsUnset() {
|
||||
vals = append(vals, "quantity")
|
||||
}
|
||||
|
||||
if !s.Added.IsUnset() {
|
||||
vals = append(vals, "added")
|
||||
}
|
||||
|
||||
if !s.UserID.IsUnset() {
|
||||
vals = append(vals, "user_id")
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
func (s ItemSetter) Overwrite(t *Item) {
|
||||
if !s.ID.IsUnset() {
|
||||
t.ID, _ = s.ID.Get()
|
||||
}
|
||||
if !s.Name.IsUnset() {
|
||||
t.Name, _ = s.Name.GetNull()
|
||||
}
|
||||
if !s.Description.IsUnset() {
|
||||
t.Description, _ = s.Description.GetNull()
|
||||
}
|
||||
if !s.Price.IsUnset() {
|
||||
t.Price, _ = s.Price.GetNull()
|
||||
}
|
||||
if !s.Quantity.IsUnset() {
|
||||
t.Quantity, _ = s.Quantity.GetNull()
|
||||
}
|
||||
if !s.Added.IsUnset() {
|
||||
t.Added, _ = s.Added.GetNull()
|
||||
}
|
||||
if !s.UserID.IsUnset() {
|
||||
t.UserID, _ = s.UserID.GetNull()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ItemSetter) Apply(q *dialect.InsertQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Items.BeforeInsertHooks.RunHooks(ctx, exec, s)
|
||||
})
|
||||
|
||||
if len(q.Table.Columns) == 0 {
|
||||
q.Table.Columns = s.SetColumns()
|
||||
}
|
||||
|
||||
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
vals := make([]bob.Expression, 0, 7)
|
||||
if !s.ID.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.ID))
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Name))
|
||||
}
|
||||
|
||||
if !s.Description.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Description))
|
||||
}
|
||||
|
||||
if !s.Price.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Price))
|
||||
}
|
||||
|
||||
if !s.Quantity.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Quantity))
|
||||
}
|
||||
|
||||
if !s.Added.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Added))
|
||||
}
|
||||
|
||||
if !s.UserID.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.UserID))
|
||||
}
|
||||
|
||||
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
|
||||
}))
|
||||
}
|
||||
|
||||
func (s ItemSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
|
||||
return um.Set(s.Expressions()...)
|
||||
}
|
||||
|
||||
func (s ItemSetter) Expressions(prefix ...string) []bob.Expression {
|
||||
exprs := make([]bob.Expression, 0, 7)
|
||||
|
||||
if !s.ID.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "id")...),
|
||||
sqlite.Arg(s.ID),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Name.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "name")...),
|
||||
sqlite.Arg(s.Name),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Description.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "description")...),
|
||||
sqlite.Arg(s.Description),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Price.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "price")...),
|
||||
sqlite.Arg(s.Price),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Quantity.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "quantity")...),
|
||||
sqlite.Arg(s.Quantity),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Added.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "added")...),
|
||||
sqlite.Arg(s.Added),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.UserID.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "user_id")...),
|
||||
sqlite.Arg(s.UserID),
|
||||
}})
|
||||
}
|
||||
|
||||
return exprs
|
||||
}
|
||||
|
||||
// FindItem retrieves a single record by primary key
|
||||
// If cols is empty Find will return all columns.
|
||||
func FindItem(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*Item, error) {
|
||||
if len(cols) == 0 {
|
||||
return Items.Query(
|
||||
SelectWhere.Items.ID.EQ(IDPK),
|
||||
).One(ctx, exec)
|
||||
}
|
||||
|
||||
return Items.Query(
|
||||
SelectWhere.Items.ID.EQ(IDPK),
|
||||
sm.Columns(Items.Columns().Only(cols...)),
|
||||
).One(ctx, exec)
|
||||
}
|
||||
|
||||
// ItemExists checks the presence of a single record by primary key
|
||||
func ItemExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) {
|
||||
return Items.Query(
|
||||
SelectWhere.Items.ID.EQ(IDPK),
|
||||
).Exists(ctx, exec)
|
||||
}
|
||||
|
||||
// AfterQueryHook is called after Item is retrieved from the database
|
||||
func (o *Item) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
|
||||
var err error
|
||||
|
||||
switch queryType {
|
||||
case bob.QueryTypeSelect:
|
||||
ctx, err = Items.AfterSelectHooks.RunHooks(ctx, exec, ItemSlice{o})
|
||||
case bob.QueryTypeInsert:
|
||||
ctx, err = Items.AfterInsertHooks.RunHooks(ctx, exec, ItemSlice{o})
|
||||
case bob.QueryTypeUpdate:
|
||||
ctx, err = Items.AfterUpdateHooks.RunHooks(ctx, exec, ItemSlice{o})
|
||||
case bob.QueryTypeDelete:
|
||||
ctx, err = Items.AfterDeleteHooks.RunHooks(ctx, exec, ItemSlice{o})
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// PrimaryKeyVals returns the primary key values of the Item
|
||||
func (o *Item) PrimaryKeyVals() bob.Expression {
|
||||
return sqlite.Arg(o.ID)
|
||||
}
|
||||
|
||||
func (o *Item) pkEQ() dialect.Expression {
|
||||
return sqlite.Quote("items", "id").EQ(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
return o.PrimaryKeyVals().WriteSQL(ctx, w, d, start)
|
||||
}))
|
||||
}
|
||||
|
||||
// Update uses an executor to update the Item
|
||||
func (o *Item) Update(ctx context.Context, exec bob.Executor, s *ItemSetter) error {
|
||||
v, err := Items.Update(s.UpdateMod(), um.Where(o.pkEQ())).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.R = v.R
|
||||
*o = *v
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes a single Item record with an executor
|
||||
func (o *Item) Delete(ctx context.Context, exec bob.Executor) error {
|
||||
_, err := Items.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
// Reload refreshes the Item using the executor
|
||||
func (o *Item) Reload(ctx context.Context, exec bob.Executor) error {
|
||||
o2, err := Items.Query(
|
||||
SelectWhere.Items.ID.EQ(o.ID),
|
||||
).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o2.R = o.R
|
||||
*o = *o2
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AfterQueryHook is called after ItemSlice is retrieved from the database
|
||||
func (o ItemSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
|
||||
var err error
|
||||
|
||||
switch queryType {
|
||||
case bob.QueryTypeSelect:
|
||||
ctx, err = Items.AfterSelectHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeInsert:
|
||||
ctx, err = Items.AfterInsertHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeUpdate:
|
||||
ctx, err = Items.AfterUpdateHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeDelete:
|
||||
ctx, err = Items.AfterDeleteHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (o ItemSlice) pkIN() dialect.Expression {
|
||||
if len(o) == 0 {
|
||||
return sqlite.Raw("NULL")
|
||||
}
|
||||
|
||||
return sqlite.Quote("items", "id").In(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
pkPairs := make([]bob.Expression, len(o))
|
||||
for i, row := range o {
|
||||
pkPairs[i] = row.PrimaryKeyVals()
|
||||
}
|
||||
return bob.ExpressSlice(ctx, w, d, start, pkPairs, "", ", ", "")
|
||||
}))
|
||||
}
|
||||
|
||||
// copyMatchingRows finds models in the given slice that have the same primary key
|
||||
// then it first copies the existing relationships from the old model to the new model
|
||||
// and then replaces the old model in the slice with the new model
|
||||
func (o ItemSlice) copyMatchingRows(from ...*Item) {
|
||||
for i, old := range o {
|
||||
for _, new := range from {
|
||||
if new.ID != old.ID {
|
||||
continue
|
||||
}
|
||||
new.R = old.R
|
||||
o[i] = new
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateMod modifies an update query with "WHERE primary_key IN (o...)"
|
||||
func (o ItemSlice) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
|
||||
return bob.ModFunc[*dialect.UpdateQuery](func(q *dialect.UpdateQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Items.BeforeUpdateHooks.RunHooks(ctx, exec, o)
|
||||
})
|
||||
|
||||
q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
var err error
|
||||
switch retrieved := retrieved.(type) {
|
||||
case *Item:
|
||||
o.copyMatchingRows(retrieved)
|
||||
case []*Item:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
case ItemSlice:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
default:
|
||||
// If the retrieved value is not a Item or a slice of Item
|
||||
// then run the AfterUpdateHooks on the slice
|
||||
_, err = Items.AfterUpdateHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}))
|
||||
|
||||
q.AppendWhere(o.pkIN())
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
|
||||
func (o ItemSlice) DeleteMod() bob.Mod[*dialect.DeleteQuery] {
|
||||
return bob.ModFunc[*dialect.DeleteQuery](func(q *dialect.DeleteQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Items.BeforeDeleteHooks.RunHooks(ctx, exec, o)
|
||||
})
|
||||
|
||||
q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
var err error
|
||||
switch retrieved := retrieved.(type) {
|
||||
case *Item:
|
||||
o.copyMatchingRows(retrieved)
|
||||
case []*Item:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
case ItemSlice:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
default:
|
||||
// If the retrieved value is not a Item or a slice of Item
|
||||
// then run the AfterDeleteHooks on the slice
|
||||
_, err = Items.AfterDeleteHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}))
|
||||
|
||||
q.AppendWhere(o.pkIN())
|
||||
})
|
||||
}
|
||||
|
||||
func (o ItemSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals ItemSetter) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := Items.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
func (o ItemSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := Items.Delete(o.DeleteMod()).Exec(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
func (o ItemSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
o2, err := Items.Query(sm.Where(o.pkIN())).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.copyMatchingRows(o2...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type itemJoins[Q dialect.Joinable] struct {
|
||||
typ string
|
||||
User func(context.Context) modAs[Q, userColumns]
|
||||
}
|
||||
|
||||
func (j itemJoins[Q]) aliasedAs(alias string) itemJoins[Q] {
|
||||
return buildItemJoins[Q](buildItemColumns(alias), j.typ)
|
||||
}
|
||||
|
||||
func buildItemJoins[Q dialect.Joinable](cols itemColumns, typ string) itemJoins[Q] {
|
||||
return itemJoins[Q]{
|
||||
typ: typ,
|
||||
User: itemsJoinUser[Q](cols, typ),
|
||||
}
|
||||
}
|
||||
|
||||
func itemsJoinUser[Q dialect.Joinable](from itemColumns, typ string) func(context.Context) modAs[Q, userColumns] {
|
||||
return func(ctx context.Context) modAs[Q, userColumns] {
|
||||
return modAs[Q, userColumns]{
|
||||
c: UserColumns,
|
||||
f: func(to userColumns) bob.Mod[Q] {
|
||||
mods := make(mods.QueryMods[Q], 0, 1)
|
||||
|
||||
{
|
||||
mods = append(mods, dialect.Join[Q](typ, Users.Name().As(to.Alias())).On(
|
||||
to.ID.EQ(from.UserID),
|
||||
))
|
||||
}
|
||||
|
||||
return mods
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User starts a query for related objects on users
|
||||
func (o *Item) User(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery {
|
||||
return Users.Query(append(mods,
|
||||
sm.Where(UserColumns.ID.EQ(sqlite.Arg(o.UserID))),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (os ItemSlice) User(mods ...bob.Mod[*dialect.SelectQuery]) UsersQuery {
|
||||
PKArgs := make([]bob.Expression, len(os))
|
||||
for i, o := range os {
|
||||
PKArgs[i] = sqlite.ArgGroup(o.UserID)
|
||||
}
|
||||
|
||||
return Users.Query(append(mods,
|
||||
sm.Where(sqlite.Group(UserColumns.ID).In(PKArgs...)),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (o *Item) Preload(name string, retrieved any) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "User":
|
||||
rel, ok := retrieved.(*User)
|
||||
if !ok {
|
||||
return fmt.Errorf("item cannot load %T as %q", retrieved, name)
|
||||
}
|
||||
|
||||
o.R.User = rel
|
||||
|
||||
if rel != nil {
|
||||
rel.R.Items = ItemSlice{o}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("item has no relationship %q", name)
|
||||
}
|
||||
}
|
||||
|
||||
func PreloadItemUser(opts ...sqlite.PreloadOption) sqlite.Preloader {
|
||||
return sqlite.Preload[*User, UserSlice](orm.Relationship{
|
||||
Name: "User",
|
||||
Sides: []orm.RelSide{
|
||||
{
|
||||
From: TableNames.Items,
|
||||
To: TableNames.Users,
|
||||
FromColumns: []string{
|
||||
ColumnNames.Items.UserID,
|
||||
},
|
||||
ToColumns: []string{
|
||||
ColumnNames.Users.ID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, Users.Columns().Names(), opts...)
|
||||
}
|
||||
|
||||
func ThenLoadItemUser(queryMods ...bob.Mod[*dialect.SelectQuery]) sqlite.Loader {
|
||||
return sqlite.Loader(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
loader, isLoader := retrieved.(interface {
|
||||
LoadItemUser(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
|
||||
})
|
||||
if !isLoader {
|
||||
return fmt.Errorf("object %T cannot load ItemUser", retrieved)
|
||||
}
|
||||
|
||||
err := loader.LoadItemUser(ctx, exec, queryMods...)
|
||||
|
||||
// Don't cause an issue due to missing relationships
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// LoadItemUser loads the item's User into the .R struct
|
||||
func (o *Item) LoadItemUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reset the relationship
|
||||
o.R.User = nil
|
||||
|
||||
related, err := o.User(mods...).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
related.R.Items = ItemSlice{o}
|
||||
|
||||
o.R.User = related
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadItemUser loads the item's User into the .R struct
|
||||
func (os ItemSlice) LoadItemUser(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if len(os) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
users, err := os.User(mods...).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
for _, rel := range users {
|
||||
if o.UserID.GetOrZero() != rel.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
rel.R.Items = append(rel.R.Items, o)
|
||||
|
||||
o.R.User = rel
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func attachItemUser0(ctx context.Context, exec bob.Executor, count int, item0 *Item, user1 *User) (*Item, error) {
|
||||
setter := &ItemSetter{
|
||||
UserID: omitnull.From(user1.ID),
|
||||
}
|
||||
|
||||
err := item0.Update(ctx, exec, setter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("attachItemUser0: %w", err)
|
||||
}
|
||||
|
||||
return item0, nil
|
||||
}
|
||||
|
||||
func (item0 *Item) InsertUser(ctx context.Context, exec bob.Executor, related *UserSetter) error {
|
||||
user1, err := Users.Insert(related).One(ctx, exec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("inserting related objects: %w", err)
|
||||
}
|
||||
|
||||
_, err = attachItemUser0(ctx, exec, 1, item0, user1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
item0.R.User = user1
|
||||
|
||||
user1.R.Items = append(user1.R.Items, item0)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (item0 *Item) AttachUser(ctx context.Context, exec bob.Executor, user1 *User) error {
|
||||
var err error
|
||||
|
||||
_, err = attachItemUser0(ctx, exec, 1, item0, user1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
item0.R.User = user1
|
||||
|
||||
user1.R.Items = append(user1.R.Items, item0)
|
||||
|
||||
return nil
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Passkey struct {
|
||||
ID string `gorm:"primaryKey"`
|
||||
|
||||
PublicKey string
|
||||
Algorithm int
|
||||
CreatedAt time.Time
|
||||
LastUsed time.Time
|
||||
|
||||
// User
|
||||
UserID uint
|
||||
User User
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
userv1 "github.com/spotdemo4/trevstack/server/internal/services/user/v1"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID uint32 `gorm:"primaryKey"`
|
||||
|
||||
Username string
|
||||
Password string
|
||||
Challenge *string
|
||||
|
||||
// Passkeys
|
||||
Passkeys []Passkey
|
||||
|
||||
// Profile picture
|
||||
ProfilePictureID *uint
|
||||
ProfilePicture *File
|
||||
}
|
||||
|
||||
func (u User) ToConnectV1() *userv1.User {
|
||||
var ppid *string
|
||||
if u.ProfilePicture != nil {
|
||||
id := fmt.Sprintf("/file/%d", u.ProfilePicture.ID)
|
||||
ppid = &id
|
||||
}
|
||||
|
||||
return &userv1.User{
|
||||
Id: u.ID,
|
||||
Username: u.Username,
|
||||
ProfilePicture: ppid,
|
||||
}
|
||||
}
|
887
server/internal/models/users.bob.go
Normal file
887
server/internal/models/users.bob.go
Normal file
@ -0,0 +1,887 @@
|
||||
// Code generated by BobGen sqlite (devel). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/aarondl/opt/null"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/aarondl/opt/omitnull"
|
||||
"github.com/stephenafamo/bob"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/dialect"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/dm"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/sm"
|
||||
"github.com/stephenafamo/bob/dialect/sqlite/um"
|
||||
"github.com/stephenafamo/bob/expr"
|
||||
"github.com/stephenafamo/bob/mods"
|
||||
)
|
||||
|
||||
// User is an object representing the database table.
|
||||
type User struct {
|
||||
ID int32 `db:"id,pk" `
|
||||
Username null.Val[string] `db:"username" `
|
||||
Password null.Val[string] `db:"password" `
|
||||
ProfilePictureID null.Val[int32] `db:"profile_picture_id" `
|
||||
Challenge null.Val[string] `db:"challenge" `
|
||||
|
||||
R userR `db:"-" `
|
||||
}
|
||||
|
||||
// UserSlice is an alias for a slice of pointers to User.
|
||||
// This should almost always be used instead of []*User.
|
||||
type UserSlice []*User
|
||||
|
||||
// Users contains methods to work with the users table
|
||||
var Users = sqlite.NewTablex[*User, UserSlice, *UserSetter]("", "users")
|
||||
|
||||
// UsersQuery is a query on the users table
|
||||
type UsersQuery = *sqlite.ViewQuery[*User, UserSlice]
|
||||
|
||||
// userR is where relationships are stored.
|
||||
type userR struct {
|
||||
Files FileSlice // fk_files_0
|
||||
Items ItemSlice // fk_items_0
|
||||
}
|
||||
|
||||
type userColumnNames struct {
|
||||
ID string
|
||||
Username string
|
||||
Password string
|
||||
ProfilePictureID string
|
||||
Challenge string
|
||||
}
|
||||
|
||||
var UserColumns = buildUserColumns("users")
|
||||
|
||||
type userColumns struct {
|
||||
tableAlias string
|
||||
ID sqlite.Expression
|
||||
Username sqlite.Expression
|
||||
Password sqlite.Expression
|
||||
ProfilePictureID sqlite.Expression
|
||||
Challenge sqlite.Expression
|
||||
}
|
||||
|
||||
func (c userColumns) Alias() string {
|
||||
return c.tableAlias
|
||||
}
|
||||
|
||||
func (userColumns) AliasedAs(alias string) userColumns {
|
||||
return buildUserColumns(alias)
|
||||
}
|
||||
|
||||
func buildUserColumns(alias string) userColumns {
|
||||
return userColumns{
|
||||
tableAlias: alias,
|
||||
ID: sqlite.Quote(alias, "id"),
|
||||
Username: sqlite.Quote(alias, "username"),
|
||||
Password: sqlite.Quote(alias, "password"),
|
||||
ProfilePictureID: sqlite.Quote(alias, "profile_picture_id"),
|
||||
Challenge: sqlite.Quote(alias, "challenge"),
|
||||
}
|
||||
}
|
||||
|
||||
type userWhere[Q sqlite.Filterable] struct {
|
||||
ID sqlite.WhereMod[Q, int32]
|
||||
Username sqlite.WhereNullMod[Q, string]
|
||||
Password sqlite.WhereNullMod[Q, string]
|
||||
ProfilePictureID sqlite.WhereNullMod[Q, int32]
|
||||
Challenge sqlite.WhereNullMod[Q, string]
|
||||
}
|
||||
|
||||
func (userWhere[Q]) AliasedAs(alias string) userWhere[Q] {
|
||||
return buildUserWhere[Q](buildUserColumns(alias))
|
||||
}
|
||||
|
||||
func buildUserWhere[Q sqlite.Filterable](cols userColumns) userWhere[Q] {
|
||||
return userWhere[Q]{
|
||||
ID: sqlite.Where[Q, int32](cols.ID),
|
||||
Username: sqlite.WhereNull[Q, string](cols.Username),
|
||||
Password: sqlite.WhereNull[Q, string](cols.Password),
|
||||
ProfilePictureID: sqlite.WhereNull[Q, int32](cols.ProfilePictureID),
|
||||
Challenge: sqlite.WhereNull[Q, string](cols.Challenge),
|
||||
}
|
||||
}
|
||||
|
||||
var UserErrors = &userErrors{
|
||||
ErrUniquePkMainUsers: &UniqueConstraintError{s: "pk_main_users"},
|
||||
}
|
||||
|
||||
type userErrors struct {
|
||||
ErrUniquePkMainUsers *UniqueConstraintError
|
||||
}
|
||||
|
||||
// UserSetter is used for insert/upsert/update operations
|
||||
// All values are optional, and do not have to be set
|
||||
// Generated columns are not included
|
||||
type UserSetter struct {
|
||||
ID omit.Val[int32] `db:"id,pk" `
|
||||
Username omitnull.Val[string] `db:"username" `
|
||||
Password omitnull.Val[string] `db:"password" `
|
||||
ProfilePictureID omitnull.Val[int32] `db:"profile_picture_id" `
|
||||
Challenge omitnull.Val[string] `db:"challenge" `
|
||||
}
|
||||
|
||||
func (s UserSetter) SetColumns() []string {
|
||||
vals := make([]string, 0, 5)
|
||||
if !s.ID.IsUnset() {
|
||||
vals = append(vals, "id")
|
||||
}
|
||||
|
||||
if !s.Username.IsUnset() {
|
||||
vals = append(vals, "username")
|
||||
}
|
||||
|
||||
if !s.Password.IsUnset() {
|
||||
vals = append(vals, "password")
|
||||
}
|
||||
|
||||
if !s.ProfilePictureID.IsUnset() {
|
||||
vals = append(vals, "profile_picture_id")
|
||||
}
|
||||
|
||||
if !s.Challenge.IsUnset() {
|
||||
vals = append(vals, "challenge")
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
func (s UserSetter) Overwrite(t *User) {
|
||||
if !s.ID.IsUnset() {
|
||||
t.ID, _ = s.ID.Get()
|
||||
}
|
||||
if !s.Username.IsUnset() {
|
||||
t.Username, _ = s.Username.GetNull()
|
||||
}
|
||||
if !s.Password.IsUnset() {
|
||||
t.Password, _ = s.Password.GetNull()
|
||||
}
|
||||
if !s.ProfilePictureID.IsUnset() {
|
||||
t.ProfilePictureID, _ = s.ProfilePictureID.GetNull()
|
||||
}
|
||||
if !s.Challenge.IsUnset() {
|
||||
t.Challenge, _ = s.Challenge.GetNull()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *UserSetter) Apply(q *dialect.InsertQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Users.BeforeInsertHooks.RunHooks(ctx, exec, s)
|
||||
})
|
||||
|
||||
if len(q.Table.Columns) == 0 {
|
||||
q.Table.Columns = s.SetColumns()
|
||||
}
|
||||
|
||||
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
vals := make([]bob.Expression, 0, 5)
|
||||
if !s.ID.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.ID))
|
||||
}
|
||||
|
||||
if !s.Username.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Username))
|
||||
}
|
||||
|
||||
if !s.Password.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Password))
|
||||
}
|
||||
|
||||
if !s.ProfilePictureID.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.ProfilePictureID))
|
||||
}
|
||||
|
||||
if !s.Challenge.IsUnset() {
|
||||
vals = append(vals, sqlite.Arg(s.Challenge))
|
||||
}
|
||||
|
||||
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
|
||||
}))
|
||||
}
|
||||
|
||||
func (s UserSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
|
||||
return um.Set(s.Expressions()...)
|
||||
}
|
||||
|
||||
func (s UserSetter) Expressions(prefix ...string) []bob.Expression {
|
||||
exprs := make([]bob.Expression, 0, 5)
|
||||
|
||||
if !s.ID.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "id")...),
|
||||
sqlite.Arg(s.ID),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Username.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "username")...),
|
||||
sqlite.Arg(s.Username),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Password.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "password")...),
|
||||
sqlite.Arg(s.Password),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.ProfilePictureID.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "profile_picture_id")...),
|
||||
sqlite.Arg(s.ProfilePictureID),
|
||||
}})
|
||||
}
|
||||
|
||||
if !s.Challenge.IsUnset() {
|
||||
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
|
||||
sqlite.Quote(append(prefix, "challenge")...),
|
||||
sqlite.Arg(s.Challenge),
|
||||
}})
|
||||
}
|
||||
|
||||
return exprs
|
||||
}
|
||||
|
||||
// FindUser retrieves a single record by primary key
|
||||
// If cols is empty Find will return all columns.
|
||||
func FindUser(ctx context.Context, exec bob.Executor, IDPK int32, cols ...string) (*User, error) {
|
||||
if len(cols) == 0 {
|
||||
return Users.Query(
|
||||
SelectWhere.Users.ID.EQ(IDPK),
|
||||
).One(ctx, exec)
|
||||
}
|
||||
|
||||
return Users.Query(
|
||||
SelectWhere.Users.ID.EQ(IDPK),
|
||||
sm.Columns(Users.Columns().Only(cols...)),
|
||||
).One(ctx, exec)
|
||||
}
|
||||
|
||||
// UserExists checks the presence of a single record by primary key
|
||||
func UserExists(ctx context.Context, exec bob.Executor, IDPK int32) (bool, error) {
|
||||
return Users.Query(
|
||||
SelectWhere.Users.ID.EQ(IDPK),
|
||||
).Exists(ctx, exec)
|
||||
}
|
||||
|
||||
// AfterQueryHook is called after User is retrieved from the database
|
||||
func (o *User) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
|
||||
var err error
|
||||
|
||||
switch queryType {
|
||||
case bob.QueryTypeSelect:
|
||||
ctx, err = Users.AfterSelectHooks.RunHooks(ctx, exec, UserSlice{o})
|
||||
case bob.QueryTypeInsert:
|
||||
ctx, err = Users.AfterInsertHooks.RunHooks(ctx, exec, UserSlice{o})
|
||||
case bob.QueryTypeUpdate:
|
||||
ctx, err = Users.AfterUpdateHooks.RunHooks(ctx, exec, UserSlice{o})
|
||||
case bob.QueryTypeDelete:
|
||||
ctx, err = Users.AfterDeleteHooks.RunHooks(ctx, exec, UserSlice{o})
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// PrimaryKeyVals returns the primary key values of the User
|
||||
func (o *User) PrimaryKeyVals() bob.Expression {
|
||||
return sqlite.Arg(o.ID)
|
||||
}
|
||||
|
||||
func (o *User) pkEQ() dialect.Expression {
|
||||
return sqlite.Quote("users", "id").EQ(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
return o.PrimaryKeyVals().WriteSQL(ctx, w, d, start)
|
||||
}))
|
||||
}
|
||||
|
||||
// Update uses an executor to update the User
|
||||
func (o *User) Update(ctx context.Context, exec bob.Executor, s *UserSetter) error {
|
||||
v, err := Users.Update(s.UpdateMod(), um.Where(o.pkEQ())).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.R = v.R
|
||||
*o = *v
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete deletes a single User record with an executor
|
||||
func (o *User) Delete(ctx context.Context, exec bob.Executor) error {
|
||||
_, err := Users.Delete(dm.Where(o.pkEQ())).Exec(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
// Reload refreshes the User using the executor
|
||||
func (o *User) Reload(ctx context.Context, exec bob.Executor) error {
|
||||
o2, err := Users.Query(
|
||||
SelectWhere.Users.ID.EQ(o.ID),
|
||||
).One(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o2.R = o.R
|
||||
*o = *o2
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AfterQueryHook is called after UserSlice is retrieved from the database
|
||||
func (o UserSlice) AfterQueryHook(ctx context.Context, exec bob.Executor, queryType bob.QueryType) error {
|
||||
var err error
|
||||
|
||||
switch queryType {
|
||||
case bob.QueryTypeSelect:
|
||||
ctx, err = Users.AfterSelectHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeInsert:
|
||||
ctx, err = Users.AfterInsertHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeUpdate:
|
||||
ctx, err = Users.AfterUpdateHooks.RunHooks(ctx, exec, o)
|
||||
case bob.QueryTypeDelete:
|
||||
ctx, err = Users.AfterDeleteHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (o UserSlice) pkIN() dialect.Expression {
|
||||
if len(o) == 0 {
|
||||
return sqlite.Raw("NULL")
|
||||
}
|
||||
|
||||
return sqlite.Quote("users", "id").In(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
|
||||
pkPairs := make([]bob.Expression, len(o))
|
||||
for i, row := range o {
|
||||
pkPairs[i] = row.PrimaryKeyVals()
|
||||
}
|
||||
return bob.ExpressSlice(ctx, w, d, start, pkPairs, "", ", ", "")
|
||||
}))
|
||||
}
|
||||
|
||||
// copyMatchingRows finds models in the given slice that have the same primary key
|
||||
// then it first copies the existing relationships from the old model to the new model
|
||||
// and then replaces the old model in the slice with the new model
|
||||
func (o UserSlice) copyMatchingRows(from ...*User) {
|
||||
for i, old := range o {
|
||||
for _, new := range from {
|
||||
if new.ID != old.ID {
|
||||
continue
|
||||
}
|
||||
new.R = old.R
|
||||
o[i] = new
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateMod modifies an update query with "WHERE primary_key IN (o...)"
|
||||
func (o UserSlice) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
|
||||
return bob.ModFunc[*dialect.UpdateQuery](func(q *dialect.UpdateQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Users.BeforeUpdateHooks.RunHooks(ctx, exec, o)
|
||||
})
|
||||
|
||||
q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
var err error
|
||||
switch retrieved := retrieved.(type) {
|
||||
case *User:
|
||||
o.copyMatchingRows(retrieved)
|
||||
case []*User:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
case UserSlice:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
default:
|
||||
// If the retrieved value is not a User or a slice of User
|
||||
// then run the AfterUpdateHooks on the slice
|
||||
_, err = Users.AfterUpdateHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}))
|
||||
|
||||
q.AppendWhere(o.pkIN())
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteMod modifies an delete query with "WHERE primary_key IN (o...)"
|
||||
func (o UserSlice) DeleteMod() bob.Mod[*dialect.DeleteQuery] {
|
||||
return bob.ModFunc[*dialect.DeleteQuery](func(q *dialect.DeleteQuery) {
|
||||
q.AppendHooks(func(ctx context.Context, exec bob.Executor) (context.Context, error) {
|
||||
return Users.BeforeDeleteHooks.RunHooks(ctx, exec, o)
|
||||
})
|
||||
|
||||
q.AppendLoader(bob.LoaderFunc(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
var err error
|
||||
switch retrieved := retrieved.(type) {
|
||||
case *User:
|
||||
o.copyMatchingRows(retrieved)
|
||||
case []*User:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
case UserSlice:
|
||||
o.copyMatchingRows(retrieved...)
|
||||
default:
|
||||
// If the retrieved value is not a User or a slice of User
|
||||
// then run the AfterDeleteHooks on the slice
|
||||
_, err = Users.AfterDeleteHooks.RunHooks(ctx, exec, o)
|
||||
}
|
||||
|
||||
return err
|
||||
}))
|
||||
|
||||
q.AppendWhere(o.pkIN())
|
||||
})
|
||||
}
|
||||
|
||||
func (o UserSlice) UpdateAll(ctx context.Context, exec bob.Executor, vals UserSetter) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := Users.Update(vals.UpdateMod(), o.UpdateMod()).All(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
func (o UserSlice) DeleteAll(ctx context.Context, exec bob.Executor) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := Users.Delete(o.DeleteMod()).Exec(ctx, exec)
|
||||
return err
|
||||
}
|
||||
|
||||
func (o UserSlice) ReloadAll(ctx context.Context, exec bob.Executor) error {
|
||||
if len(o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
o2, err := Users.Query(sm.Where(o.pkIN())).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
o.copyMatchingRows(o2...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type userJoins[Q dialect.Joinable] struct {
|
||||
typ string
|
||||
Files func(context.Context) modAs[Q, fileColumns]
|
||||
Items func(context.Context) modAs[Q, itemColumns]
|
||||
}
|
||||
|
||||
func (j userJoins[Q]) aliasedAs(alias string) userJoins[Q] {
|
||||
return buildUserJoins[Q](buildUserColumns(alias), j.typ)
|
||||
}
|
||||
|
||||
func buildUserJoins[Q dialect.Joinable](cols userColumns, typ string) userJoins[Q] {
|
||||
return userJoins[Q]{
|
||||
typ: typ,
|
||||
Files: usersJoinFiles[Q](cols, typ),
|
||||
Items: usersJoinItems[Q](cols, typ),
|
||||
}
|
||||
}
|
||||
|
||||
func usersJoinFiles[Q dialect.Joinable](from userColumns, typ string) func(context.Context) modAs[Q, fileColumns] {
|
||||
return func(ctx context.Context) modAs[Q, fileColumns] {
|
||||
return modAs[Q, fileColumns]{
|
||||
c: FileColumns,
|
||||
f: func(to fileColumns) bob.Mod[Q] {
|
||||
mods := make(mods.QueryMods[Q], 0, 1)
|
||||
|
||||
{
|
||||
mods = append(mods, dialect.Join[Q](typ, Files.Name().As(to.Alias())).On(
|
||||
to.UserID.EQ(from.ID),
|
||||
))
|
||||
}
|
||||
|
||||
return mods
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func usersJoinItems[Q dialect.Joinable](from userColumns, typ string) func(context.Context) modAs[Q, itemColumns] {
|
||||
return func(ctx context.Context) modAs[Q, itemColumns] {
|
||||
return modAs[Q, itemColumns]{
|
||||
c: ItemColumns,
|
||||
f: func(to itemColumns) bob.Mod[Q] {
|
||||
mods := make(mods.QueryMods[Q], 0, 1)
|
||||
|
||||
{
|
||||
mods = append(mods, dialect.Join[Q](typ, Items.Name().As(to.Alias())).On(
|
||||
to.UserID.EQ(from.ID),
|
||||
))
|
||||
}
|
||||
|
||||
return mods
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Files starts a query for related objects on files
|
||||
func (o *User) Files(mods ...bob.Mod[*dialect.SelectQuery]) FilesQuery {
|
||||
return Files.Query(append(mods,
|
||||
sm.Where(FileColumns.UserID.EQ(sqlite.Arg(o.ID))),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (os UserSlice) Files(mods ...bob.Mod[*dialect.SelectQuery]) FilesQuery {
|
||||
PKArgs := make([]bob.Expression, len(os))
|
||||
for i, o := range os {
|
||||
PKArgs[i] = sqlite.ArgGroup(o.ID)
|
||||
}
|
||||
|
||||
return Files.Query(append(mods,
|
||||
sm.Where(sqlite.Group(FileColumns.UserID).In(PKArgs...)),
|
||||
)...)
|
||||
}
|
||||
|
||||
// Items starts a query for related objects on items
|
||||
func (o *User) Items(mods ...bob.Mod[*dialect.SelectQuery]) ItemsQuery {
|
||||
return Items.Query(append(mods,
|
||||
sm.Where(ItemColumns.UserID.EQ(sqlite.Arg(o.ID))),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (os UserSlice) Items(mods ...bob.Mod[*dialect.SelectQuery]) ItemsQuery {
|
||||
PKArgs := make([]bob.Expression, len(os))
|
||||
for i, o := range os {
|
||||
PKArgs[i] = sqlite.ArgGroup(o.ID)
|
||||
}
|
||||
|
||||
return Items.Query(append(mods,
|
||||
sm.Where(sqlite.Group(ItemColumns.UserID).In(PKArgs...)),
|
||||
)...)
|
||||
}
|
||||
|
||||
func (o *User) Preload(name string, retrieved any) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "Files":
|
||||
rels, ok := retrieved.(FileSlice)
|
||||
if !ok {
|
||||
return fmt.Errorf("user cannot load %T as %q", retrieved, name)
|
||||
}
|
||||
|
||||
o.R.Files = rels
|
||||
|
||||
for _, rel := range rels {
|
||||
if rel != nil {
|
||||
rel.R.User = o
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case "Items":
|
||||
rels, ok := retrieved.(ItemSlice)
|
||||
if !ok {
|
||||
return fmt.Errorf("user cannot load %T as %q", retrieved, name)
|
||||
}
|
||||
|
||||
o.R.Items = rels
|
||||
|
||||
for _, rel := range rels {
|
||||
if rel != nil {
|
||||
rel.R.User = o
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("user has no relationship %q", name)
|
||||
}
|
||||
}
|
||||
|
||||
func ThenLoadUserFiles(queryMods ...bob.Mod[*dialect.SelectQuery]) sqlite.Loader {
|
||||
return sqlite.Loader(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
loader, isLoader := retrieved.(interface {
|
||||
LoadUserFiles(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
|
||||
})
|
||||
if !isLoader {
|
||||
return fmt.Errorf("object %T cannot load UserFiles", retrieved)
|
||||
}
|
||||
|
||||
err := loader.LoadUserFiles(ctx, exec, queryMods...)
|
||||
|
||||
// Don't cause an issue due to missing relationships
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// LoadUserFiles loads the user's Files into the .R struct
|
||||
func (o *User) LoadUserFiles(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reset the relationship
|
||||
o.R.Files = nil
|
||||
|
||||
related, err := o.Files(mods...).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, rel := range related {
|
||||
rel.R.User = o
|
||||
}
|
||||
|
||||
o.R.Files = related
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadUserFiles loads the user's Files into the .R struct
|
||||
func (os UserSlice) LoadUserFiles(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if len(os) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
files, err := os.Files(mods...).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
o.R.Files = nil
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
for _, rel := range files {
|
||||
if o.ID != rel.UserID.GetOrZero() {
|
||||
continue
|
||||
}
|
||||
|
||||
rel.R.User = o
|
||||
|
||||
o.R.Files = append(o.R.Files, rel)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ThenLoadUserItems(queryMods ...bob.Mod[*dialect.SelectQuery]) sqlite.Loader {
|
||||
return sqlite.Loader(func(ctx context.Context, exec bob.Executor, retrieved any) error {
|
||||
loader, isLoader := retrieved.(interface {
|
||||
LoadUserItems(context.Context, bob.Executor, ...bob.Mod[*dialect.SelectQuery]) error
|
||||
})
|
||||
if !isLoader {
|
||||
return fmt.Errorf("object %T cannot load UserItems", retrieved)
|
||||
}
|
||||
|
||||
err := loader.LoadUserItems(ctx, exec, queryMods...)
|
||||
|
||||
// Don't cause an issue due to missing relationships
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// LoadUserItems loads the user's Items into the .R struct
|
||||
func (o *User) LoadUserItems(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reset the relationship
|
||||
o.R.Items = nil
|
||||
|
||||
related, err := o.Items(mods...).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, rel := range related {
|
||||
rel.R.User = o
|
||||
}
|
||||
|
||||
o.R.Items = related
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadUserItems loads the user's Items into the .R struct
|
||||
func (os UserSlice) LoadUserItems(ctx context.Context, exec bob.Executor, mods ...bob.Mod[*dialect.SelectQuery]) error {
|
||||
if len(os) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
items, err := os.Items(mods...).All(ctx, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
o.R.Items = nil
|
||||
}
|
||||
|
||||
for _, o := range os {
|
||||
for _, rel := range items {
|
||||
if o.ID != rel.UserID.GetOrZero() {
|
||||
continue
|
||||
}
|
||||
|
||||
rel.R.User = o
|
||||
|
||||
o.R.Items = append(o.R.Items, rel)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func insertUserFiles0(ctx context.Context, exec bob.Executor, files1 []*FileSetter, user0 *User) (FileSlice, error) {
|
||||
for i := range files1 {
|
||||
files1[i].UserID = omitnull.From(user0.ID)
|
||||
}
|
||||
|
||||
ret, err := Files.Insert(bob.ToMods(files1...)).All(ctx, exec)
|
||||
if err != nil {
|
||||
return ret, fmt.Errorf("insertUserFiles0: %w", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func attachUserFiles0(ctx context.Context, exec bob.Executor, count int, files1 FileSlice, user0 *User) (FileSlice, error) {
|
||||
setter := &FileSetter{
|
||||
UserID: omitnull.From(user0.ID),
|
||||
}
|
||||
|
||||
err := files1.UpdateAll(ctx, exec, *setter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("attachUserFiles0: %w", err)
|
||||
}
|
||||
|
||||
return files1, nil
|
||||
}
|
||||
|
||||
func (user0 *User) InsertFiles(ctx context.Context, exec bob.Executor, related ...*FileSetter) error {
|
||||
if len(related) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
files1, err := insertUserFiles0(ctx, exec, related, user0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user0.R.Files = append(user0.R.Files, files1...)
|
||||
|
||||
for _, rel := range files1 {
|
||||
rel.R.User = user0
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (user0 *User) AttachFiles(ctx context.Context, exec bob.Executor, related ...*File) error {
|
||||
if len(related) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
files1 := FileSlice(related)
|
||||
|
||||
_, err = attachUserFiles0(ctx, exec, len(related), files1, user0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user0.R.Files = append(user0.R.Files, files1...)
|
||||
|
||||
for _, rel := range related {
|
||||
rel.R.User = user0
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func insertUserItems0(ctx context.Context, exec bob.Executor, items1 []*ItemSetter, user0 *User) (ItemSlice, error) {
|
||||
for i := range items1 {
|
||||
items1[i].UserID = omitnull.From(user0.ID)
|
||||
}
|
||||
|
||||
ret, err := Items.Insert(bob.ToMods(items1...)).All(ctx, exec)
|
||||
if err != nil {
|
||||
return ret, fmt.Errorf("insertUserItems0: %w", err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func attachUserItems0(ctx context.Context, exec bob.Executor, count int, items1 ItemSlice, user0 *User) (ItemSlice, error) {
|
||||
setter := &ItemSetter{
|
||||
UserID: omitnull.From(user0.ID),
|
||||
}
|
||||
|
||||
err := items1.UpdateAll(ctx, exec, *setter)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("attachUserItems0: %w", err)
|
||||
}
|
||||
|
||||
return items1, nil
|
||||
}
|
||||
|
||||
func (user0 *User) InsertItems(ctx context.Context, exec bob.Executor, related ...*ItemSetter) error {
|
||||
if len(related) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
items1, err := insertUserItems0(ctx, exec, related, user0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user0.R.Items = append(user0.R.Items, items1...)
|
||||
|
||||
for _, rel := range items1 {
|
||||
rel.R.User = user0
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (user0 *User) AttachItems(ctx context.Context, exec bob.Executor, related ...*Item) error {
|
||||
if len(related) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
items1 := ItemSlice(related)
|
||||
|
||||
_, err = attachUserItems0(ctx, exec, len(related), items1, user0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user0.R.Items = append(user0.R.Items, items1...)
|
||||
|
||||
for _, rel := range related {
|
||||
rel.R.User = user0
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -373,29 +373,26 @@ func (x *GetPasskeyIDsResponse) GetPasskeyIds() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
type PasskeyLoginRequest struct {
|
||||
type BeginPasskeyLoginRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
|
||||
Algorithm int32 `protobuf:"varint,3,opt,name=algorithm,proto3" json:"algorithm,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginRequest) Reset() {
|
||||
*x = PasskeyLoginRequest{}
|
||||
func (x *BeginPasskeyLoginRequest) Reset() {
|
||||
*x = BeginPasskeyLoginRequest{}
|
||||
mi := &file_user_v1_auth_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginRequest) String() string {
|
||||
func (x *BeginPasskeyLoginRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PasskeyLoginRequest) ProtoMessage() {}
|
||||
func (*BeginPasskeyLoginRequest) ProtoMessage() {}
|
||||
|
||||
func (x *PasskeyLoginRequest) ProtoReflect() protoreflect.Message {
|
||||
func (x *BeginPasskeyLoginRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_auth_proto_msgTypes[8]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -407,53 +404,31 @@ func (x *PasskeyLoginRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PasskeyLoginRequest.ProtoReflect.Descriptor instead.
|
||||
func (*PasskeyLoginRequest) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use BeginPasskeyLoginRequest.ProtoReflect.Descriptor instead.
|
||||
func (*BeginPasskeyLoginRequest) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_auth_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginRequest) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginRequest) GetSignature() []byte {
|
||||
if x != nil {
|
||||
return x.Signature
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginRequest) GetAlgorithm() int32 {
|
||||
if x != nil {
|
||||
return x.Algorithm
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type PasskeyLoginResponse struct {
|
||||
type BeginPasskeyLoginResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginResponse) Reset() {
|
||||
*x = PasskeyLoginResponse{}
|
||||
func (x *BeginPasskeyLoginResponse) Reset() {
|
||||
*x = BeginPasskeyLoginResponse{}
|
||||
mi := &file_user_v1_auth_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginResponse) String() string {
|
||||
func (x *BeginPasskeyLoginResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PasskeyLoginResponse) ProtoMessage() {}
|
||||
func (*BeginPasskeyLoginResponse) ProtoMessage() {}
|
||||
|
||||
func (x *PasskeyLoginResponse) ProtoReflect() protoreflect.Message {
|
||||
func (x *BeginPasskeyLoginResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_auth_proto_msgTypes[9]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -465,16 +440,81 @@ func (x *PasskeyLoginResponse) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PasskeyLoginResponse.ProtoReflect.Descriptor instead.
|
||||
func (*PasskeyLoginResponse) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use BeginPasskeyLoginResponse.ProtoReflect.Descriptor instead.
|
||||
func (*BeginPasskeyLoginResponse) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_auth_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *PasskeyLoginResponse) GetToken() string {
|
||||
type FinishPasskeyLoginRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyLoginRequest) Reset() {
|
||||
*x = FinishPasskeyLoginRequest{}
|
||||
mi := &file_user_v1_auth_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyLoginRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FinishPasskeyLoginRequest) ProtoMessage() {}
|
||||
|
||||
func (x *FinishPasskeyLoginRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_auth_proto_msgTypes[10]
|
||||
if x != nil {
|
||||
return x.Token
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return ""
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FinishPasskeyLoginRequest.ProtoReflect.Descriptor instead.
|
||||
func (*FinishPasskeyLoginRequest) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_auth_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
type FinishPasskeyLoginResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyLoginResponse) Reset() {
|
||||
*x = FinishPasskeyLoginResponse{}
|
||||
mi := &file_user_v1_auth_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyLoginResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FinishPasskeyLoginResponse) ProtoMessage() {}
|
||||
|
||||
func (x *FinishPasskeyLoginResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_auth_proto_msgTypes[11]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FinishPasskeyLoginResponse.ProtoReflect.Descriptor instead.
|
||||
func (*FinishPasskeyLoginResponse) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_auth_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
var File_user_v1_auth_proto protoreflect.FileDescriptor
|
||||
@ -506,49 +546,54 @@ var file_user_v1_auth_proto_rawDesc = string([]byte{
|
||||
0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x49, 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64,
|
||||
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79,
|
||||
0x49, 0x64, 0x73, 0x22, 0x61, 0x0a, 0x13, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f,
|
||||
0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f,
|
||||
0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x61, 0x6c, 0x67,
|
||||
0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0x2c, 0x0a, 0x14, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65,
|
||||
0x79, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xe2, 0x02, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x15, 0x2e,
|
||||
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b,
|
||||
0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x12, 0x16, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x55,
|
||||
0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x06, 0x4c,
|
||||
0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e,
|
||||
0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x50,
|
||||
0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x49, 0x44, 0x73, 0x12, 0x1d, 0x2e, 0x75, 0x73, 0x65, 0x72,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x49, 0x44,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x49, 0x44, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0c, 0x50, 0x61,
|
||||
0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x75, 0x73, 0x65,
|
||||
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9d, 0x01, 0x0a, 0x0b, 0x63, 0x6f,
|
||||
0x6d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x41, 0x75, 0x74, 0x68, 0x50,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x73, 0x70, 0x6f, 0x74, 0x64, 0x65, 0x6d, 0x6f, 0x34, 0x2f, 0x74, 0x72, 0x65,
|
||||
0x76, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
|
||||
0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02,
|
||||
0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02,
|
||||
0x07, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x55, 0x73, 0x65, 0x72, 0x5c,
|
||||
0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
|
||||
0x08, 0x55, 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
0x49, 0x64, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73,
|
||||
0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
|
||||
0x1b, 0x0a, 0x19, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x0a, 0x19,
|
||||
0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67,
|
||||
0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1c, 0x0a, 0x1a, 0x46, 0x69, 0x6e,
|
||||
0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xd2, 0x03, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68,
|
||||
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
|
||||
0x12, 0x15, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x00, 0x12, 0x3b, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x12, 0x16, 0x2e, 0x75, 0x73,
|
||||
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b,
|
||||
0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x6f, 0x75,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0d, 0x47,
|
||||
0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x49, 0x44, 0x73, 0x12, 0x1d, 0x2e, 0x75,
|
||||
0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65,
|
||||
0x79, 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x75, 0x73,
|
||||
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79,
|
||||
0x49, 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a,
|
||||
0x11, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67,
|
||||
0x69, 0x6e, 0x12, 0x21, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x67,
|
||||
0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x42, 0x65, 0x67, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69,
|
||||
0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5f, 0x0a, 0x12, 0x46,
|
||||
0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69,
|
||||
0x6e, 0x12, 0x22, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x69,
|
||||
0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x67,
|
||||
0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9d, 0x01, 0x0a,
|
||||
0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x41, 0x75,
|
||||
0x74, 0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x70, 0x6f, 0x74, 0x64, 0x65, 0x6d, 0x6f, 0x34, 0x2f,
|
||||
0x74, 0x72, 0x65, 0x76, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76,
|
||||
0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56,
|
||||
0x31, 0xca, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x55, 0x73,
|
||||
0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0xea, 0x02, 0x08, 0x55, 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var (
|
||||
@ -563,35 +608,39 @@ func file_user_v1_auth_proto_rawDescGZIP() []byte {
|
||||
return file_user_v1_auth_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_user_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_user_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
||||
var file_user_v1_auth_proto_goTypes = []any{
|
||||
(*LoginRequest)(nil), // 0: user.v1.LoginRequest
|
||||
(*LoginResponse)(nil), // 1: user.v1.LoginResponse
|
||||
(*SignUpRequest)(nil), // 2: user.v1.SignUpRequest
|
||||
(*SignUpResponse)(nil), // 3: user.v1.SignUpResponse
|
||||
(*LogoutRequest)(nil), // 4: user.v1.LogoutRequest
|
||||
(*LogoutResponse)(nil), // 5: user.v1.LogoutResponse
|
||||
(*GetPasskeyIDsRequest)(nil), // 6: user.v1.GetPasskeyIDsRequest
|
||||
(*GetPasskeyIDsResponse)(nil), // 7: user.v1.GetPasskeyIDsResponse
|
||||
(*PasskeyLoginRequest)(nil), // 8: user.v1.PasskeyLoginRequest
|
||||
(*PasskeyLoginResponse)(nil), // 9: user.v1.PasskeyLoginResponse
|
||||
(*LoginRequest)(nil), // 0: user.v1.LoginRequest
|
||||
(*LoginResponse)(nil), // 1: user.v1.LoginResponse
|
||||
(*SignUpRequest)(nil), // 2: user.v1.SignUpRequest
|
||||
(*SignUpResponse)(nil), // 3: user.v1.SignUpResponse
|
||||
(*LogoutRequest)(nil), // 4: user.v1.LogoutRequest
|
||||
(*LogoutResponse)(nil), // 5: user.v1.LogoutResponse
|
||||
(*GetPasskeyIDsRequest)(nil), // 6: user.v1.GetPasskeyIDsRequest
|
||||
(*GetPasskeyIDsResponse)(nil), // 7: user.v1.GetPasskeyIDsResponse
|
||||
(*BeginPasskeyLoginRequest)(nil), // 8: user.v1.BeginPasskeyLoginRequest
|
||||
(*BeginPasskeyLoginResponse)(nil), // 9: user.v1.BeginPasskeyLoginResponse
|
||||
(*FinishPasskeyLoginRequest)(nil), // 10: user.v1.FinishPasskeyLoginRequest
|
||||
(*FinishPasskeyLoginResponse)(nil), // 11: user.v1.FinishPasskeyLoginResponse
|
||||
}
|
||||
var file_user_v1_auth_proto_depIdxs = []int32{
|
||||
0, // 0: user.v1.AuthService.Login:input_type -> user.v1.LoginRequest
|
||||
2, // 1: user.v1.AuthService.SignUp:input_type -> user.v1.SignUpRequest
|
||||
4, // 2: user.v1.AuthService.Logout:input_type -> user.v1.LogoutRequest
|
||||
6, // 3: user.v1.AuthService.GetPasskeyIDs:input_type -> user.v1.GetPasskeyIDsRequest
|
||||
8, // 4: user.v1.AuthService.PasskeyLogin:input_type -> user.v1.PasskeyLoginRequest
|
||||
1, // 5: user.v1.AuthService.Login:output_type -> user.v1.LoginResponse
|
||||
3, // 6: user.v1.AuthService.SignUp:output_type -> user.v1.SignUpResponse
|
||||
5, // 7: user.v1.AuthService.Logout:output_type -> user.v1.LogoutResponse
|
||||
7, // 8: user.v1.AuthService.GetPasskeyIDs:output_type -> user.v1.GetPasskeyIDsResponse
|
||||
9, // 9: user.v1.AuthService.PasskeyLogin:output_type -> user.v1.PasskeyLoginResponse
|
||||
5, // [5:10] is the sub-list for method output_type
|
||||
0, // [0:5] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
0, // 0: user.v1.AuthService.Login:input_type -> user.v1.LoginRequest
|
||||
2, // 1: user.v1.AuthService.SignUp:input_type -> user.v1.SignUpRequest
|
||||
4, // 2: user.v1.AuthService.Logout:input_type -> user.v1.LogoutRequest
|
||||
6, // 3: user.v1.AuthService.GetPasskeyIDs:input_type -> user.v1.GetPasskeyIDsRequest
|
||||
8, // 4: user.v1.AuthService.BeginPasskeyLogin:input_type -> user.v1.BeginPasskeyLoginRequest
|
||||
10, // 5: user.v1.AuthService.FinishPasskeyLogin:input_type -> user.v1.FinishPasskeyLoginRequest
|
||||
1, // 6: user.v1.AuthService.Login:output_type -> user.v1.LoginResponse
|
||||
3, // 7: user.v1.AuthService.SignUp:output_type -> user.v1.SignUpResponse
|
||||
5, // 8: user.v1.AuthService.Logout:output_type -> user.v1.LogoutResponse
|
||||
7, // 9: user.v1.AuthService.GetPasskeyIDs:output_type -> user.v1.GetPasskeyIDsResponse
|
||||
9, // 10: user.v1.AuthService.BeginPasskeyLogin:output_type -> user.v1.BeginPasskeyLoginResponse
|
||||
11, // 11: user.v1.AuthService.FinishPasskeyLogin:output_type -> user.v1.FinishPasskeyLoginResponse
|
||||
6, // [6:12] is the sub-list for method output_type
|
||||
0, // [0:6] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_user_v1_auth_proto_init() }
|
||||
@ -605,7 +654,7 @@ func file_user_v1_auth_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_v1_auth_proto_rawDesc), len(file_user_v1_auth_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 10,
|
||||
NumMessages: 12,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
@ -457,28 +457,26 @@ func (x *UpdateProfilePictureResponse) GetUser() *User {
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreatePasskeyRequest struct {
|
||||
type BeginPasskeyRegistrationRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreatePasskeyRequest) Reset() {
|
||||
*x = CreatePasskeyRequest{}
|
||||
func (x *BeginPasskeyRegistrationRequest) Reset() {
|
||||
*x = BeginPasskeyRegistrationRequest{}
|
||||
mi := &file_user_v1_user_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CreatePasskeyRequest) String() string {
|
||||
func (x *BeginPasskeyRegistrationRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreatePasskeyRequest) ProtoMessage() {}
|
||||
func (*BeginPasskeyRegistrationRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CreatePasskeyRequest) ProtoReflect() protoreflect.Message {
|
||||
func (x *BeginPasskeyRegistrationRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_user_proto_msgTypes[9]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -490,45 +488,31 @@ func (x *CreatePasskeyRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CreatePasskeyRequest.ProtoReflect.Descriptor instead.
|
||||
func (*CreatePasskeyRequest) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use BeginPasskeyRegistrationRequest.ProtoReflect.Descriptor instead.
|
||||
func (*BeginPasskeyRegistrationRequest) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_user_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *CreatePasskeyRequest) GetId() string {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *CreatePasskeyRequest) GetPublicKey() []byte {
|
||||
if x != nil {
|
||||
return x.PublicKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreatePasskeyResponse struct {
|
||||
type BeginPasskeyRegistrationResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CreatePasskeyResponse) Reset() {
|
||||
*x = CreatePasskeyResponse{}
|
||||
func (x *BeginPasskeyRegistrationResponse) Reset() {
|
||||
*x = BeginPasskeyRegistrationResponse{}
|
||||
mi := &file_user_v1_user_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CreatePasskeyResponse) String() string {
|
||||
func (x *BeginPasskeyRegistrationResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreatePasskeyResponse) ProtoMessage() {}
|
||||
func (*BeginPasskeyRegistrationResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CreatePasskeyResponse) ProtoReflect() protoreflect.Message {
|
||||
func (x *BeginPasskeyRegistrationResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_user_proto_msgTypes[10]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -540,11 +524,83 @@ func (x *CreatePasskeyResponse) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CreatePasskeyResponse.ProtoReflect.Descriptor instead.
|
||||
func (*CreatePasskeyResponse) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use BeginPasskeyRegistrationResponse.ProtoReflect.Descriptor instead.
|
||||
func (*BeginPasskeyRegistrationResponse) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_user_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
type FinishPasskeyRegistrationRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyRegistrationRequest) Reset() {
|
||||
*x = FinishPasskeyRegistrationRequest{}
|
||||
mi := &file_user_v1_user_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyRegistrationRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FinishPasskeyRegistrationRequest) ProtoMessage() {}
|
||||
|
||||
func (x *FinishPasskeyRegistrationRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_user_proto_msgTypes[11]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FinishPasskeyRegistrationRequest.ProtoReflect.Descriptor instead.
|
||||
func (*FinishPasskeyRegistrationRequest) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_user_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
type FinishPasskeyRegistrationResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyRegistrationResponse) Reset() {
|
||||
*x = FinishPasskeyRegistrationResponse{}
|
||||
mi := &file_user_v1_user_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *FinishPasskeyRegistrationResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FinishPasskeyRegistrationResponse) ProtoMessage() {}
|
||||
|
||||
func (x *FinishPasskeyRegistrationResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_user_v1_user_proto_msgTypes[12]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FinishPasskeyRegistrationResponse.ProtoReflect.Descriptor instead.
|
||||
func (*FinishPasskeyRegistrationResponse) Descriptor() ([]byte, []int) {
|
||||
return file_user_v1_user_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
var File_user_v1_user_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_user_v1_user_proto_rawDesc = string([]byte{
|
||||
@ -591,13 +647,16 @@ var file_user_v1_user_proto_rawDesc = string([]byte{
|
||||
0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73,
|
||||
0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x45, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22,
|
||||
0x17, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa1, 0x03, 0x0a, 0x0b, 0x55, 0x73, 0x65,
|
||||
0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x21, 0x0a, 0x1f, 0x42, 0x65, 0x67, 0x69,
|
||||
0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x20, 0x42,
|
||||
0x65, 0x67, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x67, 0x69, 0x73,
|
||||
0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x22, 0x0a, 0x20, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79,
|
||||
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x22, 0x23, 0x0a, 0x21, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73,
|
||||
0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb8, 0x04, 0x0a, 0x0b, 0x55, 0x73, 0x65,
|
||||
0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55,
|
||||
0x73, 0x65, 0x72, 0x12, 0x17, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x75,
|
||||
@ -618,23 +677,32 @@ var file_user_v1_user_proto_rawDesc = string([]byte{
|
||||
0x69, 0x6c, 0x65, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x25, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x69, 0x63, 0x74, 0x75, 0x72, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0d, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x12, 0x1d, 0x2e, 0x75, 0x73,
|
||||
0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73,
|
||||
0x6b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x75, 0x73, 0x65,
|
||||
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x6b,
|
||||
0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9d, 0x01, 0x0a,
|
||||
0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x55, 0x73,
|
||||
0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x70, 0x6f, 0x74, 0x64, 0x65, 0x6d, 0x6f, 0x34, 0x2f,
|
||||
0x74, 0x72, 0x65, 0x76, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76,
|
||||
0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56,
|
||||
0x31, 0xca, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x13, 0x55, 0x73,
|
||||
0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0xea, 0x02, 0x08, 0x55, 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x18, 0x42, 0x65,
|
||||
0x67, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x67,
|
||||
0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x29, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x67, 0x69, 0x6e,
|
||||
0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a,
|
||||
0x19, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65,
|
||||
0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x2e, 0x75, 0x73, 0x65,
|
||||
0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b,
|
||||
0x65, 0x79, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x50, 0x61, 0x73, 0x73, 0x6b, 0x65, 0x79, 0x52, 0x65, 0x67,
|
||||
0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x00, 0x42, 0x9d, 0x01, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x73, 0x65, 0x72,
|
||||
0x2e, 0x76, 0x31, 0x42, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
|
||||
0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x70, 0x6f,
|
||||
0x74, 0x64, 0x65, 0x6d, 0x6f, 0x34, 0x2f, 0x74, 0x72, 0x65, 0x76, 0x73, 0x74, 0x61, 0x63, 0x6b,
|
||||
0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76,
|
||||
0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02,
|
||||
0x07, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x07, 0x55, 0x73, 0x65, 0x72, 0x5c,
|
||||
0x56, 0x31, 0xe2, 0x02, 0x13, 0x55, 0x73, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42,
|
||||
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x08, 0x55, 0x73, 0x65, 0x72, 0x3a,
|
||||
0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
})
|
||||
|
||||
var (
|
||||
@ -649,19 +717,21 @@ func file_user_v1_user_proto_rawDescGZIP() []byte {
|
||||
return file_user_v1_user_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_user_v1_user_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_user_v1_user_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
|
||||
var file_user_v1_user_proto_goTypes = []any{
|
||||
(*User)(nil), // 0: user.v1.User
|
||||
(*GetUserRequest)(nil), // 1: user.v1.GetUserRequest
|
||||
(*GetUserResponse)(nil), // 2: user.v1.GetUserResponse
|
||||
(*UpdatePasswordRequest)(nil), // 3: user.v1.UpdatePasswordRequest
|
||||
(*UpdatePasswordResponse)(nil), // 4: user.v1.UpdatePasswordResponse
|
||||
(*GetAPIKeyRequest)(nil), // 5: user.v1.GetAPIKeyRequest
|
||||
(*GetAPIKeyResponse)(nil), // 6: user.v1.GetAPIKeyResponse
|
||||
(*UpdateProfilePictureRequest)(nil), // 7: user.v1.UpdateProfilePictureRequest
|
||||
(*UpdateProfilePictureResponse)(nil), // 8: user.v1.UpdateProfilePictureResponse
|
||||
(*CreatePasskeyRequest)(nil), // 9: user.v1.CreatePasskeyRequest
|
||||
(*CreatePasskeyResponse)(nil), // 10: user.v1.CreatePasskeyResponse
|
||||
(*User)(nil), // 0: user.v1.User
|
||||
(*GetUserRequest)(nil), // 1: user.v1.GetUserRequest
|
||||
(*GetUserResponse)(nil), // 2: user.v1.GetUserResponse
|
||||
(*UpdatePasswordRequest)(nil), // 3: user.v1.UpdatePasswordRequest
|
||||
(*UpdatePasswordResponse)(nil), // 4: user.v1.UpdatePasswordResponse
|
||||
(*GetAPIKeyRequest)(nil), // 5: user.v1.GetAPIKeyRequest
|
||||
(*GetAPIKeyResponse)(nil), // 6: user.v1.GetAPIKeyResponse
|
||||
(*UpdateProfilePictureRequest)(nil), // 7: user.v1.UpdateProfilePictureRequest
|
||||
(*UpdateProfilePictureResponse)(nil), // 8: user.v1.UpdateProfilePictureResponse
|
||||
(*BeginPasskeyRegistrationRequest)(nil), // 9: user.v1.BeginPasskeyRegistrationRequest
|
||||
(*BeginPasskeyRegistrationResponse)(nil), // 10: user.v1.BeginPasskeyRegistrationResponse
|
||||
(*FinishPasskeyRegistrationRequest)(nil), // 11: user.v1.FinishPasskeyRegistrationRequest
|
||||
(*FinishPasskeyRegistrationResponse)(nil), // 12: user.v1.FinishPasskeyRegistrationResponse
|
||||
}
|
||||
var file_user_v1_user_proto_depIdxs = []int32{
|
||||
0, // 0: user.v1.GetUserResponse.user:type_name -> user.v1.User
|
||||
@ -671,14 +741,16 @@ var file_user_v1_user_proto_depIdxs = []int32{
|
||||
3, // 4: user.v1.UserService.UpdatePassword:input_type -> user.v1.UpdatePasswordRequest
|
||||
5, // 5: user.v1.UserService.GetAPIKey:input_type -> user.v1.GetAPIKeyRequest
|
||||
7, // 6: user.v1.UserService.UpdateProfilePicture:input_type -> user.v1.UpdateProfilePictureRequest
|
||||
9, // 7: user.v1.UserService.CreatePasskey:input_type -> user.v1.CreatePasskeyRequest
|
||||
2, // 8: user.v1.UserService.GetUser:output_type -> user.v1.GetUserResponse
|
||||
4, // 9: user.v1.UserService.UpdatePassword:output_type -> user.v1.UpdatePasswordResponse
|
||||
6, // 10: user.v1.UserService.GetAPIKey:output_type -> user.v1.GetAPIKeyResponse
|
||||
8, // 11: user.v1.UserService.UpdateProfilePicture:output_type -> user.v1.UpdateProfilePictureResponse
|
||||
10, // 12: user.v1.UserService.CreatePasskey:output_type -> user.v1.CreatePasskeyResponse
|
||||
8, // [8:13] is the sub-list for method output_type
|
||||
3, // [3:8] is the sub-list for method input_type
|
||||
9, // 7: user.v1.UserService.BeginPasskeyRegistration:input_type -> user.v1.BeginPasskeyRegistrationRequest
|
||||
11, // 8: user.v1.UserService.FinishPasskeyRegistration:input_type -> user.v1.FinishPasskeyRegistrationRequest
|
||||
2, // 9: user.v1.UserService.GetUser:output_type -> user.v1.GetUserResponse
|
||||
4, // 10: user.v1.UserService.UpdatePassword:output_type -> user.v1.UpdatePasswordResponse
|
||||
6, // 11: user.v1.UserService.GetAPIKey:output_type -> user.v1.GetAPIKeyResponse
|
||||
8, // 12: user.v1.UserService.UpdateProfilePicture:output_type -> user.v1.UpdateProfilePictureResponse
|
||||
10, // 13: user.v1.UserService.BeginPasskeyRegistration:output_type -> user.v1.BeginPasskeyRegistrationResponse
|
||||
12, // 14: user.v1.UserService.FinishPasskeyRegistration:output_type -> user.v1.FinishPasskeyRegistrationResponse
|
||||
9, // [9:15] is the sub-list for method output_type
|
||||
3, // [3:9] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
@ -696,7 +768,7 @@ func file_user_v1_user_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_v1_user_proto_rawDesc), len(file_user_v1_user_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 11,
|
||||
NumMessages: 13,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
@ -42,9 +42,12 @@ const (
|
||||
// AuthServiceGetPasskeyIDsProcedure is the fully-qualified name of the AuthService's GetPasskeyIDs
|
||||
// RPC.
|
||||
AuthServiceGetPasskeyIDsProcedure = "/user.v1.AuthService/GetPasskeyIDs"
|
||||
// AuthServicePasskeyLoginProcedure is the fully-qualified name of the AuthService's PasskeyLogin
|
||||
// RPC.
|
||||
AuthServicePasskeyLoginProcedure = "/user.v1.AuthService/PasskeyLogin"
|
||||
// AuthServiceBeginPasskeyLoginProcedure is the fully-qualified name of the AuthService's
|
||||
// BeginPasskeyLogin RPC.
|
||||
AuthServiceBeginPasskeyLoginProcedure = "/user.v1.AuthService/BeginPasskeyLogin"
|
||||
// AuthServiceFinishPasskeyLoginProcedure is the fully-qualified name of the AuthService's
|
||||
// FinishPasskeyLogin RPC.
|
||||
AuthServiceFinishPasskeyLoginProcedure = "/user.v1.AuthService/FinishPasskeyLogin"
|
||||
)
|
||||
|
||||
// AuthServiceClient is a client for the user.v1.AuthService service.
|
||||
@ -53,7 +56,8 @@ type AuthServiceClient interface {
|
||||
SignUp(context.Context, *connect.Request[v1.SignUpRequest]) (*connect.Response[v1.SignUpResponse], error)
|
||||
Logout(context.Context, *connect.Request[v1.LogoutRequest]) (*connect.Response[v1.LogoutResponse], error)
|
||||
GetPasskeyIDs(context.Context, *connect.Request[v1.GetPasskeyIDsRequest]) (*connect.Response[v1.GetPasskeyIDsResponse], error)
|
||||
PasskeyLogin(context.Context, *connect.Request[v1.PasskeyLoginRequest]) (*connect.Response[v1.PasskeyLoginResponse], error)
|
||||
BeginPasskeyLogin(context.Context, *connect.Request[v1.BeginPasskeyLoginRequest]) (*connect.Response[v1.BeginPasskeyLoginResponse], error)
|
||||
FinishPasskeyLogin(context.Context, *connect.Request[v1.FinishPasskeyLoginRequest]) (*connect.Response[v1.FinishPasskeyLoginResponse], error)
|
||||
}
|
||||
|
||||
// NewAuthServiceClient constructs a client for the user.v1.AuthService service. By default, it uses
|
||||
@ -91,10 +95,16 @@ func NewAuthServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
|
||||
connect.WithSchema(authServiceMethods.ByName("GetPasskeyIDs")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
passkeyLogin: connect.NewClient[v1.PasskeyLoginRequest, v1.PasskeyLoginResponse](
|
||||
beginPasskeyLogin: connect.NewClient[v1.BeginPasskeyLoginRequest, v1.BeginPasskeyLoginResponse](
|
||||
httpClient,
|
||||
baseURL+AuthServicePasskeyLoginProcedure,
|
||||
connect.WithSchema(authServiceMethods.ByName("PasskeyLogin")),
|
||||
baseURL+AuthServiceBeginPasskeyLoginProcedure,
|
||||
connect.WithSchema(authServiceMethods.ByName("BeginPasskeyLogin")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
finishPasskeyLogin: connect.NewClient[v1.FinishPasskeyLoginRequest, v1.FinishPasskeyLoginResponse](
|
||||
httpClient,
|
||||
baseURL+AuthServiceFinishPasskeyLoginProcedure,
|
||||
connect.WithSchema(authServiceMethods.ByName("FinishPasskeyLogin")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
@ -102,11 +112,12 @@ func NewAuthServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
|
||||
|
||||
// authServiceClient implements AuthServiceClient.
|
||||
type authServiceClient struct {
|
||||
login *connect.Client[v1.LoginRequest, v1.LoginResponse]
|
||||
signUp *connect.Client[v1.SignUpRequest, v1.SignUpResponse]
|
||||
logout *connect.Client[v1.LogoutRequest, v1.LogoutResponse]
|
||||
getPasskeyIDs *connect.Client[v1.GetPasskeyIDsRequest, v1.GetPasskeyIDsResponse]
|
||||
passkeyLogin *connect.Client[v1.PasskeyLoginRequest, v1.PasskeyLoginResponse]
|
||||
login *connect.Client[v1.LoginRequest, v1.LoginResponse]
|
||||
signUp *connect.Client[v1.SignUpRequest, v1.SignUpResponse]
|
||||
logout *connect.Client[v1.LogoutRequest, v1.LogoutResponse]
|
||||
getPasskeyIDs *connect.Client[v1.GetPasskeyIDsRequest, v1.GetPasskeyIDsResponse]
|
||||
beginPasskeyLogin *connect.Client[v1.BeginPasskeyLoginRequest, v1.BeginPasskeyLoginResponse]
|
||||
finishPasskeyLogin *connect.Client[v1.FinishPasskeyLoginRequest, v1.FinishPasskeyLoginResponse]
|
||||
}
|
||||
|
||||
// Login calls user.v1.AuthService.Login.
|
||||
@ -129,9 +140,14 @@ func (c *authServiceClient) GetPasskeyIDs(ctx context.Context, req *connect.Requ
|
||||
return c.getPasskeyIDs.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// PasskeyLogin calls user.v1.AuthService.PasskeyLogin.
|
||||
func (c *authServiceClient) PasskeyLogin(ctx context.Context, req *connect.Request[v1.PasskeyLoginRequest]) (*connect.Response[v1.PasskeyLoginResponse], error) {
|
||||
return c.passkeyLogin.CallUnary(ctx, req)
|
||||
// BeginPasskeyLogin calls user.v1.AuthService.BeginPasskeyLogin.
|
||||
func (c *authServiceClient) BeginPasskeyLogin(ctx context.Context, req *connect.Request[v1.BeginPasskeyLoginRequest]) (*connect.Response[v1.BeginPasskeyLoginResponse], error) {
|
||||
return c.beginPasskeyLogin.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// FinishPasskeyLogin calls user.v1.AuthService.FinishPasskeyLogin.
|
||||
func (c *authServiceClient) FinishPasskeyLogin(ctx context.Context, req *connect.Request[v1.FinishPasskeyLoginRequest]) (*connect.Response[v1.FinishPasskeyLoginResponse], error) {
|
||||
return c.finishPasskeyLogin.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// AuthServiceHandler is an implementation of the user.v1.AuthService service.
|
||||
@ -140,7 +156,8 @@ type AuthServiceHandler interface {
|
||||
SignUp(context.Context, *connect.Request[v1.SignUpRequest]) (*connect.Response[v1.SignUpResponse], error)
|
||||
Logout(context.Context, *connect.Request[v1.LogoutRequest]) (*connect.Response[v1.LogoutResponse], error)
|
||||
GetPasskeyIDs(context.Context, *connect.Request[v1.GetPasskeyIDsRequest]) (*connect.Response[v1.GetPasskeyIDsResponse], error)
|
||||
PasskeyLogin(context.Context, *connect.Request[v1.PasskeyLoginRequest]) (*connect.Response[v1.PasskeyLoginResponse], error)
|
||||
BeginPasskeyLogin(context.Context, *connect.Request[v1.BeginPasskeyLoginRequest]) (*connect.Response[v1.BeginPasskeyLoginResponse], error)
|
||||
FinishPasskeyLogin(context.Context, *connect.Request[v1.FinishPasskeyLoginRequest]) (*connect.Response[v1.FinishPasskeyLoginResponse], error)
|
||||
}
|
||||
|
||||
// NewAuthServiceHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
@ -174,10 +191,16 @@ func NewAuthServiceHandler(svc AuthServiceHandler, opts ...connect.HandlerOption
|
||||
connect.WithSchema(authServiceMethods.ByName("GetPasskeyIDs")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
authServicePasskeyLoginHandler := connect.NewUnaryHandler(
|
||||
AuthServicePasskeyLoginProcedure,
|
||||
svc.PasskeyLogin,
|
||||
connect.WithSchema(authServiceMethods.ByName("PasskeyLogin")),
|
||||
authServiceBeginPasskeyLoginHandler := connect.NewUnaryHandler(
|
||||
AuthServiceBeginPasskeyLoginProcedure,
|
||||
svc.BeginPasskeyLogin,
|
||||
connect.WithSchema(authServiceMethods.ByName("BeginPasskeyLogin")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
authServiceFinishPasskeyLoginHandler := connect.NewUnaryHandler(
|
||||
AuthServiceFinishPasskeyLoginProcedure,
|
||||
svc.FinishPasskeyLogin,
|
||||
connect.WithSchema(authServiceMethods.ByName("FinishPasskeyLogin")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/user.v1.AuthService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@ -190,8 +213,10 @@ func NewAuthServiceHandler(svc AuthServiceHandler, opts ...connect.HandlerOption
|
||||
authServiceLogoutHandler.ServeHTTP(w, r)
|
||||
case AuthServiceGetPasskeyIDsProcedure:
|
||||
authServiceGetPasskeyIDsHandler.ServeHTTP(w, r)
|
||||
case AuthServicePasskeyLoginProcedure:
|
||||
authServicePasskeyLoginHandler.ServeHTTP(w, r)
|
||||
case AuthServiceBeginPasskeyLoginProcedure:
|
||||
authServiceBeginPasskeyLoginHandler.ServeHTTP(w, r)
|
||||
case AuthServiceFinishPasskeyLoginProcedure:
|
||||
authServiceFinishPasskeyLoginHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
@ -217,6 +242,10 @@ func (UnimplementedAuthServiceHandler) GetPasskeyIDs(context.Context, *connect.R
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.AuthService.GetPasskeyIDs is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAuthServiceHandler) PasskeyLogin(context.Context, *connect.Request[v1.PasskeyLoginRequest]) (*connect.Response[v1.PasskeyLoginResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.AuthService.PasskeyLogin is not implemented"))
|
||||
func (UnimplementedAuthServiceHandler) BeginPasskeyLogin(context.Context, *connect.Request[v1.BeginPasskeyLoginRequest]) (*connect.Response[v1.BeginPasskeyLoginResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.AuthService.BeginPasskeyLogin is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAuthServiceHandler) FinishPasskeyLogin(context.Context, *connect.Request[v1.FinishPasskeyLoginRequest]) (*connect.Response[v1.FinishPasskeyLoginResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.AuthService.FinishPasskeyLogin is not implemented"))
|
||||
}
|
||||
|
@ -43,9 +43,12 @@ const (
|
||||
// UserServiceUpdateProfilePictureProcedure is the fully-qualified name of the UserService's
|
||||
// UpdateProfilePicture RPC.
|
||||
UserServiceUpdateProfilePictureProcedure = "/user.v1.UserService/UpdateProfilePicture"
|
||||
// UserServiceCreatePasskeyProcedure is the fully-qualified name of the UserService's CreatePasskey
|
||||
// RPC.
|
||||
UserServiceCreatePasskeyProcedure = "/user.v1.UserService/CreatePasskey"
|
||||
// UserServiceBeginPasskeyRegistrationProcedure is the fully-qualified name of the UserService's
|
||||
// BeginPasskeyRegistration RPC.
|
||||
UserServiceBeginPasskeyRegistrationProcedure = "/user.v1.UserService/BeginPasskeyRegistration"
|
||||
// UserServiceFinishPasskeyRegistrationProcedure is the fully-qualified name of the UserService's
|
||||
// FinishPasskeyRegistration RPC.
|
||||
UserServiceFinishPasskeyRegistrationProcedure = "/user.v1.UserService/FinishPasskeyRegistration"
|
||||
)
|
||||
|
||||
// UserServiceClient is a client for the user.v1.UserService service.
|
||||
@ -54,7 +57,8 @@ type UserServiceClient interface {
|
||||
UpdatePassword(context.Context, *connect.Request[v1.UpdatePasswordRequest]) (*connect.Response[v1.UpdatePasswordResponse], error)
|
||||
GetAPIKey(context.Context, *connect.Request[v1.GetAPIKeyRequest]) (*connect.Response[v1.GetAPIKeyResponse], error)
|
||||
UpdateProfilePicture(context.Context, *connect.Request[v1.UpdateProfilePictureRequest]) (*connect.Response[v1.UpdateProfilePictureResponse], error)
|
||||
CreatePasskey(context.Context, *connect.Request[v1.CreatePasskeyRequest]) (*connect.Response[v1.CreatePasskeyResponse], error)
|
||||
BeginPasskeyRegistration(context.Context, *connect.Request[v1.BeginPasskeyRegistrationRequest]) (*connect.Response[v1.BeginPasskeyRegistrationResponse], error)
|
||||
FinishPasskeyRegistration(context.Context, *connect.Request[v1.FinishPasskeyRegistrationRequest]) (*connect.Response[v1.FinishPasskeyRegistrationResponse], error)
|
||||
}
|
||||
|
||||
// NewUserServiceClient constructs a client for the user.v1.UserService service. By default, it uses
|
||||
@ -92,10 +96,16 @@ func NewUserServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateProfilePicture")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createPasskey: connect.NewClient[v1.CreatePasskeyRequest, v1.CreatePasskeyResponse](
|
||||
beginPasskeyRegistration: connect.NewClient[v1.BeginPasskeyRegistrationRequest, v1.BeginPasskeyRegistrationResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceCreatePasskeyProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreatePasskey")),
|
||||
baseURL+UserServiceBeginPasskeyRegistrationProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("BeginPasskeyRegistration")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
finishPasskeyRegistration: connect.NewClient[v1.FinishPasskeyRegistrationRequest, v1.FinishPasskeyRegistrationResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceFinishPasskeyRegistrationProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("FinishPasskeyRegistration")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
@ -103,11 +113,12 @@ func NewUserServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
|
||||
|
||||
// userServiceClient implements UserServiceClient.
|
||||
type userServiceClient struct {
|
||||
getUser *connect.Client[v1.GetUserRequest, v1.GetUserResponse]
|
||||
updatePassword *connect.Client[v1.UpdatePasswordRequest, v1.UpdatePasswordResponse]
|
||||
getAPIKey *connect.Client[v1.GetAPIKeyRequest, v1.GetAPIKeyResponse]
|
||||
updateProfilePicture *connect.Client[v1.UpdateProfilePictureRequest, v1.UpdateProfilePictureResponse]
|
||||
createPasskey *connect.Client[v1.CreatePasskeyRequest, v1.CreatePasskeyResponse]
|
||||
getUser *connect.Client[v1.GetUserRequest, v1.GetUserResponse]
|
||||
updatePassword *connect.Client[v1.UpdatePasswordRequest, v1.UpdatePasswordResponse]
|
||||
getAPIKey *connect.Client[v1.GetAPIKeyRequest, v1.GetAPIKeyResponse]
|
||||
updateProfilePicture *connect.Client[v1.UpdateProfilePictureRequest, v1.UpdateProfilePictureResponse]
|
||||
beginPasskeyRegistration *connect.Client[v1.BeginPasskeyRegistrationRequest, v1.BeginPasskeyRegistrationResponse]
|
||||
finishPasskeyRegistration *connect.Client[v1.FinishPasskeyRegistrationRequest, v1.FinishPasskeyRegistrationResponse]
|
||||
}
|
||||
|
||||
// GetUser calls user.v1.UserService.GetUser.
|
||||
@ -130,9 +141,14 @@ func (c *userServiceClient) UpdateProfilePicture(ctx context.Context, req *conne
|
||||
return c.updateProfilePicture.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreatePasskey calls user.v1.UserService.CreatePasskey.
|
||||
func (c *userServiceClient) CreatePasskey(ctx context.Context, req *connect.Request[v1.CreatePasskeyRequest]) (*connect.Response[v1.CreatePasskeyResponse], error) {
|
||||
return c.createPasskey.CallUnary(ctx, req)
|
||||
// BeginPasskeyRegistration calls user.v1.UserService.BeginPasskeyRegistration.
|
||||
func (c *userServiceClient) BeginPasskeyRegistration(ctx context.Context, req *connect.Request[v1.BeginPasskeyRegistrationRequest]) (*connect.Response[v1.BeginPasskeyRegistrationResponse], error) {
|
||||
return c.beginPasskeyRegistration.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// FinishPasskeyRegistration calls user.v1.UserService.FinishPasskeyRegistration.
|
||||
func (c *userServiceClient) FinishPasskeyRegistration(ctx context.Context, req *connect.Request[v1.FinishPasskeyRegistrationRequest]) (*connect.Response[v1.FinishPasskeyRegistrationResponse], error) {
|
||||
return c.finishPasskeyRegistration.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UserServiceHandler is an implementation of the user.v1.UserService service.
|
||||
@ -141,7 +157,8 @@ type UserServiceHandler interface {
|
||||
UpdatePassword(context.Context, *connect.Request[v1.UpdatePasswordRequest]) (*connect.Response[v1.UpdatePasswordResponse], error)
|
||||
GetAPIKey(context.Context, *connect.Request[v1.GetAPIKeyRequest]) (*connect.Response[v1.GetAPIKeyResponse], error)
|
||||
UpdateProfilePicture(context.Context, *connect.Request[v1.UpdateProfilePictureRequest]) (*connect.Response[v1.UpdateProfilePictureResponse], error)
|
||||
CreatePasskey(context.Context, *connect.Request[v1.CreatePasskeyRequest]) (*connect.Response[v1.CreatePasskeyResponse], error)
|
||||
BeginPasskeyRegistration(context.Context, *connect.Request[v1.BeginPasskeyRegistrationRequest]) (*connect.Response[v1.BeginPasskeyRegistrationResponse], error)
|
||||
FinishPasskeyRegistration(context.Context, *connect.Request[v1.FinishPasskeyRegistrationRequest]) (*connect.Response[v1.FinishPasskeyRegistrationResponse], error)
|
||||
}
|
||||
|
||||
// NewUserServiceHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
@ -175,10 +192,16 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateProfilePicture")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceCreatePasskeyHandler := connect.NewUnaryHandler(
|
||||
UserServiceCreatePasskeyProcedure,
|
||||
svc.CreatePasskey,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreatePasskey")),
|
||||
userServiceBeginPasskeyRegistrationHandler := connect.NewUnaryHandler(
|
||||
UserServiceBeginPasskeyRegistrationProcedure,
|
||||
svc.BeginPasskeyRegistration,
|
||||
connect.WithSchema(userServiceMethods.ByName("BeginPasskeyRegistration")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceFinishPasskeyRegistrationHandler := connect.NewUnaryHandler(
|
||||
UserServiceFinishPasskeyRegistrationProcedure,
|
||||
svc.FinishPasskeyRegistration,
|
||||
connect.WithSchema(userServiceMethods.ByName("FinishPasskeyRegistration")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/user.v1.UserService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@ -191,8 +214,10 @@ func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption
|
||||
userServiceGetAPIKeyHandler.ServeHTTP(w, r)
|
||||
case UserServiceUpdateProfilePictureProcedure:
|
||||
userServiceUpdateProfilePictureHandler.ServeHTTP(w, r)
|
||||
case UserServiceCreatePasskeyProcedure:
|
||||
userServiceCreatePasskeyHandler.ServeHTTP(w, r)
|
||||
case UserServiceBeginPasskeyRegistrationProcedure:
|
||||
userServiceBeginPasskeyRegistrationHandler.ServeHTTP(w, r)
|
||||
case UserServiceFinishPasskeyRegistrationProcedure:
|
||||
userServiceFinishPasskeyRegistrationHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
@ -218,6 +243,10 @@ func (UnimplementedUserServiceHandler) UpdateProfilePicture(context.Context, *co
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.UserService.UpdateProfilePicture is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) CreatePasskey(context.Context, *connect.Request[v1.CreatePasskeyRequest]) (*connect.Response[v1.CreatePasskeyResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.UserService.CreatePasskey is not implemented"))
|
||||
func (UnimplementedUserServiceHandler) BeginPasskeyRegistration(context.Context, *connect.Request[v1.BeginPasskeyRegistrationRequest]) (*connect.Response[v1.BeginPasskeyRegistrationResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.UserService.BeginPasskeyRegistration is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) FinishPasskeyRegistration(context.Context, *connect.Request[v1.FinishPasskeyRegistrationRequest]) (*connect.Response[v1.FinishPasskeyRegistrationResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("user.v1.UserService.FinishPasskeyRegistration is not implemented"))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user