Commit: Bulk unfinished work
This commit is contained in:
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@@ -0,0 +1 @@
|
||||
.env
|
||||
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Environment-dependent path to Maven home directory
|
||||
/mavenHomeManager.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
9
.idea/golang.iml
generated
Normal file
9
.idea/golang.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/golang.iml" filepath="$PROJECT_DIR$/.idea/golang.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@@ -4,12 +4,13 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Launch Package",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${fileDirname}",
|
||||
"program": "${workspaceFolder}/cmd/api",
|
||||
"envFile": "/home/kocoder/src/js/golang/.env"
|
||||
}
|
||||
]
|
||||
|
||||
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM golang:1.25.4
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
COPY . ./
|
||||
|
||||
RUN CGO_ENABLED=1 GOOS=linux go build -o /backend ./cmd/api/main.go
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["/backend"]
|
||||
25
buf.gen.yaml
Normal file
25
buf.gen.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
version: v2
|
||||
plugins:
|
||||
- local: protoc-gen-go
|
||||
out: gen
|
||||
opt: paths=source_relative
|
||||
- local: protoc-gen-connect-go
|
||||
out: gen
|
||||
opt:
|
||||
- paths=source_relative
|
||||
- simple
|
||||
- local: protoc-gen-es
|
||||
out: ../query/src/gen
|
||||
include_imports: true
|
||||
opt: target=ts
|
||||
- local: protoc-gen-connect-query
|
||||
out: "../query/src/gen"
|
||||
opt: target=ts
|
||||
managed:
|
||||
enabled: true
|
||||
override:
|
||||
- file_option: go_package_prefix
|
||||
value: git.kocoder.xyz/kocoded/vt/gen
|
||||
disable:
|
||||
- file_option: go_package
|
||||
module: buf.build/bufbuild/protovalidate
|
||||
8
buf.yaml
Normal file
8
buf.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml
|
||||
version: v2
|
||||
lint:
|
||||
use:
|
||||
- STANDARD
|
||||
breaking:
|
||||
use:
|
||||
- FILE
|
||||
139
cmd/api/main.go
139
cmd/api/main.go
@@ -1,63 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/routers"
|
||||
kfx "git.kocoder.xyz/kocoded/vt/fx"
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces"
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces/stores"
|
||||
"git.kocoder.xyz/kocoded/vt/integration"
|
||||
"git.kocoder.xyz/kocoded/vt/integration/mailing"
|
||||
"git.kocoder.xyz/kocoded/vt/interceptors"
|
||||
"git.kocoder.xyz/kocoded/vt/repositories"
|
||||
mandantv1 "git.kocoder.xyz/kocoded/vt/routers/mandant/v1"
|
||||
messagebusv1 "git.kocoder.xyz/kocoded/vt/routers/messagebus/v1"
|
||||
projectv1 "git.kocoder.xyz/kocoded/vt/routers/project/v1"
|
||||
todov1 "git.kocoder.xyz/kocoded/vt/routers/todo/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/joho/godotenv"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
logger.Error("Error Loading Environment variables! ", "error", err)
|
||||
}
|
||||
|
||||
db := utils.SetupDatabase(os.Getenv("DB_DSN"), logger)
|
||||
cache, ok := utils.SetupCache(os.Getenv("VALKEY_HOST"), os.Getenv("VALKEY_PORT"), os.Getenv("VALKEY_USER"), os.Getenv("VALKEY_PASS"))
|
||||
if !ok {
|
||||
logger.Error("Configuring and connecting to Valkey failed!")
|
||||
}
|
||||
|
||||
appCtx := utils.Application{Logger: logger, DB: db, Client: cache}
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
utils.RegisterMiddlewares(app)
|
||||
|
||||
utils.CreateOIDCClient(context.Background(), app, appCtx)
|
||||
|
||||
routers.RegisterMandantRouter(app.Group("/v1/mandant"), appCtx)
|
||||
routers.RegisterAnsprechpartnerRouter(app.Group("/v1/ansprechpartner"), appCtx)
|
||||
routers.RegisterFirmaRouter(app.Group("/v1/firma"), appCtx)
|
||||
routers.RegisterProjectRouter(app.Group("/v1/projects"), appCtx)
|
||||
routers.RegisterUserRouter(app.Group("/v1/users"), appCtx)
|
||||
|
||||
app.Use("/ws", func(c *fiber.Ctx) error {
|
||||
if websocket.IsWebSocketUpgrade(c) {
|
||||
c.Locals("allowed", true)
|
||||
return c.Next()
|
||||
}
|
||||
return fiber.ErrUpgradeRequired
|
||||
})
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
go func() {
|
||||
time.Sleep(time.Second)
|
||||
}()
|
||||
|
||||
utils.MessageBus.AddConn(1, c)
|
||||
|
||||
}))
|
||||
|
||||
log.Fatalln(app.Listen(":3000"))
|
||||
func AsIntegration(f any) any {
|
||||
return fx.Annotate(
|
||||
f,
|
||||
fx.As(new(interfaces.BasicIntegration)),
|
||||
fx.ResultTags(`group:"integration"`),
|
||||
)
|
||||
}
|
||||
|
||||
func AsRoute(f any) any {
|
||||
return fx.Annotate(
|
||||
f,
|
||||
fx.As(new(kfx.Handler)),
|
||||
fx.ResultTags(`group:"connectRoute"`),
|
||||
)
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := godotenv.Load()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Error loading env vars... %v", err)
|
||||
}
|
||||
|
||||
fx.New(
|
||||
fx.Provide(
|
||||
kfx.NewHTTPServer,
|
||||
utils.NewReflector,
|
||||
utils.NewHealthchecker,
|
||||
|
||||
utils.NewDB,
|
||||
utils.NewCache,
|
||||
|
||||
utils.NewOIDCProvider,
|
||||
utils.NewOIDCVerifier,
|
||||
|
||||
fx.Annotate(repositories.NewSessionRepository, fx.As(new(stores.SessionStore))),
|
||||
fx.Annotate(repositories.NewInMemeoryMessageRepository, fx.As(new(stores.MessageStore))),
|
||||
interceptors.NewOIDCInterceptor,
|
||||
|
||||
AsIntegration(mailing.NewImapIntegration),
|
||||
fx.Annotate(
|
||||
integration.NewIntegrationHandler,
|
||||
fx.ParamTags(`group:"integration"`),
|
||||
),
|
||||
|
||||
kfx.NewOtelLoggerProvider,
|
||||
kfx.NewOtelMeterProvider,
|
||||
kfx.NewOtelTracerProvider,
|
||||
kfx.NewLogger,
|
||||
|
||||
AsRoute(utils.NewHealthCheckV1),
|
||||
|
||||
AsRoute(utils.NewReflectorV1),
|
||||
AsRoute(utils.NewReflectorV1Alpha1),
|
||||
|
||||
AsRoute(kfx.NewEchoHandler),
|
||||
|
||||
AsRoute(messagebusv1.NewMessagebusRoute),
|
||||
|
||||
AsRoute(projectv1.NewProjectRoute),
|
||||
AsRoute(todov1.NewTodoRoute),
|
||||
AsRoute(mandantv1.NewMandantRoute),
|
||||
|
||||
fx.Annotate(
|
||||
kfx.NewServeMux,
|
||||
fx.ParamTags(`group:"connectRoute"`),
|
||||
),
|
||||
),
|
||||
|
||||
fx.Invoke(func(*integration.IntegrationHandler) {}, kfx.SetupOTelSDK, func(*http.Server) {}),
|
||||
).Run()
|
||||
}
|
||||
|
||||
38
cmd/generate/main.go
Normal file
38
cmd/generate/main.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"github.com/joho/godotenv"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
slog.Error("Error Loading Environment variables! ", "error", err)
|
||||
}
|
||||
|
||||
db, err := gorm.Open(postgres.Open(os.Getenv("DB_DSN")), &gorm.Config{})
|
||||
if err != nil {
|
||||
slog.Error("Error connecting to the Database", "error", err)
|
||||
}
|
||||
|
||||
g := gen.NewGenerator(gen.Config{
|
||||
OutPath: "query",
|
||||
Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
|
||||
})
|
||||
|
||||
// gormdb, _ := gorm.Open(mysql.Open("root:@(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local"))
|
||||
g.UseDB(db) // reuse your gorm db
|
||||
|
||||
// Generate basic type-safe DAO API for struct `model.User` following conventions
|
||||
g.ApplyBasic(model.Mandant{}, model.User{}, model.Ansprechpartner{}, model.Dokument{}, model.Firma{}, model.Kalender{}, model.Kalendereintrag{}, model.Kostenstelle{}, model.Lager{}, model.Lagerplatz{}, model.Material{}, model.Nachricht{}, model.Projekt{}, model.Rechnung{}, model.Rechnungsposition{}, model.Scanobject{}, model.User{}, model.Zahlung{}, model.FirmaAnsprechpartner{}, model.Task{})
|
||||
|
||||
// Generate the code
|
||||
g.Execute()
|
||||
}
|
||||
22
docker-compose.yaml
Normal file
22
docker-compose.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
services:
|
||||
backend:
|
||||
image: "git.kocoder.xyz/kocoded/vt-be"
|
||||
build: .
|
||||
environment:
|
||||
- CLIENT_ID="golang-vt-backend"
|
||||
- CLIENT_SECRET="awumIoacqNmwKTxRilQSM9cDmA7xA0j0"
|
||||
- BACKEND_URI="http://10.8.0.3:3000"
|
||||
- FRONTEND_URI="http://10.8.0.3:3001"
|
||||
|
||||
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://otel.kocoder.xyz/v1/traces"
|
||||
- OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="https://otel.kocoder.xyz/v1/metrics"
|
||||
- OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="https://otel.kocoder.xyz/v1/logs"
|
||||
|
||||
- DB_DSN="host=10.1.0.2 user=vt password=20a1c7809cd065bc5afe7c36fde26abf625316c8a83cc841b435c9acf3619b1f dbname=vt port=5432 sslmode=prefer TimeZone=Europe/Vienna"
|
||||
|
||||
- VALKEY_HOST="10.8.0.1"
|
||||
- VALKEY_PORT="6379"
|
||||
- VALKEY_USER="default"
|
||||
- VALKEY_PASS="Konsti2007!"
|
||||
ports:
|
||||
- 3003:3002
|
||||
32
fx/echo.go
Normal file
32
fx/echo.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
// EchoHandler is an http.Handler that copies its request body
|
||||
// back to the response.
|
||||
type EchoHandler struct{}
|
||||
|
||||
// NewEchoHandler builds a new EchoHandler.
|
||||
func NewEchoHandler() *EchoHandler {
|
||||
return &EchoHandler{}
|
||||
}
|
||||
|
||||
// ServeHTTP handles an HTTP request to the /echo endpoint.
|
||||
func (*EchoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if _, err := io.Copy(w, r.Body); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Failed to handle request:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EchoHandler) Handler() http.Handler {
|
||||
return e
|
||||
}
|
||||
|
||||
func (*EchoHandler) Path() string {
|
||||
return "/echo"
|
||||
}
|
||||
9
fx/interfaces/integration.go
Normal file
9
fx/interfaces/integration.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package interfaces
|
||||
|
||||
import "context"
|
||||
|
||||
type BasicIntegration interface {
|
||||
OnStart(context.Context) error
|
||||
OnStop(context.Context) error
|
||||
Invoke()
|
||||
}
|
||||
1
fx/interfaces/stores/mandantstore.go
Normal file
1
fx/interfaces/stores/mandantstore.go
Normal file
@@ -0,0 +1 @@
|
||||
package stores
|
||||
17
fx/interfaces/stores/messagestore.go
Normal file
17
fx/interfaces/stores/messagestore.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package stores
|
||||
|
||||
import "context"
|
||||
|
||||
type Message struct {
|
||||
Id int
|
||||
From string
|
||||
Subject string
|
||||
Body string
|
||||
}
|
||||
|
||||
type MessageStore interface {
|
||||
AddMessage(ctx context.Context, m *Message) error
|
||||
GetMessage(ctx context.Context, id int) (*Message, error)
|
||||
ListMessages(ctx context.Context) ([]*Message, error)
|
||||
RemoveMessage(ctx context.Context, id int) error
|
||||
}
|
||||
1
fx/interfaces/stores/projectstore.go
Normal file
1
fx/interfaces/stores/projectstore.go
Normal file
@@ -0,0 +1 @@
|
||||
package stores
|
||||
44
fx/interfaces/stores/sessionstore.go
Normal file
44
fx/interfaces/stores/sessionstore.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package stores
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
Token string
|
||||
UserID uint
|
||||
MandantId uint
|
||||
}
|
||||
|
||||
func (s *Session) Deserialize(t string, m map[string]string) (*Session, error) {
|
||||
userid, err := strconv.Atoi(m["userid"])
|
||||
if err != nil {
|
||||
return nil, errors.New("Userid from cache not an int")
|
||||
}
|
||||
|
||||
mandantid, err := strconv.Atoi(m["mandantid"])
|
||||
if err != nil {
|
||||
return nil, errors.New("Mandantid from cache not an int")
|
||||
}
|
||||
|
||||
s.Token = t
|
||||
s.UserID = uint(userid)
|
||||
s.MandantId = uint(mandantid)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Session) Serialize() map[string]string {
|
||||
m := make(map[string]string)
|
||||
m["userid"] = strconv.Itoa(int(s.UserID))
|
||||
m["mandantid"] = strconv.Itoa(int(s.MandantId))
|
||||
return m
|
||||
}
|
||||
|
||||
type SessionStore interface {
|
||||
AddSession(s *Session)
|
||||
GetSessionFromToken(token string) (*Session, error)
|
||||
RemoveSession(token string)
|
||||
SetMandantInSession(token string, mandantId uint) error
|
||||
}
|
||||
1
fx/interfaces/stores/todostore.go
Normal file
1
fx/interfaces/stores/todostore.go
Normal file
@@ -0,0 +1 @@
|
||||
package stores
|
||||
137
fx/logger.go
Normal file
137
fx/logger.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"go.uber.org/fx"
|
||||
|
||||
"go.opentelemetry.io/contrib/bridges/otelslog"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||||
"go.opentelemetry.io/otel/log/global"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
olog "go.opentelemetry.io/otel/sdk/log"
|
||||
"go.opentelemetry.io/otel/sdk/metric"
|
||||
"go.opentelemetry.io/otel/sdk/trace"
|
||||
)
|
||||
|
||||
func NewOtelTracerProvider(lc fx.Lifecycle) *trace.TracerProvider {
|
||||
tp, err := newTracerProvider()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return tp.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return tp
|
||||
}
|
||||
|
||||
func NewOtelMeterProvider(lc fx.Lifecycle) *metric.MeterProvider {
|
||||
mp, err := newMeterProvider()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return mp.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return mp
|
||||
}
|
||||
|
||||
func NewOtelLoggerProvider(lc fx.Lifecycle) *olog.LoggerProvider {
|
||||
lp, err := newLoggerProvider()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return lp.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return lp
|
||||
}
|
||||
|
||||
func NewLogger(loggerProvider *olog.LoggerProvider) *slog.Logger {
|
||||
logger := otelslog.NewLogger("Application", otelslog.WithLoggerProvider(loggerProvider))
|
||||
return logger
|
||||
}
|
||||
|
||||
// setupOTelSDK bootstraps the OpenTelemetry pipeline.
|
||||
// If it does not return an error, make sure to call shutdown for proper cleanup.
|
||||
func SetupOTelSDK(tracerProvider *trace.TracerProvider, meterProvider *metric.MeterProvider, loggerProvider *olog.LoggerProvider) {
|
||||
// Set up propagator.
|
||||
prop := newPropagator()
|
||||
otel.SetTextMapPropagator(prop)
|
||||
|
||||
// Set up trace provider.
|
||||
otel.SetTracerProvider(tracerProvider)
|
||||
otel.SetMeterProvider(meterProvider)
|
||||
|
||||
// Set up logger provider.
|
||||
global.SetLoggerProvider(loggerProvider)
|
||||
}
|
||||
|
||||
func newPropagator() propagation.TextMapPropagator {
|
||||
return propagation.NewCompositeTextMapPropagator(
|
||||
propagation.TraceContext{},
|
||||
propagation.Baggage{},
|
||||
)
|
||||
}
|
||||
|
||||
func newTracerProvider() (*trace.TracerProvider, error) {
|
||||
|
||||
traceExporter, err := otlptracehttp.New(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tracerProvider := trace.NewTracerProvider(
|
||||
trace.WithBatcher(traceExporter,
|
||||
// Default is 5s. Set to 1s for demonstrative purposes.
|
||||
trace.WithBatchTimeout(time.Second)),
|
||||
)
|
||||
return tracerProvider, nil
|
||||
}
|
||||
|
||||
func newMeterProvider() (*metric.MeterProvider, error) {
|
||||
metricExporter, err := otlpmetrichttp.New(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
meterProvider := metric.NewMeterProvider(
|
||||
metric.WithReader(metric.NewPeriodicReader(metricExporter,
|
||||
// Default is 1m. Set to 3s for demonstrative purposes.
|
||||
metric.WithInterval(3*time.Second))),
|
||||
)
|
||||
return meterProvider, nil
|
||||
}
|
||||
|
||||
func newLoggerProvider() (*olog.LoggerProvider, error) {
|
||||
logExporter, err := otlploghttp.New(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
loggerProvider := olog.NewLoggerProvider(
|
||||
olog.WithProcessor(olog.NewBatchProcessor(logExporter)),
|
||||
)
|
||||
|
||||
logger := otelslog.NewLogger("sloger", otelslog.WithLoggerProvider(loggerProvider))
|
||||
logger.Info("Hello")
|
||||
|
||||
return loggerProvider, nil
|
||||
}
|
||||
56
fx/routes.go
Normal file
56
fx/routes.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
connectcors "connectrpc.com/cors"
|
||||
"github.com/rs/cors"
|
||||
)
|
||||
|
||||
type Handler interface {
|
||||
Handler() http.Handler
|
||||
Path() string
|
||||
}
|
||||
|
||||
type route struct {
|
||||
path string
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
func NewRoute(path string, handler http.Handler) Handler {
|
||||
return &route{
|
||||
path: path,
|
||||
handler: handler,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *route) Handler() http.Handler {
|
||||
return r.handler
|
||||
}
|
||||
|
||||
func (r *route) Path() string {
|
||||
return r.path
|
||||
}
|
||||
|
||||
// NewServeMux builds a ServeMux that will route requests
|
||||
// to the given EchoHandler.
|
||||
func NewServeMux(handlers []Handler, logger *slog.Logger) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
for _, h := range handlers {
|
||||
logger.Debug("Registering route", "path", h.Path())
|
||||
mux.Handle(h.Path(), h.Handler())
|
||||
}
|
||||
|
||||
handler := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"http://10.8.0.3:3001", "http://10.8.0.3:3001/", os.Getenv("FRONTEND_URI")}, // replace with your domain
|
||||
AllowedMethods: connectcors.AllowedMethods(),
|
||||
AllowedHeaders: append(connectcors.AllowedHeaders(), "authentication", "Authentication"),
|
||||
ExposedHeaders: connectcors.ExposedHeaders(),
|
||||
AllowCredentials: true,
|
||||
}).Handler(mux)
|
||||
|
||||
return handler
|
||||
}
|
||||
40
fx/server.go
Normal file
40
fx/server.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
func NewHTTPServer(lc fx.Lifecycle, handler http.Handler) *http.Server {
|
||||
p := new(http.Protocols)
|
||||
p.SetHTTP1(true)
|
||||
// Use h2c so we can serve HTTP/2 without TLS.
|
||||
p.SetUnencryptedHTTP2(true)
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: ":3002",
|
||||
Protocols: p,
|
||||
Handler: handler,
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(ctx context.Context) error {
|
||||
go func() {
|
||||
fmt.Println("Listening on :3002")
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return srv.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return srv
|
||||
}
|
||||
532
gen/mandant/v1/mandant.pb.go
Normal file
532
gen/mandant/v1/mandant.pb.go
Normal file
@@ -0,0 +1,532 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: mandant/v1/mandant.proto
|
||||
|
||||
package mandantv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type GetCurrentTenantRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetCurrentTenantRequest) Reset() {
|
||||
*x = GetCurrentTenantRequest{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetCurrentTenantRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetCurrentTenantRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetCurrentTenantRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[0]
|
||||
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 GetCurrentTenantRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetCurrentTenantRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type GetTenantRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetTenantRequest) Reset() {
|
||||
*x = GetTenantRequest{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetTenantRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetTenantRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetTenantRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[1]
|
||||
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 GetTenantRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetTenantRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GetTenantRequest) GetId() int64 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type GetTenantResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Plan string `protobuf:"bytes,3,opt,name=plan,proto3" json:"plan,omitempty"`
|
||||
Logo string `protobuf:"bytes,4,opt,name=logo,proto3" json:"logo,omitempty"`
|
||||
Color string `protobuf:"bytes,5,opt,name=color,proto3" json:"color,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetTenantResponse) Reset() {
|
||||
*x = GetTenantResponse{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetTenantResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetTenantResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetTenantResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[2]
|
||||
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 GetTenantResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetTenantResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *GetTenantResponse) GetId() int64 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GetTenantResponse) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetTenantResponse) GetPlan() string {
|
||||
if x != nil {
|
||||
return x.Plan
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetTenantResponse) GetLogo() string {
|
||||
if x != nil {
|
||||
return x.Logo
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetTenantResponse) GetColor() string {
|
||||
if x != nil {
|
||||
return x.Color
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListTenantRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
|
||||
PerPage int32 `protobuf:"varint,2,opt,name=per_page,json=perPage,proto3" json:"per_page,omitempty"`
|
||||
OrberBy string `protobuf:"bytes,3,opt,name=orber_by,json=orberBy,proto3" json:"orber_by,omitempty"`
|
||||
Asc bool `protobuf:"varint,4,opt,name=asc,proto3" json:"asc,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListTenantRequest) Reset() {
|
||||
*x = ListTenantRequest{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListTenantRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListTenantRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListTenantRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[3]
|
||||
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 ListTenantRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListTenantRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ListTenantRequest) GetPage() int32 {
|
||||
if x != nil {
|
||||
return x.Page
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ListTenantRequest) GetPerPage() int32 {
|
||||
if x != nil {
|
||||
return x.PerPage
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ListTenantRequest) GetOrberBy() string {
|
||||
if x != nil {
|
||||
return x.OrberBy
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ListTenantRequest) GetAsc() bool {
|
||||
if x != nil {
|
||||
return x.Asc
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TotalCount int32 `protobuf:"varint,1,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Metadata) Reset() {
|
||||
*x = Metadata{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Metadata) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Metadata) ProtoMessage() {}
|
||||
|
||||
func (x *Metadata) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[4]
|
||||
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 Metadata.ProtoReflect.Descriptor instead.
|
||||
func (*Metadata) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *Metadata) GetTotalCount() int32 {
|
||||
if x != nil {
|
||||
return x.TotalCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ListProjectsResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Data []*GetTenantResponse `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
|
||||
Meta *Metadata `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) Reset() {
|
||||
*x = ListProjectsResponse{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListProjectsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[5]
|
||||
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 ListProjectsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListProjectsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) GetData() []*GetTenantResponse {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) GetMeta() *Metadata {
|
||||
if x != nil {
|
||||
return x.Meta
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetCurrentTenantRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TenantId int64 `protobuf:"varint,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetCurrentTenantRequest) Reset() {
|
||||
*x = SetCurrentTenantRequest{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetCurrentTenantRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetCurrentTenantRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetCurrentTenantRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[6]
|
||||
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 SetCurrentTenantRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SetCurrentTenantRequest) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *SetCurrentTenantRequest) GetTenantId() int64 {
|
||||
if x != nil {
|
||||
return x.TenantId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type SetCurrentTenantResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetCurrentTenantResponse) Reset() {
|
||||
*x = SetCurrentTenantResponse{}
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetCurrentTenantResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetCurrentTenantResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetCurrentTenantResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_mandant_v1_mandant_proto_msgTypes[7]
|
||||
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 SetCurrentTenantResponse.ProtoReflect.Descriptor instead.
|
||||
func (*SetCurrentTenantResponse) Descriptor() ([]byte, []int) {
|
||||
return file_mandant_v1_mandant_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *SetCurrentTenantResponse) GetSuccess() bool {
|
||||
if x != nil {
|
||||
return x.Success
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_mandant_v1_mandant_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_mandant_v1_mandant_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x18mandant/v1/mandant.proto\x12\n" +
|
||||
"mandant.v1\"\x19\n" +
|
||||
"\x17GetCurrentTenantRequest\"\"\n" +
|
||||
"\x10GetTenantRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\"u\n" +
|
||||
"\x11GetTenantResponse\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" +
|
||||
"\x04plan\x18\x03 \x01(\tR\x04plan\x12\x12\n" +
|
||||
"\x04logo\x18\x04 \x01(\tR\x04logo\x12\x14\n" +
|
||||
"\x05color\x18\x05 \x01(\tR\x05color\"o\n" +
|
||||
"\x11ListTenantRequest\x12\x12\n" +
|
||||
"\x04page\x18\x01 \x01(\x05R\x04page\x12\x19\n" +
|
||||
"\bper_page\x18\x02 \x01(\x05R\aperPage\x12\x19\n" +
|
||||
"\borber_by\x18\x03 \x01(\tR\aorberBy\x12\x10\n" +
|
||||
"\x03asc\x18\x04 \x01(\bR\x03asc\"*\n" +
|
||||
"\bMetadata\x12\x1e\n" +
|
||||
"\n" +
|
||||
"totalCount\x18\x01 \x01(\x05R\n" +
|
||||
"totalCount\"s\n" +
|
||||
"\x14ListProjectsResponse\x121\n" +
|
||||
"\x04data\x18\x01 \x03(\v2\x1d.mandant.v1.GetTenantResponseR\x04data\x12(\n" +
|
||||
"\x04meta\x18\x02 \x01(\v2\x14.mandant.v1.MetadataR\x04meta\"6\n" +
|
||||
"\x17SetCurrentTenantRequest\x12\x1b\n" +
|
||||
"\ttenant_id\x18\x01 \x01(\x03R\btenantId\"4\n" +
|
||||
"\x18SetCurrentTenantResponse\x12\x18\n" +
|
||||
"\asuccess\x18\x01 \x01(\bR\asuccess2\x99\x02\n" +
|
||||
"\x0eMandantService\x12V\n" +
|
||||
"\x10GetCurrentTenant\x12#.mandant.v1.GetCurrentTenantRequest\x1a\x1d.mandant.v1.GetTenantResponse\x12P\n" +
|
||||
"\rGetAllTenants\x12\x1d.mandant.v1.ListTenantRequest\x1a .mandant.v1.ListProjectsResponse\x12]\n" +
|
||||
"\x10SetCurrentTenant\x12#.mandant.v1.SetCurrentTenantRequest\x1a$.mandant.v1.SetCurrentTenantResponseB\x9c\x01\n" +
|
||||
"\x0ecom.mandant.v1B\fMandantProtoP\x01Z3git.kocoder.xyz/kocoded/vt/gen/mandant/v1;mandantv1\xa2\x02\x03MXX\xaa\x02\n" +
|
||||
"Mandant.V1\xca\x02\n" +
|
||||
"Mandant\\V1\xe2\x02\x16Mandant\\V1\\GPBMetadata\xea\x02\vMandant::V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_mandant_v1_mandant_proto_rawDescOnce sync.Once
|
||||
file_mandant_v1_mandant_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_mandant_v1_mandant_proto_rawDescGZIP() []byte {
|
||||
file_mandant_v1_mandant_proto_rawDescOnce.Do(func() {
|
||||
file_mandant_v1_mandant_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mandant_v1_mandant_proto_rawDesc), len(file_mandant_v1_mandant_proto_rawDesc)))
|
||||
})
|
||||
return file_mandant_v1_mandant_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_mandant_v1_mandant_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||
var file_mandant_v1_mandant_proto_goTypes = []any{
|
||||
(*GetCurrentTenantRequest)(nil), // 0: mandant.v1.GetCurrentTenantRequest
|
||||
(*GetTenantRequest)(nil), // 1: mandant.v1.GetTenantRequest
|
||||
(*GetTenantResponse)(nil), // 2: mandant.v1.GetTenantResponse
|
||||
(*ListTenantRequest)(nil), // 3: mandant.v1.ListTenantRequest
|
||||
(*Metadata)(nil), // 4: mandant.v1.Metadata
|
||||
(*ListProjectsResponse)(nil), // 5: mandant.v1.ListProjectsResponse
|
||||
(*SetCurrentTenantRequest)(nil), // 6: mandant.v1.SetCurrentTenantRequest
|
||||
(*SetCurrentTenantResponse)(nil), // 7: mandant.v1.SetCurrentTenantResponse
|
||||
}
|
||||
var file_mandant_v1_mandant_proto_depIdxs = []int32{
|
||||
2, // 0: mandant.v1.ListProjectsResponse.data:type_name -> mandant.v1.GetTenantResponse
|
||||
4, // 1: mandant.v1.ListProjectsResponse.meta:type_name -> mandant.v1.Metadata
|
||||
0, // 2: mandant.v1.MandantService.GetCurrentTenant:input_type -> mandant.v1.GetCurrentTenantRequest
|
||||
3, // 3: mandant.v1.MandantService.GetAllTenants:input_type -> mandant.v1.ListTenantRequest
|
||||
6, // 4: mandant.v1.MandantService.SetCurrentTenant:input_type -> mandant.v1.SetCurrentTenantRequest
|
||||
2, // 5: mandant.v1.MandantService.GetCurrentTenant:output_type -> mandant.v1.GetTenantResponse
|
||||
5, // 6: mandant.v1.MandantService.GetAllTenants:output_type -> mandant.v1.ListProjectsResponse
|
||||
7, // 7: mandant.v1.MandantService.SetCurrentTenant:output_type -> mandant.v1.SetCurrentTenantResponse
|
||||
5, // [5:8] is the sub-list for method output_type
|
||||
2, // [2:5] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_mandant_v1_mandant_proto_init() }
|
||||
func file_mandant_v1_mandant_proto_init() {
|
||||
if File_mandant_v1_mandant_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_mandant_v1_mandant_proto_rawDesc), len(file_mandant_v1_mandant_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 8,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_mandant_v1_mandant_proto_goTypes,
|
||||
DependencyIndexes: file_mandant_v1_mandant_proto_depIdxs,
|
||||
MessageInfos: file_mandant_v1_mandant_proto_msgTypes,
|
||||
}.Build()
|
||||
File_mandant_v1_mandant_proto = out.File
|
||||
file_mandant_v1_mandant_proto_goTypes = nil
|
||||
file_mandant_v1_mandant_proto_depIdxs = nil
|
||||
}
|
||||
179
gen/mandant/v1/mandantv1connect/mandant.connect.go
Normal file
179
gen/mandant/v1/mandantv1connect/mandant.connect.go
Normal file
@@ -0,0 +1,179 @@
|
||||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: mandant/v1/mandant.proto
|
||||
|
||||
package mandantv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "git.kocoder.xyz/kocoded/vt/gen/mandant/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// MandantServiceName is the fully-qualified name of the MandantService service.
|
||||
MandantServiceName = "mandant.v1.MandantService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// MandantServiceGetCurrentTenantProcedure is the fully-qualified name of the MandantService's
|
||||
// GetCurrentTenant RPC.
|
||||
MandantServiceGetCurrentTenantProcedure = "/mandant.v1.MandantService/GetCurrentTenant"
|
||||
// MandantServiceGetAllTenantsProcedure is the fully-qualified name of the MandantService's
|
||||
// GetAllTenants RPC.
|
||||
MandantServiceGetAllTenantsProcedure = "/mandant.v1.MandantService/GetAllTenants"
|
||||
// MandantServiceSetCurrentTenantProcedure is the fully-qualified name of the MandantService's
|
||||
// SetCurrentTenant RPC.
|
||||
MandantServiceSetCurrentTenantProcedure = "/mandant.v1.MandantService/SetCurrentTenant"
|
||||
)
|
||||
|
||||
// MandantServiceClient is a client for the mandant.v1.MandantService service.
|
||||
type MandantServiceClient interface {
|
||||
GetCurrentTenant(context.Context, *v1.GetCurrentTenantRequest) (*v1.GetTenantResponse, error)
|
||||
GetAllTenants(context.Context, *v1.ListTenantRequest) (*v1.ListProjectsResponse, error)
|
||||
SetCurrentTenant(context.Context, *v1.SetCurrentTenantRequest) (*v1.SetCurrentTenantResponse, error)
|
||||
}
|
||||
|
||||
// NewMandantServiceClient constructs a client for the mandant.v1.MandantService service. By
|
||||
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
|
||||
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewMandantServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) MandantServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
mandantServiceMethods := v1.File_mandant_v1_mandant_proto.Services().ByName("MandantService").Methods()
|
||||
return &mandantServiceClient{
|
||||
getCurrentTenant: connect.NewClient[v1.GetCurrentTenantRequest, v1.GetTenantResponse](
|
||||
httpClient,
|
||||
baseURL+MandantServiceGetCurrentTenantProcedure,
|
||||
connect.WithSchema(mandantServiceMethods.ByName("GetCurrentTenant")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getAllTenants: connect.NewClient[v1.ListTenantRequest, v1.ListProjectsResponse](
|
||||
httpClient,
|
||||
baseURL+MandantServiceGetAllTenantsProcedure,
|
||||
connect.WithSchema(mandantServiceMethods.ByName("GetAllTenants")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
setCurrentTenant: connect.NewClient[v1.SetCurrentTenantRequest, v1.SetCurrentTenantResponse](
|
||||
httpClient,
|
||||
baseURL+MandantServiceSetCurrentTenantProcedure,
|
||||
connect.WithSchema(mandantServiceMethods.ByName("SetCurrentTenant")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// mandantServiceClient implements MandantServiceClient.
|
||||
type mandantServiceClient struct {
|
||||
getCurrentTenant *connect.Client[v1.GetCurrentTenantRequest, v1.GetTenantResponse]
|
||||
getAllTenants *connect.Client[v1.ListTenantRequest, v1.ListProjectsResponse]
|
||||
setCurrentTenant *connect.Client[v1.SetCurrentTenantRequest, v1.SetCurrentTenantResponse]
|
||||
}
|
||||
|
||||
// GetCurrentTenant calls mandant.v1.MandantService.GetCurrentTenant.
|
||||
func (c *mandantServiceClient) GetCurrentTenant(ctx context.Context, req *v1.GetCurrentTenantRequest) (*v1.GetTenantResponse, error) {
|
||||
response, err := c.getCurrentTenant.CallUnary(ctx, connect.NewRequest(req))
|
||||
if response != nil {
|
||||
return response.Msg, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// GetAllTenants calls mandant.v1.MandantService.GetAllTenants.
|
||||
func (c *mandantServiceClient) GetAllTenants(ctx context.Context, req *v1.ListTenantRequest) (*v1.ListProjectsResponse, error) {
|
||||
response, err := c.getAllTenants.CallUnary(ctx, connect.NewRequest(req))
|
||||
if response != nil {
|
||||
return response.Msg, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// SetCurrentTenant calls mandant.v1.MandantService.SetCurrentTenant.
|
||||
func (c *mandantServiceClient) SetCurrentTenant(ctx context.Context, req *v1.SetCurrentTenantRequest) (*v1.SetCurrentTenantResponse, error) {
|
||||
response, err := c.setCurrentTenant.CallUnary(ctx, connect.NewRequest(req))
|
||||
if response != nil {
|
||||
return response.Msg, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// MandantServiceHandler is an implementation of the mandant.v1.MandantService service.
|
||||
type MandantServiceHandler interface {
|
||||
GetCurrentTenant(context.Context, *v1.GetCurrentTenantRequest) (*v1.GetTenantResponse, error)
|
||||
GetAllTenants(context.Context, *v1.ListTenantRequest) (*v1.ListProjectsResponse, error)
|
||||
SetCurrentTenant(context.Context, *v1.SetCurrentTenantRequest) (*v1.SetCurrentTenantResponse, error)
|
||||
}
|
||||
|
||||
// NewMandantServiceHandler builds an HTTP handler from the service implementation. It returns the
|
||||
// path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewMandantServiceHandler(svc MandantServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
mandantServiceMethods := v1.File_mandant_v1_mandant_proto.Services().ByName("MandantService").Methods()
|
||||
mandantServiceGetCurrentTenantHandler := connect.NewUnaryHandlerSimple(
|
||||
MandantServiceGetCurrentTenantProcedure,
|
||||
svc.GetCurrentTenant,
|
||||
connect.WithSchema(mandantServiceMethods.ByName("GetCurrentTenant")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
mandantServiceGetAllTenantsHandler := connect.NewUnaryHandlerSimple(
|
||||
MandantServiceGetAllTenantsProcedure,
|
||||
svc.GetAllTenants,
|
||||
connect.WithSchema(mandantServiceMethods.ByName("GetAllTenants")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
mandantServiceSetCurrentTenantHandler := connect.NewUnaryHandlerSimple(
|
||||
MandantServiceSetCurrentTenantProcedure,
|
||||
svc.SetCurrentTenant,
|
||||
connect.WithSchema(mandantServiceMethods.ByName("SetCurrentTenant")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/mandant.v1.MandantService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case MandantServiceGetCurrentTenantProcedure:
|
||||
mandantServiceGetCurrentTenantHandler.ServeHTTP(w, r)
|
||||
case MandantServiceGetAllTenantsProcedure:
|
||||
mandantServiceGetAllTenantsHandler.ServeHTTP(w, r)
|
||||
case MandantServiceSetCurrentTenantProcedure:
|
||||
mandantServiceSetCurrentTenantHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedMandantServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedMandantServiceHandler struct{}
|
||||
|
||||
func (UnimplementedMandantServiceHandler) GetCurrentTenant(context.Context, *v1.GetCurrentTenantRequest) (*v1.GetTenantResponse, error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mandant.v1.MandantService.GetCurrentTenant is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMandantServiceHandler) GetAllTenants(context.Context, *v1.ListTenantRequest) (*v1.ListProjectsResponse, error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mandant.v1.MandantService.GetAllTenants is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMandantServiceHandler) SetCurrentTenant(context.Context, *v1.SetCurrentTenantRequest) (*v1.SetCurrentTenantResponse, error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mandant.v1.MandantService.SetCurrentTenant is not implemented"))
|
||||
}
|
||||
217
gen/messagebus/v1/messagebus.pb.go
Normal file
217
gen/messagebus/v1/messagebus.pb.go
Normal file
@@ -0,0 +1,217 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: messagebus/v1/messagebus.proto
|
||||
|
||||
package messagebusv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type MessageBusEntityType int32
|
||||
|
||||
const (
|
||||
MessageBusEntityType_OTHER MessageBusEntityType = 0
|
||||
MessageBusEntityType_INVALIDATION_REQUEST MessageBusEntityType = 1
|
||||
)
|
||||
|
||||
// Enum value maps for MessageBusEntityType.
|
||||
var (
|
||||
MessageBusEntityType_name = map[int32]string{
|
||||
0: "OTHER",
|
||||
1: "INVALIDATION_REQUEST",
|
||||
}
|
||||
MessageBusEntityType_value = map[string]int32{
|
||||
"OTHER": 0,
|
||||
"INVALIDATION_REQUEST": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x MessageBusEntityType) Enum() *MessageBusEntityType {
|
||||
p := new(MessageBusEntityType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x MessageBusEntityType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (MessageBusEntityType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_messagebus_v1_messagebus_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (MessageBusEntityType) Type() protoreflect.EnumType {
|
||||
return &file_messagebus_v1_messagebus_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x MessageBusEntityType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MessageBusEntityType.Descriptor instead.
|
||||
func (MessageBusEntityType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_messagebus_v1_messagebus_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type MessageBusEntity struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
QueryKey string `protobuf:"bytes,1,opt,name=queryKey,proto3" json:"queryKey,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *MessageBusEntity) Reset() {
|
||||
*x = MessageBusEntity{}
|
||||
mi := &file_messagebus_v1_messagebus_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *MessageBusEntity) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MessageBusEntity) ProtoMessage() {}
|
||||
|
||||
func (x *MessageBusEntity) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messagebus_v1_messagebus_proto_msgTypes[0]
|
||||
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 MessageBusEntity.ProtoReflect.Descriptor instead.
|
||||
func (*MessageBusEntity) Descriptor() ([]byte, []int) {
|
||||
return file_messagebus_v1_messagebus_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *MessageBusEntity) GetQueryKey() string {
|
||||
if x != nil {
|
||||
return x.QueryKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SubscribeToConnectInvalidationRequestsRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SubscribeToConnectInvalidationRequestsRequest) Reset() {
|
||||
*x = SubscribeToConnectInvalidationRequestsRequest{}
|
||||
mi := &file_messagebus_v1_messagebus_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SubscribeToConnectInvalidationRequestsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SubscribeToConnectInvalidationRequestsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SubscribeToConnectInvalidationRequestsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messagebus_v1_messagebus_proto_msgTypes[1]
|
||||
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 SubscribeToConnectInvalidationRequestsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SubscribeToConnectInvalidationRequestsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_messagebus_v1_messagebus_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
var File_messagebus_v1_messagebus_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_messagebus_v1_messagebus_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1emessagebus/v1/messagebus.proto\x12\rmessagebus.v1\".\n" +
|
||||
"\x10MessageBusEntity\x12\x1a\n" +
|
||||
"\bqueryKey\x18\x01 \x01(\tR\bqueryKey\"/\n" +
|
||||
"-SubscribeToConnectInvalidationRequestsRequest*;\n" +
|
||||
"\x14MessageBusEntityType\x12\t\n" +
|
||||
"\x05OTHER\x10\x00\x12\x18\n" +
|
||||
"\x14INVALIDATION_REQUEST\x10\x012\x9f\x01\n" +
|
||||
"\x11MessageBusService\x12\x89\x01\n" +
|
||||
"&SubscribeToConnectInvalidationRequests\x12<.messagebus.v1.SubscribeToConnectInvalidationRequestsRequest\x1a\x1f.messagebus.v1.MessageBusEntity0\x01B\xb4\x01\n" +
|
||||
"\x11com.messagebus.v1B\x0fMessagebusProtoP\x01Z9git.kocoder.xyz/kocoded/vt/gen/messagebus/v1;messagebusv1\xa2\x02\x03MXX\xaa\x02\rMessagebus.V1\xca\x02\rMessagebus\\V1\xe2\x02\x19Messagebus\\V1\\GPBMetadata\xea\x02\x0eMessagebus::V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_messagebus_v1_messagebus_proto_rawDescOnce sync.Once
|
||||
file_messagebus_v1_messagebus_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_messagebus_v1_messagebus_proto_rawDescGZIP() []byte {
|
||||
file_messagebus_v1_messagebus_proto_rawDescOnce.Do(func() {
|
||||
file_messagebus_v1_messagebus_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_messagebus_v1_messagebus_proto_rawDesc), len(file_messagebus_v1_messagebus_proto_rawDesc)))
|
||||
})
|
||||
return file_messagebus_v1_messagebus_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_messagebus_v1_messagebus_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_messagebus_v1_messagebus_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_messagebus_v1_messagebus_proto_goTypes = []any{
|
||||
(MessageBusEntityType)(0), // 0: messagebus.v1.MessageBusEntityType
|
||||
(*MessageBusEntity)(nil), // 1: messagebus.v1.MessageBusEntity
|
||||
(*SubscribeToConnectInvalidationRequestsRequest)(nil), // 2: messagebus.v1.SubscribeToConnectInvalidationRequestsRequest
|
||||
}
|
||||
var file_messagebus_v1_messagebus_proto_depIdxs = []int32{
|
||||
2, // 0: messagebus.v1.MessageBusService.SubscribeToConnectInvalidationRequests:input_type -> messagebus.v1.SubscribeToConnectInvalidationRequestsRequest
|
||||
1, // 1: messagebus.v1.MessageBusService.SubscribeToConnectInvalidationRequests:output_type -> messagebus.v1.MessageBusEntity
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] 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_messagebus_v1_messagebus_proto_init() }
|
||||
func file_messagebus_v1_messagebus_proto_init() {
|
||||
if File_messagebus_v1_messagebus_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_messagebus_v1_messagebus_proto_rawDesc), len(file_messagebus_v1_messagebus_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_messagebus_v1_messagebus_proto_goTypes,
|
||||
DependencyIndexes: file_messagebus_v1_messagebus_proto_depIdxs,
|
||||
EnumInfos: file_messagebus_v1_messagebus_proto_enumTypes,
|
||||
MessageInfos: file_messagebus_v1_messagebus_proto_msgTypes,
|
||||
}.Build()
|
||||
File_messagebus_v1_messagebus_proto = out.File
|
||||
file_messagebus_v1_messagebus_proto_goTypes = nil
|
||||
file_messagebus_v1_messagebus_proto_depIdxs = nil
|
||||
}
|
||||
110
gen/messagebus/v1/messagebusv1connect/messagebus.connect.go
Normal file
110
gen/messagebus/v1/messagebusv1connect/messagebus.connect.go
Normal file
@@ -0,0 +1,110 @@
|
||||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: messagebus/v1/messagebus.proto
|
||||
|
||||
package messagebusv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "git.kocoder.xyz/kocoded/vt/gen/messagebus/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// MessageBusServiceName is the fully-qualified name of the MessageBusService service.
|
||||
MessageBusServiceName = "messagebus.v1.MessageBusService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// MessageBusServiceSubscribeToConnectInvalidationRequestsProcedure is the fully-qualified name of
|
||||
// the MessageBusService's SubscribeToConnectInvalidationRequests RPC.
|
||||
MessageBusServiceSubscribeToConnectInvalidationRequestsProcedure = "/messagebus.v1.MessageBusService/SubscribeToConnectInvalidationRequests"
|
||||
)
|
||||
|
||||
// MessageBusServiceClient is a client for the messagebus.v1.MessageBusService service.
|
||||
type MessageBusServiceClient interface {
|
||||
SubscribeToConnectInvalidationRequests(context.Context, *v1.SubscribeToConnectInvalidationRequestsRequest) (*connect.ServerStreamForClient[v1.MessageBusEntity], error)
|
||||
}
|
||||
|
||||
// NewMessageBusServiceClient constructs a client for the messagebus.v1.MessageBusService service.
|
||||
// By default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped
|
||||
// responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewMessageBusServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) MessageBusServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
messageBusServiceMethods := v1.File_messagebus_v1_messagebus_proto.Services().ByName("MessageBusService").Methods()
|
||||
return &messageBusServiceClient{
|
||||
subscribeToConnectInvalidationRequests: connect.NewClient[v1.SubscribeToConnectInvalidationRequestsRequest, v1.MessageBusEntity](
|
||||
httpClient,
|
||||
baseURL+MessageBusServiceSubscribeToConnectInvalidationRequestsProcedure,
|
||||
connect.WithSchema(messageBusServiceMethods.ByName("SubscribeToConnectInvalidationRequests")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// messageBusServiceClient implements MessageBusServiceClient.
|
||||
type messageBusServiceClient struct {
|
||||
subscribeToConnectInvalidationRequests *connect.Client[v1.SubscribeToConnectInvalidationRequestsRequest, v1.MessageBusEntity]
|
||||
}
|
||||
|
||||
// SubscribeToConnectInvalidationRequests calls
|
||||
// messagebus.v1.MessageBusService.SubscribeToConnectInvalidationRequests.
|
||||
func (c *messageBusServiceClient) SubscribeToConnectInvalidationRequests(ctx context.Context, req *v1.SubscribeToConnectInvalidationRequestsRequest) (*connect.ServerStreamForClient[v1.MessageBusEntity], error) {
|
||||
return c.subscribeToConnectInvalidationRequests.CallServerStream(ctx, connect.NewRequest(req))
|
||||
}
|
||||
|
||||
// MessageBusServiceHandler is an implementation of the messagebus.v1.MessageBusService service.
|
||||
type MessageBusServiceHandler interface {
|
||||
SubscribeToConnectInvalidationRequests(context.Context, *v1.SubscribeToConnectInvalidationRequestsRequest, *connect.ServerStream[v1.MessageBusEntity]) error
|
||||
}
|
||||
|
||||
// NewMessageBusServiceHandler builds an HTTP handler from the service implementation. It returns
|
||||
// the path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewMessageBusServiceHandler(svc MessageBusServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
messageBusServiceMethods := v1.File_messagebus_v1_messagebus_proto.Services().ByName("MessageBusService").Methods()
|
||||
messageBusServiceSubscribeToConnectInvalidationRequestsHandler := connect.NewServerStreamHandlerSimple(
|
||||
MessageBusServiceSubscribeToConnectInvalidationRequestsProcedure,
|
||||
svc.SubscribeToConnectInvalidationRequests,
|
||||
connect.WithSchema(messageBusServiceMethods.ByName("SubscribeToConnectInvalidationRequests")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/messagebus.v1.MessageBusService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case MessageBusServiceSubscribeToConnectInvalidationRequestsProcedure:
|
||||
messageBusServiceSubscribeToConnectInvalidationRequestsHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedMessageBusServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedMessageBusServiceHandler struct{}
|
||||
|
||||
func (UnimplementedMessageBusServiceHandler) SubscribeToConnectInvalidationRequests(context.Context, *v1.SubscribeToConnectInvalidationRequestsRequest, *connect.ServerStream[v1.MessageBusEntity]) error {
|
||||
return connect.NewError(connect.CodeUnimplemented, errors.New("messagebus.v1.MessageBusService.SubscribeToConnectInvalidationRequests is not implemented"))
|
||||
}
|
||||
433
gen/project/v1/project.pb.go
Normal file
433
gen/project/v1/project.pb.go
Normal file
@@ -0,0 +1,433 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: project/v1/project.proto
|
||||
|
||||
package projectv1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type GetProjectRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetProjectRequest) Reset() {
|
||||
*x = GetProjectRequest{}
|
||||
mi := &file_project_v1_project_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetProjectRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetProjectRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetProjectRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_project_v1_project_proto_msgTypes[0]
|
||||
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 GetProjectRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetProjectRequest) Descriptor() ([]byte, []int) {
|
||||
return file_project_v1_project_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *GetProjectRequest) GetId() int32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type GetProjectResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
|
||||
IsMaterialized *bool `protobuf:"varint,5,opt,name=is_materialized,json=isMaterialized,proto3,oneof" json:"is_materialized,omitempty"`
|
||||
IsPersonalized *bool `protobuf:"varint,6,opt,name=is_personalized,json=isPersonalized,proto3,oneof" json:"is_personalized,omitempty"`
|
||||
IsConfirmed *bool `protobuf:"varint,7,opt,name=is_confirmed,json=isConfirmed,proto3,oneof" json:"is_confirmed,omitempty"`
|
||||
IsPaid *bool `protobuf:"varint,8,opt,name=is_paid,json=isPaid,proto3,oneof" json:"is_paid,omitempty"`
|
||||
IsDone *bool `protobuf:"varint,9,opt,name=is_done,json=isDone,proto3,oneof" json:"is_done,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) Reset() {
|
||||
*x = GetProjectResponse{}
|
||||
mi := &file_project_v1_project_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetProjectResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetProjectResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_project_v1_project_proto_msgTypes[1]
|
||||
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 GetProjectResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetProjectResponse) Descriptor() ([]byte, []int) {
|
||||
return file_project_v1_project_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetId() int64 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetIsMaterialized() bool {
|
||||
if x != nil && x.IsMaterialized != nil {
|
||||
return *x.IsMaterialized
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetIsPersonalized() bool {
|
||||
if x != nil && x.IsPersonalized != nil {
|
||||
return *x.IsPersonalized
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetIsConfirmed() bool {
|
||||
if x != nil && x.IsConfirmed != nil {
|
||||
return *x.IsConfirmed
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetIsPaid() bool {
|
||||
if x != nil && x.IsPaid != nil {
|
||||
return *x.IsPaid
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *GetProjectResponse) GetIsDone() bool {
|
||||
if x != nil && x.IsDone != nil {
|
||||
return *x.IsDone
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ListProjectsRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
|
||||
PerPage int32 `protobuf:"varint,2,opt,name=per_page,json=perPage,proto3" json:"per_page,omitempty"`
|
||||
OrberBy string `protobuf:"bytes,3,opt,name=orber_by,json=orberBy,proto3" json:"orber_by,omitempty"`
|
||||
Asc bool `protobuf:"varint,4,opt,name=asc,proto3" json:"asc,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListProjectsRequest) Reset() {
|
||||
*x = ListProjectsRequest{}
|
||||
mi := &file_project_v1_project_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListProjectsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListProjectsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListProjectsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_project_v1_project_proto_msgTypes[2]
|
||||
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 ListProjectsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListProjectsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_project_v1_project_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ListProjectsRequest) GetPage() int32 {
|
||||
if x != nil {
|
||||
return x.Page
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ListProjectsRequest) GetPerPage() int32 {
|
||||
if x != nil {
|
||||
return x.PerPage
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ListProjectsRequest) GetOrberBy() string {
|
||||
if x != nil {
|
||||
return x.OrberBy
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ListProjectsRequest) GetAsc() bool {
|
||||
if x != nil {
|
||||
return x.Asc
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TotalCount int32 `protobuf:"varint,1,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Metadata) Reset() {
|
||||
*x = Metadata{}
|
||||
mi := &file_project_v1_project_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Metadata) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Metadata) ProtoMessage() {}
|
||||
|
||||
func (x *Metadata) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_project_v1_project_proto_msgTypes[3]
|
||||
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 Metadata.ProtoReflect.Descriptor instead.
|
||||
func (*Metadata) Descriptor() ([]byte, []int) {
|
||||
return file_project_v1_project_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *Metadata) GetTotalCount() int32 {
|
||||
if x != nil {
|
||||
return x.TotalCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ListProjectsResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Data []*GetProjectResponse `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
|
||||
Meta *Metadata `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) Reset() {
|
||||
*x = ListProjectsResponse{}
|
||||
mi := &file_project_v1_project_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListProjectsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_project_v1_project_proto_msgTypes[4]
|
||||
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 ListProjectsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListProjectsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_project_v1_project_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) GetData() []*GetProjectResponse {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ListProjectsResponse) GetMeta() *Metadata {
|
||||
if x != nil {
|
||||
return x.Meta
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_project_v1_project_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_project_v1_project_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x18project/v1/project.proto\x12\n" +
|
||||
"project.v1\"#\n" +
|
||||
"\x11GetProjectRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x05R\x02id\"\xeb\x02\n" +
|
||||
"\x12GetProjectResponse\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x01(\tR\x04name\x12 \n" +
|
||||
"\vdescription\x18\x03 \x01(\tR\vdescription\x12,\n" +
|
||||
"\x0fis_materialized\x18\x05 \x01(\bH\x00R\x0eisMaterialized\x88\x01\x01\x12,\n" +
|
||||
"\x0fis_personalized\x18\x06 \x01(\bH\x01R\x0eisPersonalized\x88\x01\x01\x12&\n" +
|
||||
"\fis_confirmed\x18\a \x01(\bH\x02R\visConfirmed\x88\x01\x01\x12\x1c\n" +
|
||||
"\ais_paid\x18\b \x01(\bH\x03R\x06isPaid\x88\x01\x01\x12\x1c\n" +
|
||||
"\ais_done\x18\t \x01(\bH\x04R\x06isDone\x88\x01\x01B\x12\n" +
|
||||
"\x10_is_materializedB\x12\n" +
|
||||
"\x10_is_personalizedB\x0f\n" +
|
||||
"\r_is_confirmedB\n" +
|
||||
"\n" +
|
||||
"\b_is_paidB\n" +
|
||||
"\n" +
|
||||
"\b_is_done\"q\n" +
|
||||
"\x13ListProjectsRequest\x12\x12\n" +
|
||||
"\x04page\x18\x01 \x01(\x05R\x04page\x12\x19\n" +
|
||||
"\bper_page\x18\x02 \x01(\x05R\aperPage\x12\x19\n" +
|
||||
"\borber_by\x18\x03 \x01(\tR\aorberBy\x12\x10\n" +
|
||||
"\x03asc\x18\x04 \x01(\bR\x03asc\"*\n" +
|
||||
"\bMetadata\x12\x1e\n" +
|
||||
"\n" +
|
||||
"totalCount\x18\x01 \x01(\x05R\n" +
|
||||
"totalCount\"t\n" +
|
||||
"\x14ListProjectsResponse\x122\n" +
|
||||
"\x04data\x18\x01 \x03(\v2\x1e.project.v1.GetProjectResponseR\x04data\x12(\n" +
|
||||
"\x04meta\x18\x02 \x01(\v2\x14.project.v1.MetadataR\x04meta2\xb0\x01\n" +
|
||||
"\x0eProjectService\x12K\n" +
|
||||
"\n" +
|
||||
"GetProject\x12\x1d.project.v1.GetProjectRequest\x1a\x1e.project.v1.GetProjectResponse\x12Q\n" +
|
||||
"\fListProjects\x12\x1f.project.v1.ListProjectsRequest\x1a .project.v1.ListProjectsResponseB\x9c\x01\n" +
|
||||
"\x0ecom.project.v1B\fProjectProtoP\x01Z3git.kocoder.xyz/kocoded/vt/gen/project/v1;projectv1\xa2\x02\x03PXX\xaa\x02\n" +
|
||||
"Project.V1\xca\x02\n" +
|
||||
"Project\\V1\xe2\x02\x16Project\\V1\\GPBMetadata\xea\x02\vProject::V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_project_v1_project_proto_rawDescOnce sync.Once
|
||||
file_project_v1_project_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_project_v1_project_proto_rawDescGZIP() []byte {
|
||||
file_project_v1_project_proto_rawDescOnce.Do(func() {
|
||||
file_project_v1_project_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_project_v1_project_proto_rawDesc), len(file_project_v1_project_proto_rawDesc)))
|
||||
})
|
||||
return file_project_v1_project_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_project_v1_project_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_project_v1_project_proto_goTypes = []any{
|
||||
(*GetProjectRequest)(nil), // 0: project.v1.GetProjectRequest
|
||||
(*GetProjectResponse)(nil), // 1: project.v1.GetProjectResponse
|
||||
(*ListProjectsRequest)(nil), // 2: project.v1.ListProjectsRequest
|
||||
(*Metadata)(nil), // 3: project.v1.Metadata
|
||||
(*ListProjectsResponse)(nil), // 4: project.v1.ListProjectsResponse
|
||||
}
|
||||
var file_project_v1_project_proto_depIdxs = []int32{
|
||||
1, // 0: project.v1.ListProjectsResponse.data:type_name -> project.v1.GetProjectResponse
|
||||
3, // 1: project.v1.ListProjectsResponse.meta:type_name -> project.v1.Metadata
|
||||
0, // 2: project.v1.ProjectService.GetProject:input_type -> project.v1.GetProjectRequest
|
||||
2, // 3: project.v1.ProjectService.ListProjects:input_type -> project.v1.ListProjectsRequest
|
||||
1, // 4: project.v1.ProjectService.GetProject:output_type -> project.v1.GetProjectResponse
|
||||
4, // 5: project.v1.ProjectService.ListProjects:output_type -> project.v1.ListProjectsResponse
|
||||
4, // [4:6] is the sub-list for method output_type
|
||||
2, // [2:4] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_project_v1_project_proto_init() }
|
||||
func file_project_v1_project_proto_init() {
|
||||
if File_project_v1_project_proto != nil {
|
||||
return
|
||||
}
|
||||
file_project_v1_project_proto_msgTypes[1].OneofWrappers = []any{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_project_v1_project_proto_rawDesc), len(file_project_v1_project_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_project_v1_project_proto_goTypes,
|
||||
DependencyIndexes: file_project_v1_project_proto_depIdxs,
|
||||
MessageInfos: file_project_v1_project_proto_msgTypes,
|
||||
}.Build()
|
||||
File_project_v1_project_proto = out.File
|
||||
file_project_v1_project_proto_goTypes = nil
|
||||
file_project_v1_project_proto_depIdxs = nil
|
||||
}
|
||||
146
gen/project/v1/projectv1connect/project.connect.go
Normal file
146
gen/project/v1/projectv1connect/project.connect.go
Normal file
@@ -0,0 +1,146 @@
|
||||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: project/v1/project.proto
|
||||
|
||||
package projectv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "git.kocoder.xyz/kocoded/vt/gen/project/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// ProjectServiceName is the fully-qualified name of the ProjectService service.
|
||||
ProjectServiceName = "project.v1.ProjectService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// ProjectServiceGetProjectProcedure is the fully-qualified name of the ProjectService's GetProject
|
||||
// RPC.
|
||||
ProjectServiceGetProjectProcedure = "/project.v1.ProjectService/GetProject"
|
||||
// ProjectServiceListProjectsProcedure is the fully-qualified name of the ProjectService's
|
||||
// ListProjects RPC.
|
||||
ProjectServiceListProjectsProcedure = "/project.v1.ProjectService/ListProjects"
|
||||
)
|
||||
|
||||
// ProjectServiceClient is a client for the project.v1.ProjectService service.
|
||||
type ProjectServiceClient interface {
|
||||
GetProject(context.Context, *v1.GetProjectRequest) (*v1.GetProjectResponse, error)
|
||||
ListProjects(context.Context, *v1.ListProjectsRequest) (*v1.ListProjectsResponse, error)
|
||||
}
|
||||
|
||||
// NewProjectServiceClient constructs a client for the project.v1.ProjectService service. By
|
||||
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
|
||||
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewProjectServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) ProjectServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
projectServiceMethods := v1.File_project_v1_project_proto.Services().ByName("ProjectService").Methods()
|
||||
return &projectServiceClient{
|
||||
getProject: connect.NewClient[v1.GetProjectRequest, v1.GetProjectResponse](
|
||||
httpClient,
|
||||
baseURL+ProjectServiceGetProjectProcedure,
|
||||
connect.WithSchema(projectServiceMethods.ByName("GetProject")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listProjects: connect.NewClient[v1.ListProjectsRequest, v1.ListProjectsResponse](
|
||||
httpClient,
|
||||
baseURL+ProjectServiceListProjectsProcedure,
|
||||
connect.WithSchema(projectServiceMethods.ByName("ListProjects")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// projectServiceClient implements ProjectServiceClient.
|
||||
type projectServiceClient struct {
|
||||
getProject *connect.Client[v1.GetProjectRequest, v1.GetProjectResponse]
|
||||
listProjects *connect.Client[v1.ListProjectsRequest, v1.ListProjectsResponse]
|
||||
}
|
||||
|
||||
// GetProject calls project.v1.ProjectService.GetProject.
|
||||
func (c *projectServiceClient) GetProject(ctx context.Context, req *v1.GetProjectRequest) (*v1.GetProjectResponse, error) {
|
||||
response, err := c.getProject.CallUnary(ctx, connect.NewRequest(req))
|
||||
if response != nil {
|
||||
return response.Msg, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ListProjects calls project.v1.ProjectService.ListProjects.
|
||||
func (c *projectServiceClient) ListProjects(ctx context.Context, req *v1.ListProjectsRequest) (*v1.ListProjectsResponse, error) {
|
||||
response, err := c.listProjects.CallUnary(ctx, connect.NewRequest(req))
|
||||
if response != nil {
|
||||
return response.Msg, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ProjectServiceHandler is an implementation of the project.v1.ProjectService service.
|
||||
type ProjectServiceHandler interface {
|
||||
GetProject(context.Context, *v1.GetProjectRequest) (*v1.GetProjectResponse, error)
|
||||
ListProjects(context.Context, *v1.ListProjectsRequest) (*v1.ListProjectsResponse, error)
|
||||
}
|
||||
|
||||
// NewProjectServiceHandler builds an HTTP handler from the service implementation. It returns the
|
||||
// path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewProjectServiceHandler(svc ProjectServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
projectServiceMethods := v1.File_project_v1_project_proto.Services().ByName("ProjectService").Methods()
|
||||
projectServiceGetProjectHandler := connect.NewUnaryHandlerSimple(
|
||||
ProjectServiceGetProjectProcedure,
|
||||
svc.GetProject,
|
||||
connect.WithSchema(projectServiceMethods.ByName("GetProject")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
projectServiceListProjectsHandler := connect.NewUnaryHandlerSimple(
|
||||
ProjectServiceListProjectsProcedure,
|
||||
svc.ListProjects,
|
||||
connect.WithSchema(projectServiceMethods.ByName("ListProjects")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/project.v1.ProjectService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case ProjectServiceGetProjectProcedure:
|
||||
projectServiceGetProjectHandler.ServeHTTP(w, r)
|
||||
case ProjectServiceListProjectsProcedure:
|
||||
projectServiceListProjectsHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedProjectServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedProjectServiceHandler struct{}
|
||||
|
||||
func (UnimplementedProjectServiceHandler) GetProject(context.Context, *v1.GetProjectRequest) (*v1.GetProjectResponse, error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("project.v1.ProjectService.GetProject is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedProjectServiceHandler) ListProjects(context.Context, *v1.ListProjectsRequest) (*v1.ListProjectsResponse, error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("project.v1.ProjectService.ListProjects is not implemented"))
|
||||
}
|
||||
645
gen/todo/v1/todo.pb.go
Normal file
645
gen/todo/v1/todo.pb.go
Normal file
@@ -0,0 +1,645 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: todo/v1/todo.proto
|
||||
|
||||
package todov1
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Status int32
|
||||
|
||||
const (
|
||||
Status_Todo Status = 0
|
||||
Status_NeedsMoreInfo Status = 1
|
||||
Status_Doing Status = 2
|
||||
Status_Done Status = 3
|
||||
)
|
||||
|
||||
// Enum value maps for Status.
|
||||
var (
|
||||
Status_name = map[int32]string{
|
||||
0: "Todo",
|
||||
1: "NeedsMoreInfo",
|
||||
2: "Doing",
|
||||
3: "Done",
|
||||
}
|
||||
Status_value = map[string]int32{
|
||||
"Todo": 0,
|
||||
"NeedsMoreInfo": 1,
|
||||
"Doing": 2,
|
||||
"Done": 3,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Status) Enum() *Status {
|
||||
p := new(Status)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Status) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Status) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_todo_v1_todo_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Status) Type() protoreflect.EnumType {
|
||||
return &file_todo_v1_todo_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Status) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Status.Descriptor instead.
|
||||
func (Status) EnumDescriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type Field int32
|
||||
|
||||
const (
|
||||
Field_FieldId Field = 0
|
||||
Field_FieldTitle Field = 1
|
||||
Field_FieldDescription Field = 2
|
||||
Field_FieldStatus Field = 3
|
||||
)
|
||||
|
||||
// Enum value maps for Field.
|
||||
var (
|
||||
Field_name = map[int32]string{
|
||||
0: "FieldId",
|
||||
1: "FieldTitle",
|
||||
2: "FieldDescription",
|
||||
3: "FieldStatus",
|
||||
}
|
||||
Field_value = map[string]int32{
|
||||
"FieldId": 0,
|
||||
"FieldTitle": 1,
|
||||
"FieldDescription": 2,
|
||||
"FieldStatus": 3,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Field) Enum() *Field {
|
||||
p := new(Field)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Field) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Field) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_todo_v1_todo_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (Field) Type() protoreflect.EnumType {
|
||||
return &file_todo_v1_todo_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x Field) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Field.Descriptor instead.
|
||||
func (Field) EnumDescriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type Operation int32
|
||||
|
||||
const (
|
||||
Operation_Equals Operation = 0
|
||||
Operation_NotEquals Operation = 1
|
||||
Operation_GreaterThan Operation = 2
|
||||
Operation_LessThan Operation = 3
|
||||
Operation_Like Operation = 4
|
||||
)
|
||||
|
||||
// Enum value maps for Operation.
|
||||
var (
|
||||
Operation_name = map[int32]string{
|
||||
0: "Equals",
|
||||
1: "NotEquals",
|
||||
2: "GreaterThan",
|
||||
3: "LessThan",
|
||||
4: "Like",
|
||||
}
|
||||
Operation_value = map[string]int32{
|
||||
"Equals": 0,
|
||||
"NotEquals": 1,
|
||||
"GreaterThan": 2,
|
||||
"LessThan": 3,
|
||||
"Like": 4,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Operation) Enum() *Operation {
|
||||
p := new(Operation)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Operation) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Operation) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_todo_v1_todo_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (Operation) Type() protoreflect.EnumType {
|
||||
return &file_todo_v1_todo_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x Operation) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Operation.Descriptor instead.
|
||||
func (Operation) EnumDescriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type GetTodosRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetTodosRequest) Reset() {
|
||||
*x = GetTodosRequest{}
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetTodosRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetTodosRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetTodosRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[0]
|
||||
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 GetTodosRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetTodosRequest) Descriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *GetTodosRequest) GetId() int32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type GetTodosResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
|
||||
Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Status Status `protobuf:"varint,4,opt,name=status,proto3,enum=todo.v1.Status" json:"status,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetTodosResponse) Reset() {
|
||||
*x = GetTodosResponse{}
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *GetTodosResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetTodosResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetTodosResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[1]
|
||||
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 GetTodosResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetTodosResponse) Descriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GetTodosResponse) GetId() int64 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GetTodosResponse) GetTitle() string {
|
||||
if x != nil {
|
||||
return x.Title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetTodosResponse) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GetTodosResponse) GetStatus() Status {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return Status_Todo
|
||||
}
|
||||
|
||||
type ListTodosRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
|
||||
PerPage int32 `protobuf:"varint,2,opt,name=per_page,json=perPage,proto3" json:"per_page,omitempty"`
|
||||
OrberBy string `protobuf:"bytes,3,opt,name=orber_by,json=orberBy,proto3" json:"orber_by,omitempty"`
|
||||
Asc bool `protobuf:"varint,4,opt,name=asc,proto3" json:"asc,omitempty"`
|
||||
Filters []*Filter `protobuf:"bytes,5,rep,name=filters,proto3" json:"filters,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListTodosRequest) Reset() {
|
||||
*x = ListTodosRequest{}
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListTodosRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListTodosRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListTodosRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[2]
|
||||
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 ListTodosRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListTodosRequest) Descriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ListTodosRequest) GetPage() int32 {
|
||||
if x != nil {
|
||||
return x.Page
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ListTodosRequest) GetPerPage() int32 {
|
||||
if x != nil {
|
||||
return x.PerPage
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ListTodosRequest) GetOrberBy() string {
|
||||
if x != nil {
|
||||
return x.OrberBy
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ListTodosRequest) GetAsc() bool {
|
||||
if x != nil {
|
||||
return x.Asc
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *ListTodosRequest) GetFilters() []*Filter {
|
||||
if x != nil {
|
||||
return x.Filters
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Field Field `protobuf:"varint,1,opt,name=field,proto3,enum=todo.v1.Field" json:"field,omitempty"`
|
||||
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
Operation Operation `protobuf:"varint,3,opt,name=operation,proto3,enum=todo.v1.Operation" json:"operation,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Filter) Reset() {
|
||||
*x = Filter{}
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Filter) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Filter) ProtoMessage() {}
|
||||
|
||||
func (x *Filter) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[3]
|
||||
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 Filter.ProtoReflect.Descriptor instead.
|
||||
func (*Filter) Descriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *Filter) GetField() Field {
|
||||
if x != nil {
|
||||
return x.Field
|
||||
}
|
||||
return Field_FieldId
|
||||
}
|
||||
|
||||
func (x *Filter) GetValue() string {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Filter) GetOperation() Operation {
|
||||
if x != nil {
|
||||
return x.Operation
|
||||
}
|
||||
return Operation_Equals
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
TotalCount int32 `protobuf:"varint,1,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Metadata) Reset() {
|
||||
*x = Metadata{}
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Metadata) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Metadata) ProtoMessage() {}
|
||||
|
||||
func (x *Metadata) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[4]
|
||||
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 Metadata.ProtoReflect.Descriptor instead.
|
||||
func (*Metadata) Descriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *Metadata) GetTotalCount() int32 {
|
||||
if x != nil {
|
||||
return x.TotalCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ListTodosResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Data []*GetTodosResponse `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"`
|
||||
Meta *Metadata `protobuf:"bytes,2,opt,name=meta,proto3" json:"meta,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListTodosResponse) Reset() {
|
||||
*x = ListTodosResponse{}
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListTodosResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListTodosResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListTodosResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_todo_v1_todo_proto_msgTypes[5]
|
||||
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 ListTodosResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListTodosResponse) Descriptor() ([]byte, []int) {
|
||||
return file_todo_v1_todo_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *ListTodosResponse) GetData() []*GetTodosResponse {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ListTodosResponse) GetMeta() *Metadata {
|
||||
if x != nil {
|
||||
return x.Meta
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_todo_v1_todo_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_todo_v1_todo_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x12todo/v1/todo.proto\x12\atodo.v1\"!\n" +
|
||||
"\x0fGetTodosRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x05R\x02id\"\x83\x01\n" +
|
||||
"\x10GetTodosResponse\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x14\n" +
|
||||
"\x05title\x18\x02 \x01(\tR\x05title\x12 \n" +
|
||||
"\vdescription\x18\x03 \x01(\tR\vdescription\x12'\n" +
|
||||
"\x06status\x18\x04 \x01(\x0e2\x0f.todo.v1.StatusR\x06status\"\x99\x01\n" +
|
||||
"\x10ListTodosRequest\x12\x12\n" +
|
||||
"\x04page\x18\x01 \x01(\x05R\x04page\x12\x19\n" +
|
||||
"\bper_page\x18\x02 \x01(\x05R\aperPage\x12\x19\n" +
|
||||
"\borber_by\x18\x03 \x01(\tR\aorberBy\x12\x10\n" +
|
||||
"\x03asc\x18\x04 \x01(\bR\x03asc\x12)\n" +
|
||||
"\afilters\x18\x05 \x03(\v2\x0f.todo.v1.FilterR\afilters\"v\n" +
|
||||
"\x06Filter\x12$\n" +
|
||||
"\x05field\x18\x01 \x01(\x0e2\x0e.todo.v1.FieldR\x05field\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value\x120\n" +
|
||||
"\toperation\x18\x03 \x01(\x0e2\x12.todo.v1.OperationR\toperation\"*\n" +
|
||||
"\bMetadata\x12\x1e\n" +
|
||||
"\n" +
|
||||
"totalCount\x18\x01 \x01(\x05R\n" +
|
||||
"totalCount\"i\n" +
|
||||
"\x11ListTodosResponse\x12-\n" +
|
||||
"\x04data\x18\x01 \x03(\v2\x19.todo.v1.GetTodosResponseR\x04data\x12%\n" +
|
||||
"\x04meta\x18\x02 \x01(\v2\x11.todo.v1.MetadataR\x04meta*:\n" +
|
||||
"\x06Status\x12\b\n" +
|
||||
"\x04Todo\x10\x00\x12\x11\n" +
|
||||
"\rNeedsMoreInfo\x10\x01\x12\t\n" +
|
||||
"\x05Doing\x10\x02\x12\b\n" +
|
||||
"\x04Done\x10\x03*K\n" +
|
||||
"\x05Field\x12\v\n" +
|
||||
"\aFieldId\x10\x00\x12\x0e\n" +
|
||||
"\n" +
|
||||
"FieldTitle\x10\x01\x12\x14\n" +
|
||||
"\x10FieldDescription\x10\x02\x12\x0f\n" +
|
||||
"\vFieldStatus\x10\x03*O\n" +
|
||||
"\tOperation\x12\n" +
|
||||
"\n" +
|
||||
"\x06Equals\x10\x00\x12\r\n" +
|
||||
"\tNotEquals\x10\x01\x12\x0f\n" +
|
||||
"\vGreaterThan\x10\x02\x12\f\n" +
|
||||
"\bLessThan\x10\x03\x12\b\n" +
|
||||
"\x04Like\x10\x042\x91\x01\n" +
|
||||
"\vTodoService\x12>\n" +
|
||||
"\aGetTodo\x12\x18.todo.v1.GetTodosRequest\x1a\x19.todo.v1.GetTodosResponse\x12B\n" +
|
||||
"\tListTodos\x12\x19.todo.v1.ListTodosRequest\x1a\x1a.todo.v1.ListTodosResponseB\x84\x01\n" +
|
||||
"\vcom.todo.v1B\tTodoProtoP\x01Z-git.kocoder.xyz/kocoded/vt/gen/todo/v1;todov1\xa2\x02\x03TXX\xaa\x02\aTodo.V1\xca\x02\aTodo\\V1\xe2\x02\x13Todo\\V1\\GPBMetadata\xea\x02\bTodo::V1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_todo_v1_todo_proto_rawDescOnce sync.Once
|
||||
file_todo_v1_todo_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_todo_v1_todo_proto_rawDescGZIP() []byte {
|
||||
file_todo_v1_todo_proto_rawDescOnce.Do(func() {
|
||||
file_todo_v1_todo_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_todo_v1_todo_proto_rawDesc), len(file_todo_v1_todo_proto_rawDesc)))
|
||||
})
|
||||
return file_todo_v1_todo_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_todo_v1_todo_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
||||
var file_todo_v1_todo_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_todo_v1_todo_proto_goTypes = []any{
|
||||
(Status)(0), // 0: todo.v1.Status
|
||||
(Field)(0), // 1: todo.v1.Field
|
||||
(Operation)(0), // 2: todo.v1.Operation
|
||||
(*GetTodosRequest)(nil), // 3: todo.v1.GetTodosRequest
|
||||
(*GetTodosResponse)(nil), // 4: todo.v1.GetTodosResponse
|
||||
(*ListTodosRequest)(nil), // 5: todo.v1.ListTodosRequest
|
||||
(*Filter)(nil), // 6: todo.v1.Filter
|
||||
(*Metadata)(nil), // 7: todo.v1.Metadata
|
||||
(*ListTodosResponse)(nil), // 8: todo.v1.ListTodosResponse
|
||||
}
|
||||
var file_todo_v1_todo_proto_depIdxs = []int32{
|
||||
0, // 0: todo.v1.GetTodosResponse.status:type_name -> todo.v1.Status
|
||||
6, // 1: todo.v1.ListTodosRequest.filters:type_name -> todo.v1.Filter
|
||||
1, // 2: todo.v1.Filter.field:type_name -> todo.v1.Field
|
||||
2, // 3: todo.v1.Filter.operation:type_name -> todo.v1.Operation
|
||||
4, // 4: todo.v1.ListTodosResponse.data:type_name -> todo.v1.GetTodosResponse
|
||||
7, // 5: todo.v1.ListTodosResponse.meta:type_name -> todo.v1.Metadata
|
||||
3, // 6: todo.v1.TodoService.GetTodo:input_type -> todo.v1.GetTodosRequest
|
||||
5, // 7: todo.v1.TodoService.ListTodos:input_type -> todo.v1.ListTodosRequest
|
||||
4, // 8: todo.v1.TodoService.GetTodo:output_type -> todo.v1.GetTodosResponse
|
||||
8, // 9: todo.v1.TodoService.ListTodos:output_type -> todo.v1.ListTodosResponse
|
||||
8, // [8:10] is the sub-list for method output_type
|
||||
6, // [6:8] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_todo_v1_todo_proto_init() }
|
||||
func file_todo_v1_todo_proto_init() {
|
||||
if File_todo_v1_todo_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_todo_v1_todo_proto_rawDesc), len(file_todo_v1_todo_proto_rawDesc)),
|
||||
NumEnums: 3,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_todo_v1_todo_proto_goTypes,
|
||||
DependencyIndexes: file_todo_v1_todo_proto_depIdxs,
|
||||
EnumInfos: file_todo_v1_todo_proto_enumTypes,
|
||||
MessageInfos: file_todo_v1_todo_proto_msgTypes,
|
||||
}.Build()
|
||||
File_todo_v1_todo_proto = out.File
|
||||
file_todo_v1_todo_proto_goTypes = nil
|
||||
file_todo_v1_todo_proto_depIdxs = nil
|
||||
}
|
||||
144
gen/todo/v1/todov1connect/todo.connect.go
Normal file
144
gen/todo/v1/todov1connect/todo.connect.go
Normal file
@@ -0,0 +1,144 @@
|
||||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: todo/v1/todo.proto
|
||||
|
||||
package todov1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "git.kocoder.xyz/kocoded/vt/gen/todo/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// TodoServiceName is the fully-qualified name of the TodoService service.
|
||||
TodoServiceName = "todo.v1.TodoService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// TodoServiceGetTodoProcedure is the fully-qualified name of the TodoService's GetTodo RPC.
|
||||
TodoServiceGetTodoProcedure = "/todo.v1.TodoService/GetTodo"
|
||||
// TodoServiceListTodosProcedure is the fully-qualified name of the TodoService's ListTodos RPC.
|
||||
TodoServiceListTodosProcedure = "/todo.v1.TodoService/ListTodos"
|
||||
)
|
||||
|
||||
// TodoServiceClient is a client for the todo.v1.TodoService service.
|
||||
type TodoServiceClient interface {
|
||||
GetTodo(context.Context, *v1.GetTodosRequest) (*v1.GetTodosResponse, error)
|
||||
ListTodos(context.Context, *v1.ListTodosRequest) (*v1.ListTodosResponse, error)
|
||||
}
|
||||
|
||||
// NewTodoServiceClient constructs a client for the todo.v1.TodoService service. By default, it uses
|
||||
// the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
|
||||
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
|
||||
// connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewTodoServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) TodoServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
todoServiceMethods := v1.File_todo_v1_todo_proto.Services().ByName("TodoService").Methods()
|
||||
return &todoServiceClient{
|
||||
getTodo: connect.NewClient[v1.GetTodosRequest, v1.GetTodosResponse](
|
||||
httpClient,
|
||||
baseURL+TodoServiceGetTodoProcedure,
|
||||
connect.WithSchema(todoServiceMethods.ByName("GetTodo")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listTodos: connect.NewClient[v1.ListTodosRequest, v1.ListTodosResponse](
|
||||
httpClient,
|
||||
baseURL+TodoServiceListTodosProcedure,
|
||||
connect.WithSchema(todoServiceMethods.ByName("ListTodos")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// todoServiceClient implements TodoServiceClient.
|
||||
type todoServiceClient struct {
|
||||
getTodo *connect.Client[v1.GetTodosRequest, v1.GetTodosResponse]
|
||||
listTodos *connect.Client[v1.ListTodosRequest, v1.ListTodosResponse]
|
||||
}
|
||||
|
||||
// GetTodo calls todo.v1.TodoService.GetTodo.
|
||||
func (c *todoServiceClient) GetTodo(ctx context.Context, req *v1.GetTodosRequest) (*v1.GetTodosResponse, error) {
|
||||
response, err := c.getTodo.CallUnary(ctx, connect.NewRequest(req))
|
||||
if response != nil {
|
||||
return response.Msg, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ListTodos calls todo.v1.TodoService.ListTodos.
|
||||
func (c *todoServiceClient) ListTodos(ctx context.Context, req *v1.ListTodosRequest) (*v1.ListTodosResponse, error) {
|
||||
response, err := c.listTodos.CallUnary(ctx, connect.NewRequest(req))
|
||||
if response != nil {
|
||||
return response.Msg, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TodoServiceHandler is an implementation of the todo.v1.TodoService service.
|
||||
type TodoServiceHandler interface {
|
||||
GetTodo(context.Context, *v1.GetTodosRequest) (*v1.GetTodosResponse, error)
|
||||
ListTodos(context.Context, *v1.ListTodosRequest) (*v1.ListTodosResponse, error)
|
||||
}
|
||||
|
||||
// NewTodoServiceHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
// on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewTodoServiceHandler(svc TodoServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
todoServiceMethods := v1.File_todo_v1_todo_proto.Services().ByName("TodoService").Methods()
|
||||
todoServiceGetTodoHandler := connect.NewUnaryHandlerSimple(
|
||||
TodoServiceGetTodoProcedure,
|
||||
svc.GetTodo,
|
||||
connect.WithSchema(todoServiceMethods.ByName("GetTodo")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
todoServiceListTodosHandler := connect.NewUnaryHandlerSimple(
|
||||
TodoServiceListTodosProcedure,
|
||||
svc.ListTodos,
|
||||
connect.WithSchema(todoServiceMethods.ByName("ListTodos")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/todo.v1.TodoService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case TodoServiceGetTodoProcedure:
|
||||
todoServiceGetTodoHandler.ServeHTTP(w, r)
|
||||
case TodoServiceListTodosProcedure:
|
||||
todoServiceListTodosHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedTodoServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedTodoServiceHandler struct{}
|
||||
|
||||
func (UnimplementedTodoServiceHandler) GetTodo(context.Context, *v1.GetTodosRequest) (*v1.GetTodosResponse, error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("todo.v1.TodoService.GetTodo is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedTodoServiceHandler) ListTodos(context.Context, *v1.ListTodosRequest) (*v1.ListTodosResponse, error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("todo.v1.TodoService.ListTodos is not implemented"))
|
||||
}
|
||||
86
go.mod
86
go.mod
@@ -1,12 +1,18 @@
|
||||
module git.kocoder.xyz/kocoded/vt
|
||||
|
||||
go 1.24.4
|
||||
go 1.25
|
||||
|
||||
require (
|
||||
github.com/emersion/go-imap/v2 v2.0.0-beta.6
|
||||
github.com/emersion/go-message v0.18.1
|
||||
github.com/gofiber/fiber/v2 v2.52.9
|
||||
golang.org/x/oauth2 v0.28.0
|
||||
github.com/valkey-io/valkey-glide/go/v2 v2.1.1
|
||||
go.opentelemetry.io/otel v1.39.0
|
||||
go.opentelemetry.io/otel/log v0.15.0
|
||||
go.opentelemetry.io/otel/sdk v1.38.0
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0
|
||||
google.golang.org/protobuf v1.36.9
|
||||
gorm.io/driver/postgres v1.6.0
|
||||
gorm.io/gen v0.3.27
|
||||
gorm.io/gorm v1.30.1
|
||||
@@ -14,26 +20,69 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ClickHouse/ch-go v0.61.5 // indirect
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0 // indirect
|
||||
github.com/StirlingMarketingGroup/go-retry v0.0.0-20190512160921-94a8eb23e893 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect
|
||||
github.com/fasthttp/websocket v1.5.8 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-faster/city v1.0.1 // indirect
|
||||
github.com/go-faster/errors v0.7.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
|
||||
github.com/jhillyerd/enmime v1.3.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/paulmach/orb v0.11.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect
|
||||
github.com/valkey-io/valkey-glide/go/v2 v2.1.1 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
github.com/segmentio/asm v1.2.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sqs/go-xoauth2 v0.0.0-20120917012134-0911dad68e56 // indirect
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
go.uber.org/dig v1.19.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
google.golang.org/grpc v1.75.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/clickhouse v0.7.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
connectrpc.com/connect v1.19.1
|
||||
connectrpc.com/cors v0.1.0
|
||||
connectrpc.com/grpchealth v1.4.0
|
||||
connectrpc.com/grpcreflect v1.3.0
|
||||
connectrpc.com/otelconnect v0.8.0
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/BrianLeishman/go-imap v0.1.20
|
||||
github.com/andybalholm/brotli v1.2.0 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.15.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/coreos/go-oidc/v3 v3.17.0
|
||||
github.com/go-sql-driver/mysql v1.9.3 // indirect
|
||||
github.com/gofiber/contrib/websocket v1.3.4
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.5 // indirect
|
||||
github.com/jackc/pgx/v5 v5.8.0 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
@@ -44,16 +93,23 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/tinylib/msgp v1.3.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.64.0 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/mod v0.27.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0
|
||||
go.uber.org/fx v1.24.0
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/mod v0.30.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
gorm.io/datatypes v1.2.6 // indirect
|
||||
gorm.io/driver/mysql v1.6.0 // indirect
|
||||
gorm.io/hints v1.1.2 // indirect
|
||||
gorm.io/plugin/opentelemetry v0.1.16
|
||||
)
|
||||
|
||||
225
go.sum
225
go.sum
@@ -1,12 +1,38 @@
|
||||
connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14=
|
||||
connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w=
|
||||
connectrpc.com/cors v0.1.0 h1:f3gTXJyDZPrDIZCQ567jxfD9PAIpopHiRDnJRt3QuOQ=
|
||||
connectrpc.com/cors v0.1.0/go.mod h1:v8SJZCPfHtGH1zsm+Ttajpozd4cYIUryl4dFB6QEpfg=
|
||||
connectrpc.com/grpchealth v1.4.0 h1:MJC96JLelARPgZTiRF9KRfY/2N9OcoQvF2EWX07v2IE=
|
||||
connectrpc.com/grpchealth v1.4.0/go.mod h1:WhW6m1EzTmq3Ky1FE8EfkIpSDc6TfUx2M2KqZO3ts/Q=
|
||||
connectrpc.com/grpcreflect v1.3.0 h1:Y4V+ACf8/vOb1XOc251Qun7jMB75gCUNw6llvB9csXc=
|
||||
connectrpc.com/grpcreflect v1.3.0/go.mod h1:nfloOtCS8VUQOQ1+GTdFzVg2CJo4ZGaat8JIovCtDYs=
|
||||
connectrpc.com/otelconnect v0.8.0 h1:a4qrN4H8aEE2jAoCxheZYYfEjXMgVPyL9OzPQLBEFXU=
|
||||
connectrpc.com/otelconnect v0.8.0/go.mod h1:AEkVLjCPXra+ObGFCOClcJkNjS7zPaQSqvO0lCyjfZc=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/BrianLeishman/go-imap v0.1.20 h1:jvkir/v5A7Ml0zAAZyTSq60+WDN54RzRhhPwC9Bw9Bg=
|
||||
github.com/BrianLeishman/go-imap v0.1.20/go.mod h1:MiXltWbhjxLKrYHGivAieizDwQ+oOULASiV9kVMyBLc=
|
||||
github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
|
||||
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0 h1:AG4D/hW39qa58+JHQIFOSnxyL46H6h2lrmGGk17dhFo=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0/go.mod h1:i9ZQAojcayW3RsdCb3YR+n+wC2h65eJsZCscZ1Z1wyo=
|
||||
github.com/StirlingMarketingGroup/go-retry v0.0.0-20190512160921-94a8eb23e893 h1:y1OlgL2twHNQGJ4OTHhvVLebgDCwP4pttmZc2w4UAz8=
|
||||
github.com/StirlingMarketingGroup/go-retry v0.0.0-20190512160921-94a8eb23e893/go.mod h1:RHK0VFlYDZQeNFg4C2dp7cPE6urfbpgyEZIGxa9f5zw=
|
||||
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/coreos/go-oidc/v3 v3.15.0 h1:R6Oz8Z4bqWR7VFQ+sPSvZPQv4x8M+sJkDO5ojgwlyAg=
|
||||
github.com/coreos/go-oidc/v3 v3.15.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc=
|
||||
github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/emersion/go-imap/v2 v2.0.0-beta.6 h1:3w7QGUcDEoZXr+okRZR75VBjX0yvvJqkfy3gibbH2yY=
|
||||
github.com/emersion/go-imap/v2 v2.0.0-beta.6/go.mod h1:BZTFHsS1hmgBkFlHqbxGLXk2hnRqTItUgwjSSCsYNAk=
|
||||
github.com/emersion/go-message v0.18.1 h1:tfTxIoXFSFRwWaZsgnqS1DSZuGpYGzSmCZD8SK3QA2E=
|
||||
@@ -15,44 +41,81 @@ github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 h1:hH4PQfOndHDlpz
|
||||
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/fasthttp/websocket v1.5.8 h1:k5DpirKkftIF/w1R8ZzjSgARJrs54Je9YJK37DL/Ah8=
|
||||
github.com/fasthttp/websocket v1.5.8/go.mod h1:d08g8WaT6nnyvg9uMm8K9zMYyDjfKyj3170AtPRuVU0=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
|
||||
github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
|
||||
github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg=
|
||||
github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/gofiber/contrib/websocket v1.3.4 h1:tWeBdbJ8q0WFQXariLN4dBIbGH9KBU75s0s7YXplOSg=
|
||||
github.com/gofiber/contrib/websocket v1.3.4/go.mod h1:kTFBPC6YENCnKfKx0BoOFjgXxdz7E85/STdkmZPEmPs=
|
||||
github.com/gofiber/fiber/v2 v2.52.9 h1:YjKl5DOiyP3j0mO61u3NTmK7or8GzzWzCFzkboyP5cw=
|
||||
github.com/gofiber/fiber/v2 v2.52.9/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
||||
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||
github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo=
|
||||
github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA=
|
||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||
github.com/jhillyerd/enmime v1.3.0 h1:LV5kzfLidiOr8qRGIpYYmUZCnhrPbcFAnAFUnWn99rw=
|
||||
github.com/jhillyerd/enmime v1.3.0/go.mod h1:6c6jg5HdRRV2FtvVL69LjiX1M8oE0xDX9VEhV3oy4gs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
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-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
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/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
@@ -60,20 +123,46 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
|
||||
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
|
||||
github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
|
||||
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
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=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 h1:KanIMPX0QdEdB4R3CiimCAbxFrhB3j7h0/OvpYGVQa8=
|
||||
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
|
||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/sqs/go-xoauth2 v0.0.0-20120917012134-0911dad68e56 h1:KCgKdj+ha4CgnVHIiJYGKzgZk3HfCc6XssESfOa6atM=
|
||||
github.com/sqs/go-xoauth2 v0.0.0-20120917012134-0911dad68e56/go.mod h1:ghDEBrT4oFcM4rv18bzcZaAWXbHPGpDa4e2hh9oXL8A=
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
|
||||
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
github.com/valkey-io/valkey-glide/go/v2 v2.1.1 h1:78eoWXIYLbse0ZpspKRMwbREj0+Tkoc/qkSR8H9iRsc=
|
||||
@@ -82,32 +171,111 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.64.0 h1:QBygLLQmiAyiXuRhthf0tuRkqAFcrC42dckN2S+N3og=
|
||||
github.com/valyala/fasthttp v1.64.0/go.mod h1:dGmFxwkWXSK0NbOSJuF7AMVzU+lkHz0wQVvVITv2UQA=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0 h1:eypSOd+0txRKCXPNyqLPsbSfA0jULgJcGmSAdFAnrCM=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0/go.mod h1:CRGvIBL/aAxpQU34ZxyQVFlovVcp67s4cAmQu8Jh9mc=
|
||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4=
|
||||
go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=
|
||||
go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=
|
||||
go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY=
|
||||
go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4=
|
||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
||||
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
|
||||
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg=
|
||||
go.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM=
|
||||
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
|
||||
go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=
|
||||
go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||
go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg=
|
||||
go.uber.org/fx v1.24.0/go.mod h1:AmDeGyS+ZARGKM4tlH4FY2Jr63VjbEDJHtqXTGP5hbo=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -115,31 +283,58 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc=
|
||||
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
|
||||
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/datatypes v1.2.6 h1:KafLdXvFUhzNeL2ncm03Gl3eTLONQfNKZ+wJ+9Y4Nck=
|
||||
gorm.io/datatypes v1.2.6/go.mod h1:M2iO+6S3hhi4nAyYe444Pcb0dcIiOMJ7QHaUXxyiNZY=
|
||||
gorm.io/driver/clickhouse v0.7.0 h1:BCrqvgONayvZRgtuA6hdya+eAW5P2QVagV3OlEp1vtA=
|
||||
gorm.io/driver/clickhouse v0.7.0/go.mod h1:TmNo0wcVTsD4BBObiRnCahUgHJHjBIwuRejHwYt3JRs=
|
||||
gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg=
|
||||
gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo=
|
||||
gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
|
||||
@@ -158,3 +353,5 @@ gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o=
|
||||
gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg=
|
||||
gorm.io/plugin/dbresolver v1.6.2 h1:F4b85TenghUeITqe3+epPSUtHH7RIk3fXr5l83DF8Pc=
|
||||
gorm.io/plugin/dbresolver v1.6.2/go.mod h1:tctw63jdrOezFR9HmrKnPkmig3m5Edem9fdxk9bQSzM=
|
||||
gorm.io/plugin/opentelemetry v0.1.16 h1:Kypj2YYAliJqkIczDZDde6P6sFMhKSlG5IpngMFQGpc=
|
||||
gorm.io/plugin/opentelemetry v0.1.16/go.mod h1:P3RmTeZXT+9n0F1ccUqR5uuTvEXDxF8k2UpO7mTIB2Y=
|
||||
|
||||
17
integration/integration_handler.go
Normal file
17
integration/integration_handler.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
type IntegrationHandler struct {
|
||||
}
|
||||
|
||||
func NewIntegrationHandler(integrations []interfaces.BasicIntegration, lc fx.Lifecycle) *IntegrationHandler {
|
||||
for _, i := range integrations {
|
||||
lc.Append(fx.StartStopHook(i.OnStart, i.OnStop))
|
||||
}
|
||||
|
||||
return &IntegrationHandler{}
|
||||
}
|
||||
84
integration/mailing/imap_integration.go
Normal file
84
integration/mailing/imap_integration.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package mailing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces"
|
||||
|
||||
imap "github.com/BrianLeishman/go-imap"
|
||||
)
|
||||
|
||||
type imapIntegration struct {
|
||||
id *imap.Dialer
|
||||
}
|
||||
|
||||
// Invoke implements interfaces.BasicIntegration.
|
||||
func (i *imapIntegration) Invoke() {
|
||||
fmt.Println("Invoked!")
|
||||
}
|
||||
|
||||
// OnStart implements interfaces.BasicIntegration.
|
||||
func (i *imapIntegration) OnStart(ctx context.Context) error {
|
||||
fmt.Println("Integration IMAP started")
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnStop implements interfaces.BasicIntegration.
|
||||
func (i *imapIntegration) OnStop(ctx context.Context) error {
|
||||
fmt.Println("Integration IMAP stopped")
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewImapIntegration() interfaces.BasicIntegration {
|
||||
fmt.Println("New Imap Integration")
|
||||
|
||||
imap.Verbose = true
|
||||
imap.RetryCount = 1
|
||||
imap.DialTimeout = 10 * time.Second
|
||||
imap.CommandTimeout = 30 * time.Second
|
||||
|
||||
m, err := imap.New("me@kocoder.xyz", "&,25,upMeddeEnTYPTifaccEptIonaAlErGiE", "mx.kocoder.xyz", 993)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := m.SelectFolder("INBOX"); err != nil {
|
||||
panic("Failed to select inbox")
|
||||
}
|
||||
|
||||
uids, err := m.GetUIDs("UNSEEN")
|
||||
if err != nil {
|
||||
panic("Search")
|
||||
}
|
||||
|
||||
emails, err := m.GetEmails(uids[:5]...)
|
||||
if err != nil {
|
||||
panic("Getting EMails")
|
||||
}
|
||||
|
||||
for uid, email := range emails {
|
||||
fmt.Printf("\n--- Email UID %d ---\n", uid)
|
||||
fmt.Printf("From: %s\n", email.From)
|
||||
fmt.Printf("Subject: %s\n", email.Subject)
|
||||
fmt.Printf("Date: %s\n", email.Sent.Format("Jan 2, 2006 3:04 PM"))
|
||||
fmt.Printf("Size: %.1f KB\n", float64(email.Size)/1024)
|
||||
|
||||
if len(email.Text) > 100 {
|
||||
fmt.Printf("Preview: %.100s...\n", email.Text)
|
||||
} else if len(email.Text) > 0 {
|
||||
fmt.Printf("Preview: %s\n", email.Text)
|
||||
}
|
||||
|
||||
if len(email.Attachments) > 0 {
|
||||
fmt.Printf("Attachments: %d\n", len(email.Attachments))
|
||||
for _, att := range email.Attachments {
|
||||
fmt.Printf(" - %s (%.1f KB)\n", att.Name, float64(len(att.Content))/1024)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &imapIntegration{id: m}
|
||||
}
|
||||
116
interceptors/auth.go
Normal file
116
interceptors/auth.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package interceptors
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"git.kocoder.xyz/kocoded/vt/cmd/mailingest/query"
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces/stores"
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const tokenHeader = "authentication"
|
||||
const alternativeTokenHeader = "Authorization"
|
||||
|
||||
type AuthenticationInterceptor struct {
|
||||
verifier *oidc.IDTokenVerifier
|
||||
sr stores.SessionStore
|
||||
logger *slog.Logger
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// WrapStreamingClient implements connect.Interceptor.
|
||||
func (a *AuthenticationInterceptor) WrapStreamingClient(connect.StreamingClientFunc) connect.StreamingClientFunc {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// WrapStreamingHandler implements connect.Interceptor.
|
||||
func (a *AuthenticationInterceptor) WrapStreamingHandler(connect.StreamingHandlerFunc) connect.StreamingHandlerFunc {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// WrapUnary implements connect.Interceptor.
|
||||
func (a *AuthenticationInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFunc {
|
||||
return func(
|
||||
ctx context.Context,
|
||||
req connect.AnyRequest,
|
||||
) (connect.AnyResponse, error) {
|
||||
if req.Spec().IsClient {
|
||||
panic(errors.New(""))
|
||||
} else {
|
||||
authToken := req.Header().Get(tokenHeader)
|
||||
if authToken == "" {
|
||||
authToken = req.Header().Get(alternativeTokenHeader)
|
||||
}
|
||||
|
||||
if ok := strings.HasPrefix(authToken, "Bearer "); !ok {
|
||||
a.logger.Info("No Authtoken with Bearer Prefix provided")
|
||||
return nil, connect.NewError(
|
||||
connect.CodeUnauthenticated,
|
||||
errors.New("No valid token provided"),
|
||||
)
|
||||
}
|
||||
authToken = strings.TrimPrefix(authToken, "Bearer ")
|
||||
|
||||
IDToken, err := a.verifier.Verify(context.TODO(), authToken)
|
||||
if err != nil {
|
||||
a.logger.Info("No valid/verifyable Authtoken provided", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
session, err := a.sr.GetSessionFromToken(IDToken.Subject)
|
||||
|
||||
if err != nil {
|
||||
|
||||
q := query.Use(a.db)
|
||||
u := q.User
|
||||
|
||||
claims := model.User{}
|
||||
|
||||
if err := IDToken.Claims(&claims); err != nil {
|
||||
a.logger.Error("Failed to parse claims from IDToken", "err", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
a.logger.Info("Parsed Claims", "claims", claims)
|
||||
|
||||
us, err := u.Where(u.Sub.Eq(IDToken.Subject)).Assign(field.Attrs(&claims)).FirstOrCreate()
|
||||
if err != nil {
|
||||
a.logger.Error("Failed to get or create user from DB", "err", err, "sub", IDToken.Subject)
|
||||
return nil, connect.NewError(connect.CodeInternal, errors.New("Failed to create user in DB"))
|
||||
}
|
||||
|
||||
session = &stores.Session{Token: IDToken.Subject, UserID: us.ID, MandantId: 1}
|
||||
a.sr.AddSession(session)
|
||||
}
|
||||
|
||||
ctx = NewSessionContext(ctx, session)
|
||||
}
|
||||
|
||||
return next(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
func NewOIDCInterceptor(verifier *oidc.IDTokenVerifier, sr stores.SessionStore, logger *slog.Logger, db *gorm.DB) *AuthenticationInterceptor {
|
||||
return &AuthenticationInterceptor{verifier: verifier, sr: sr, logger: logger, db: db}
|
||||
}
|
||||
|
||||
type key int
|
||||
|
||||
var sessionKey key
|
||||
|
||||
func NewSessionContext(ctx context.Context, u *stores.Session) context.Context {
|
||||
return context.WithValue(ctx, sessionKey, u)
|
||||
}
|
||||
|
||||
// FromContext returns the User value stored in ctx, if any.
|
||||
func SessionFromContext(ctx context.Context) (*stores.Session, bool) {
|
||||
u, ok := ctx.Value(sessionKey).(*stores.Session)
|
||||
return u, ok
|
||||
}
|
||||
29
interceptors/db.go
Normal file
29
interceptors/db.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package interceptors
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var dbKey key
|
||||
|
||||
func NewDBContext(ctx context.Context, db *gorm.DB) context.Context {
|
||||
return context.WithValue(ctx, dbKey, db)
|
||||
}
|
||||
|
||||
// FromContext returns the User value stored in ctx, if any.
|
||||
func DBFromContex(ctx context.Context) (*gorm.DB, bool) {
|
||||
u, ok := ctx.Value(dbKey).(*gorm.DB)
|
||||
return u, ok
|
||||
}
|
||||
|
||||
func AddDBToContext(next http.Handler, db *gorm.DB) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
ctx = NewDBContext(ctx, db)
|
||||
r = r.WithContext(ctx)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package model
|
||||
|
||||
import "gorm.io/gorm"
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Projekt struct {
|
||||
gorm.Model
|
||||
|
||||
27
model/task.go
Normal file
27
model/task.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type Status int
|
||||
|
||||
const (
|
||||
Todo Status = iota
|
||||
NeedsMoreInfo
|
||||
Started
|
||||
Done
|
||||
)
|
||||
|
||||
func (s Status) IsDone() bool {
|
||||
return s == Done
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
gorm.Model
|
||||
ProjektID uint
|
||||
Projekt Projekt
|
||||
MandantID uint
|
||||
Mandant Mandant
|
||||
Titel string `json:"titel"`
|
||||
Description string `json:"description"`
|
||||
Status Status `json:"status"`
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
},
|
||||
{
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"path": "../eventory-mobile"
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
|
||||
@@ -33,6 +33,7 @@ var (
|
||||
Rechnung *rechnung
|
||||
Rechnungsposition *rechnungsposition
|
||||
Scanobject *scanobject
|
||||
Task *task
|
||||
User *user
|
||||
Zahlung *zahlung
|
||||
)
|
||||
@@ -55,6 +56,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
Rechnung = &Q.Rechnung
|
||||
Rechnungsposition = &Q.Rechnungsposition
|
||||
Scanobject = &Q.Scanobject
|
||||
Task = &Q.Task
|
||||
User = &Q.User
|
||||
Zahlung = &Q.Zahlung
|
||||
}
|
||||
@@ -78,6 +80,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||
Rechnung: newRechnung(db, opts...),
|
||||
Rechnungsposition: newRechnungsposition(db, opts...),
|
||||
Scanobject: newScanobject(db, opts...),
|
||||
Task: newTask(db, opts...),
|
||||
User: newUser(db, opts...),
|
||||
Zahlung: newZahlung(db, opts...),
|
||||
}
|
||||
@@ -102,6 +105,7 @@ type Query struct {
|
||||
Rechnung rechnung
|
||||
Rechnungsposition rechnungsposition
|
||||
Scanobject scanobject
|
||||
Task task
|
||||
User user
|
||||
Zahlung zahlung
|
||||
}
|
||||
@@ -127,6 +131,7 @@ func (q *Query) clone(db *gorm.DB) *Query {
|
||||
Rechnung: q.Rechnung.clone(db),
|
||||
Rechnungsposition: q.Rechnungsposition.clone(db),
|
||||
Scanobject: q.Scanobject.clone(db),
|
||||
Task: q.Task.clone(db),
|
||||
User: q.User.clone(db),
|
||||
Zahlung: q.Zahlung.clone(db),
|
||||
}
|
||||
@@ -159,6 +164,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||
Rechnung: q.Rechnung.replaceDB(db),
|
||||
Rechnungsposition: q.Rechnungsposition.replaceDB(db),
|
||||
Scanobject: q.Scanobject.replaceDB(db),
|
||||
Task: q.Task.replaceDB(db),
|
||||
User: q.User.replaceDB(db),
|
||||
Zahlung: q.Zahlung.replaceDB(db),
|
||||
}
|
||||
@@ -181,6 +187,7 @@ type queryCtx struct {
|
||||
Rechnung IRechnungDo
|
||||
Rechnungsposition IRechnungspositionDo
|
||||
Scanobject IScanobjectDo
|
||||
Task ITaskDo
|
||||
User IUserDo
|
||||
Zahlung IZahlungDo
|
||||
}
|
||||
@@ -203,6 +210,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||
Rechnung: q.Rechnung.WithContext(ctx),
|
||||
Rechnungsposition: q.Rechnungsposition.WithContext(ctx),
|
||||
Scanobject: q.Scanobject.WithContext(ctx),
|
||||
Task: q.Task.WithContext(ctx),
|
||||
User: q.User.WithContext(ctx),
|
||||
Zahlung: q.Zahlung.WithContext(ctx),
|
||||
}
|
||||
|
||||
607
query/tasks.gen.go
Normal file
607
query/tasks.gen.go
Normal file
@@ -0,0 +1,607 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
)
|
||||
|
||||
func newTask(db *gorm.DB, opts ...gen.DOOption) task {
|
||||
_task := task{}
|
||||
|
||||
_task.taskDo.UseDB(db, opts...)
|
||||
_task.taskDo.UseModel(&model.Task{})
|
||||
|
||||
tableName := _task.taskDo.TableName()
|
||||
_task.ALL = field.NewAsterisk(tableName)
|
||||
_task.ID = field.NewUint(tableName, "id")
|
||||
_task.CreatedAt = field.NewTime(tableName, "created_at")
|
||||
_task.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||
_task.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||
_task.ProjektID = field.NewUint(tableName, "projekt_id")
|
||||
_task.MandantID = field.NewUint(tableName, "mandant_id")
|
||||
_task.Titel = field.NewString(tableName, "titel")
|
||||
_task.Description = field.NewString(tableName, "description")
|
||||
_task.Status = field.NewInt(tableName, "status")
|
||||
_task.Projekt = taskBelongsToProjekt{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Projekt", "model.Projekt"),
|
||||
Mandant: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Projekt.Mandant", "model.Mandant"),
|
||||
},
|
||||
}
|
||||
|
||||
_task.Mandant = taskBelongsToMandant{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Mandant", "model.Mandant"),
|
||||
}
|
||||
|
||||
_task.fillFieldMap()
|
||||
|
||||
return _task
|
||||
}
|
||||
|
||||
type task struct {
|
||||
taskDo
|
||||
|
||||
ALL field.Asterisk
|
||||
ID field.Uint
|
||||
CreatedAt field.Time
|
||||
UpdatedAt field.Time
|
||||
DeletedAt field.Field
|
||||
ProjektID field.Uint
|
||||
MandantID field.Uint
|
||||
Titel field.String
|
||||
Description field.String
|
||||
Status field.Int
|
||||
Projekt taskBelongsToProjekt
|
||||
|
||||
Mandant taskBelongsToMandant
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (t task) Table(newTableName string) *task {
|
||||
t.taskDo.UseTable(newTableName)
|
||||
return t.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (t task) As(alias string) *task {
|
||||
t.taskDo.DO = *(t.taskDo.As(alias).(*gen.DO))
|
||||
return t.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (t *task) updateTableName(table string) *task {
|
||||
t.ALL = field.NewAsterisk(table)
|
||||
t.ID = field.NewUint(table, "id")
|
||||
t.CreatedAt = field.NewTime(table, "created_at")
|
||||
t.UpdatedAt = field.NewTime(table, "updated_at")
|
||||
t.DeletedAt = field.NewField(table, "deleted_at")
|
||||
t.ProjektID = field.NewUint(table, "projekt_id")
|
||||
t.MandantID = field.NewUint(table, "mandant_id")
|
||||
t.Titel = field.NewString(table, "titel")
|
||||
t.Description = field.NewString(table, "description")
|
||||
t.Status = field.NewInt(table, "status")
|
||||
|
||||
t.fillFieldMap()
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *task) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := t.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (t *task) fillFieldMap() {
|
||||
t.fieldMap = make(map[string]field.Expr, 11)
|
||||
t.fieldMap["id"] = t.ID
|
||||
t.fieldMap["created_at"] = t.CreatedAt
|
||||
t.fieldMap["updated_at"] = t.UpdatedAt
|
||||
t.fieldMap["deleted_at"] = t.DeletedAt
|
||||
t.fieldMap["projekt_id"] = t.ProjektID
|
||||
t.fieldMap["mandant_id"] = t.MandantID
|
||||
t.fieldMap["titel"] = t.Titel
|
||||
t.fieldMap["description"] = t.Description
|
||||
t.fieldMap["status"] = t.Status
|
||||
|
||||
}
|
||||
|
||||
func (t task) clone(db *gorm.DB) task {
|
||||
t.taskDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
t.Projekt.db = db.Session(&gorm.Session{Initialized: true})
|
||||
t.Projekt.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
t.Mandant.db = db.Session(&gorm.Session{Initialized: true})
|
||||
t.Mandant.db.Statement.ConnPool = db.Statement.ConnPool
|
||||
return t
|
||||
}
|
||||
|
||||
func (t task) replaceDB(db *gorm.DB) task {
|
||||
t.taskDo.ReplaceDB(db)
|
||||
t.Projekt.db = db.Session(&gorm.Session{})
|
||||
t.Mandant.db = db.Session(&gorm.Session{})
|
||||
return t
|
||||
}
|
||||
|
||||
type taskBelongsToProjekt struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
|
||||
Mandant struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjekt) Where(conds ...field.Expr) *taskBelongsToProjekt {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjekt) WithContext(ctx context.Context) *taskBelongsToProjekt {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjekt) Session(session *gorm.Session) *taskBelongsToProjekt {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjekt) Model(m *model.Task) *taskBelongsToProjektTx {
|
||||
return &taskBelongsToProjektTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjekt) Unscoped() *taskBelongsToProjekt {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type taskBelongsToProjektTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a taskBelongsToProjektTx) Find() (result *model.Projekt, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjektTx) Append(values ...*model.Projekt) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjektTx) Replace(values ...*model.Projekt) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjektTx) Delete(values ...*model.Projekt) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjektTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjektTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a taskBelongsToProjektTx) Unscoped() *taskBelongsToProjektTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type taskBelongsToMandant struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandant) Where(conds ...field.Expr) *taskBelongsToMandant {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandant) WithContext(ctx context.Context) *taskBelongsToMandant {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandant) Session(session *gorm.Session) *taskBelongsToMandant {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandant) Model(m *model.Task) *taskBelongsToMandantTx {
|
||||
return &taskBelongsToMandantTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandant) Unscoped() *taskBelongsToMandant {
|
||||
a.db = a.db.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type taskBelongsToMandantTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a taskBelongsToMandantTx) Find() (result *model.Mandant, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandantTx) Append(values ...*model.Mandant) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandantTx) Replace(values ...*model.Mandant) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandantTx) Delete(values ...*model.Mandant) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandantTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandantTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
func (a taskBelongsToMandantTx) Unscoped() *taskBelongsToMandantTx {
|
||||
a.tx = a.tx.Unscoped()
|
||||
return &a
|
||||
}
|
||||
|
||||
type taskDo struct{ gen.DO }
|
||||
|
||||
type ITaskDo interface {
|
||||
gen.SubQuery
|
||||
Debug() ITaskDo
|
||||
WithContext(ctx context.Context) ITaskDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() ITaskDo
|
||||
WriteDB() ITaskDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) ITaskDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) ITaskDo
|
||||
Not(conds ...gen.Condition) ITaskDo
|
||||
Or(conds ...gen.Condition) ITaskDo
|
||||
Select(conds ...field.Expr) ITaskDo
|
||||
Where(conds ...gen.Condition) ITaskDo
|
||||
Order(conds ...field.Expr) ITaskDo
|
||||
Distinct(cols ...field.Expr) ITaskDo
|
||||
Omit(cols ...field.Expr) ITaskDo
|
||||
Join(table schema.Tabler, on ...field.Expr) ITaskDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) ITaskDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) ITaskDo
|
||||
Group(cols ...field.Expr) ITaskDo
|
||||
Having(conds ...gen.Condition) ITaskDo
|
||||
Limit(limit int) ITaskDo
|
||||
Offset(offset int) ITaskDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) ITaskDo
|
||||
Unscoped() ITaskDo
|
||||
Create(values ...*model.Task) error
|
||||
CreateInBatches(values []*model.Task, batchSize int) error
|
||||
Save(values ...*model.Task) error
|
||||
First() (*model.Task, error)
|
||||
Take() (*model.Task, error)
|
||||
Last() (*model.Task, error)
|
||||
Find() ([]*model.Task, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Task, err error)
|
||||
FindInBatches(result *[]*model.Task, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*model.Task) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) ITaskDo
|
||||
Assign(attrs ...field.AssignExpr) ITaskDo
|
||||
Joins(fields ...field.RelationField) ITaskDo
|
||||
Preload(fields ...field.RelationField) ITaskDo
|
||||
FirstOrInit() (*model.Task, error)
|
||||
FirstOrCreate() (*model.Task, error)
|
||||
FindByPage(offset int, limit int) (result []*model.Task, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Rows() (*sql.Rows, error)
|
||||
Row() *sql.Row
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) ITaskDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (t taskDo) Debug() ITaskDo {
|
||||
return t.withDO(t.DO.Debug())
|
||||
}
|
||||
|
||||
func (t taskDo) WithContext(ctx context.Context) ITaskDo {
|
||||
return t.withDO(t.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (t taskDo) ReadDB() ITaskDo {
|
||||
return t.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (t taskDo) WriteDB() ITaskDo {
|
||||
return t.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (t taskDo) Session(config *gorm.Session) ITaskDo {
|
||||
return t.withDO(t.DO.Session(config))
|
||||
}
|
||||
|
||||
func (t taskDo) Clauses(conds ...clause.Expression) ITaskDo {
|
||||
return t.withDO(t.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (t taskDo) Returning(value interface{}, columns ...string) ITaskDo {
|
||||
return t.withDO(t.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (t taskDo) Not(conds ...gen.Condition) ITaskDo {
|
||||
return t.withDO(t.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (t taskDo) Or(conds ...gen.Condition) ITaskDo {
|
||||
return t.withDO(t.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (t taskDo) Select(conds ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (t taskDo) Where(conds ...gen.Condition) ITaskDo {
|
||||
return t.withDO(t.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (t taskDo) Order(conds ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (t taskDo) Distinct(cols ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (t taskDo) Omit(cols ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (t taskDo) Join(table schema.Tabler, on ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (t taskDo) LeftJoin(table schema.Tabler, on ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (t taskDo) RightJoin(table schema.Tabler, on ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (t taskDo) Group(cols ...field.Expr) ITaskDo {
|
||||
return t.withDO(t.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (t taskDo) Having(conds ...gen.Condition) ITaskDo {
|
||||
return t.withDO(t.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (t taskDo) Limit(limit int) ITaskDo {
|
||||
return t.withDO(t.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (t taskDo) Offset(offset int) ITaskDo {
|
||||
return t.withDO(t.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (t taskDo) Scopes(funcs ...func(gen.Dao) gen.Dao) ITaskDo {
|
||||
return t.withDO(t.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (t taskDo) Unscoped() ITaskDo {
|
||||
return t.withDO(t.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (t taskDo) Create(values ...*model.Task) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return t.DO.Create(values)
|
||||
}
|
||||
|
||||
func (t taskDo) CreateInBatches(values []*model.Task, batchSize int) error {
|
||||
return t.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (t taskDo) Save(values ...*model.Task) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return t.DO.Save(values)
|
||||
}
|
||||
|
||||
func (t taskDo) First() (*model.Task, error) {
|
||||
if result, err := t.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Task), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t taskDo) Take() (*model.Task, error) {
|
||||
if result, err := t.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Task), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t taskDo) Last() (*model.Task, error) {
|
||||
if result, err := t.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Task), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t taskDo) Find() ([]*model.Task, error) {
|
||||
result, err := t.DO.Find()
|
||||
return result.([]*model.Task), err
|
||||
}
|
||||
|
||||
func (t taskDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Task, err error) {
|
||||
buf := make([]*model.Task, 0, batchSize)
|
||||
err = t.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (t taskDo) FindInBatches(result *[]*model.Task, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return t.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (t taskDo) Attrs(attrs ...field.AssignExpr) ITaskDo {
|
||||
return t.withDO(t.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (t taskDo) Assign(attrs ...field.AssignExpr) ITaskDo {
|
||||
return t.withDO(t.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (t taskDo) Joins(fields ...field.RelationField) ITaskDo {
|
||||
for _, _f := range fields {
|
||||
t = *t.withDO(t.DO.Joins(_f))
|
||||
}
|
||||
return &t
|
||||
}
|
||||
|
||||
func (t taskDo) Preload(fields ...field.RelationField) ITaskDo {
|
||||
for _, _f := range fields {
|
||||
t = *t.withDO(t.DO.Preload(_f))
|
||||
}
|
||||
return &t
|
||||
}
|
||||
|
||||
func (t taskDo) FirstOrInit() (*model.Task, error) {
|
||||
if result, err := t.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Task), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t taskDo) FirstOrCreate() (*model.Task, error) {
|
||||
if result, err := t.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*model.Task), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t taskDo) FindByPage(offset int, limit int) (result []*model.Task, count int64, err error) {
|
||||
result, err = t.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = t.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (t taskDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = t.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = t.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (t taskDo) Scan(result interface{}) (err error) {
|
||||
return t.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (t taskDo) Delete(models ...*model.Task) (result gen.ResultInfo, err error) {
|
||||
return t.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (t *taskDo) withDO(do gen.Dao) *taskDo {
|
||||
t.DO = *do.(*gen.DO)
|
||||
return t
|
||||
}
|
||||
48
repositories/message.go
Normal file
48
repositories/message.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces/stores"
|
||||
)
|
||||
|
||||
type InMemoryMessageRepository struct {
|
||||
m map[int]*stores.Message
|
||||
}
|
||||
|
||||
func (i *InMemoryMessageRepository) AddMessage(_ context.Context, m *stores.Message) error {
|
||||
i.m[m.Id] = m
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *InMemoryMessageRepository) GetMessage(ctx context.Context, id int) (*stores.Message, error) {
|
||||
m, ok := i.m[id]
|
||||
|
||||
if !ok {
|
||||
return nil, errors.New("Message not found")
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (i *InMemoryMessageRepository) ListMessages(ctx context.Context) ([]*stores.Message, error) {
|
||||
messages := make([]*stores.Message, 0, len(i.m))
|
||||
|
||||
for _, v := range i.m {
|
||||
messages = append(messages, v)
|
||||
}
|
||||
|
||||
return messages, nil
|
||||
}
|
||||
|
||||
func (i *InMemoryMessageRepository) RemoveMessage(ctx context.Context, id int) error {
|
||||
delete(i.m, id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewInMemeoryMessageRepository() stores.MessageStore {
|
||||
return &InMemoryMessageRepository{}
|
||||
}
|
||||
78
repositories/session.go
Normal file
78
repositories/session.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces/stores"
|
||||
glide "github.com/valkey-io/valkey-glide/go/v2"
|
||||
)
|
||||
|
||||
type SessionRepository struct {
|
||||
store *glide.Client
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewSessionRepository(store *glide.Client, logger *slog.Logger) stores.SessionStore {
|
||||
return &SessionRepository{store: store, logger: logger}
|
||||
}
|
||||
|
||||
func (sr *SessionRepository) AddSession(s *stores.Session) {
|
||||
// options.HSetExOptions{Expiry: options.NewExpiryIn(time.Hour * 2)}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
||||
defer cancel()
|
||||
|
||||
_, err := sr.store.HSet(ctx, s.Token, s.Serialize())
|
||||
if err != nil {
|
||||
sr.logger.Error("Error adding session to store", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = sr.store.Expire(context.Background(), s.Token, time.Hour*2)
|
||||
if err != nil {
|
||||
sr.logger.Error("Error setting session expiration", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (sr *SessionRepository) GetSessionFromToken(token string) (*stores.Session, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
|
||||
defer cancel()
|
||||
|
||||
s, err := sr.store.HGetAll(ctx, token)
|
||||
if err != nil {
|
||||
sr.logger.Error("Error getting session from store", "error", err)
|
||||
fmt.Println("PANIC - HGETALL")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = sr.store.Expire(ctx, token, time.Hour*2)
|
||||
if err != nil {
|
||||
sr.logger.Error("Error setting session expiration", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return (&stores.Session{}).Deserialize(token, s)
|
||||
}
|
||||
func (sr *SessionRepository) SetMandantInSession(token string, mandantId uint) error {
|
||||
_, err := sr.store.HSet(context.Background(), token, map[string]string{"mandantid": strconv.Itoa(int(mandantId))})
|
||||
|
||||
if err != nil {
|
||||
sr.logger.Error("Error setting mandant in session", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sr *SessionRepository) RemoveSession(token string) {
|
||||
_, err := sr.store.HDel(context.Background(), token, []string{"userid", "mandantid"})
|
||||
|
||||
if err != nil {
|
||||
sr.logger.Error("Error removing session from store", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ansprechpartnerRouter struct {
|
||||
utils.Application
|
||||
}
|
||||
|
||||
func RegisterAnsprechpartnerRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &ansprechpartnerRouter{Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Post("/new", router.createAnsprechpartner)
|
||||
r.Get("/all", router.getAllAnsprechpartners)
|
||||
r.Get("/:id<int>", router.getAnsprechpartner)
|
||||
r.Get("/:id<int>/firmen", router.getAnsprechpartnerFirmen)
|
||||
r.Put("/:id<int>", router.updateAnsprechpartner)
|
||||
r.Delete("/:id<int>", router.deleteAnsprechpartner)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) createAnsprechpartner(c *fiber.Ctx) error {
|
||||
ansprechpartner := new(model.Ansprechpartner)
|
||||
|
||||
if err := c.BodyParser(ansprechpartner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Ansprechpartner
|
||||
|
||||
if err := ap.Omit(ap.UpdatedAt, ap.DeletedAt).Create(ansprechpartner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.SendString("Hello")
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) getAllAnsprechpartners(c *fiber.Ctx) error {
|
||||
aps, err := query.Ansprechpartner.Find()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.JSON(aps)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) getAnsprechpartner(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap, err := query.Ansprechpartner.Where(query.Ansprechpartner.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(ap)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) getAnsprechpartnerFirmen(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap, err := query.Ansprechpartner.Where(query.Ansprechpartner.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
firmen, err := query.Ansprechpartner.Firmen.Model(ap).Find()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap.Firmen = firmen
|
||||
|
||||
return c.JSON(ap)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) updateAnsprechpartner(c *fiber.Ctx) error {
|
||||
ansprechpartner := new(model.Ansprechpartner)
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.BodyParser(ansprechpartner); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Ansprechpartner
|
||||
|
||||
res, err := ap.Where(ap.ID.Eq(uint(id))).Omit(ap.ID, ap.CreatedAt, ap.UpdatedAt, ap.DeletedAt).Updates(ansprechpartner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
func (r *ansprechpartnerRouter) deleteAnsprechpartner(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := query.Ansprechpartner.Where(query.Ansprechpartner.ID.Value(uint(id))).Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
105
routers/firma.go
105
routers/firma.go
@@ -1,105 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type firmaRouter struct {
|
||||
utils.Application
|
||||
}
|
||||
|
||||
func RegisterFirmaRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &firmaRouter{Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Post("/new", router.createFirma)
|
||||
r.Get("/all", router.getAllFirmen)
|
||||
r.Get("/:id<int>", router.getFirma)
|
||||
r.Put("/:id<int>", router.updateFirma)
|
||||
r.Delete("/:id<int>", router.deleteFirma)
|
||||
}
|
||||
|
||||
func (r *firmaRouter) createFirma(c *fiber.Ctx) error {
|
||||
firma := new(model.Firma)
|
||||
|
||||
if err := c.BodyParser(firma); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Firma
|
||||
|
||||
if err := ap.Omit(ap.UpdatedAt, ap.DeletedAt).Create(firma); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.SendString("Hello")
|
||||
}
|
||||
|
||||
func (r *firmaRouter) getAllFirmen(c *fiber.Ctx) error {
|
||||
aps, err := query.Firma.Find()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = c.JSON(aps)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *firmaRouter) getFirma(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap, err := query.Firma.Where(query.Firma.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(ap)
|
||||
}
|
||||
|
||||
func (r *firmaRouter) updateFirma(c *fiber.Ctx) error {
|
||||
firma := new(model.Firma)
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.BodyParser(firma); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ap := query.Firma
|
||||
|
||||
res, err := ap.Where(ap.ID.Eq(uint(id))).Omit(ap.ID, ap.CreatedAt, ap.UpdatedAt, ap.DeletedAt).Updates(firma)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
func (r *firmaRouter) deleteFirma(c *fiber.Ctx) error {
|
||||
id, err := c.ParamsInt("id")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := query.Firma.Where(query.Firma.ID.Value(uint(id))).Delete()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type mandantRouter struct {
|
||||
utils.Application
|
||||
currentMandant uint
|
||||
}
|
||||
|
||||
func RegisterMandantRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &mandantRouter{currentMandant: 1, Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Get("/current", router.getCurrentMandant)
|
||||
r.Put("/current", router.setCurrentMandant)
|
||||
r.Get("/all", router.getAllMandant)
|
||||
}
|
||||
|
||||
func (r *mandantRouter) getCurrentMandant(c *fiber.Ctx) error {
|
||||
m := query.Mandant
|
||||
|
||||
currentMandant, err := m.Where(m.ID.Eq(r.currentMandant)).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentMandant)
|
||||
}
|
||||
|
||||
func (r *mandantRouter) getAllMandant(c *fiber.Ctx) error {
|
||||
m := query.Mandant
|
||||
|
||||
mandanten, err := m.Find()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(mandanten)
|
||||
}
|
||||
|
||||
func (r *mandantRouter) setCurrentMandant(c *fiber.Ctx) error {
|
||||
m := query.Mandant
|
||||
mandant := &model.Mandant{}
|
||||
|
||||
if err := c.BodyParser(mandant); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.currentMandant = mandant.ID
|
||||
|
||||
currentMandant, err := m.Where(m.ID.Eq(r.currentMandant)).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentMandant)
|
||||
}
|
||||
96
routers/mandant/v1/mandant.go
Normal file
96
routers/mandant/v1/mandant.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package mandantv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"git.kocoder.xyz/kocoded/vt/fx"
|
||||
"git.kocoder.xyz/kocoded/vt/fx/interfaces/stores"
|
||||
mandantv1 "git.kocoder.xyz/kocoded/vt/gen/mandant/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/mandant/v1/mandantv1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/interceptors"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewMandantRoute(logger *slog.Logger, db *gorm.DB, sr stores.SessionStore, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
|
||||
path, handler := mandantv1connect.NewMandantServiceHandler(&mandantService{logger: logger, db: db, sr: sr}, connect.WithInterceptors(oidcInterceptor))
|
||||
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
type mandantService struct {
|
||||
logger *slog.Logger
|
||||
db *gorm.DB
|
||||
sr stores.SessionStore
|
||||
}
|
||||
|
||||
func (m *mandantService) GetAllTenants(ctx context.Context, req *mandantv1.ListTenantRequest) (*mandantv1.ListProjectsResponse, error) {
|
||||
ma := query.Use(m.db).Mandant
|
||||
tenants, err := ma.Find()
|
||||
|
||||
if err != nil {
|
||||
m.logger.Error("Error fetching tenants", "error", err)
|
||||
return nil, connect.NewError(connect.CodeUnknown, err)
|
||||
}
|
||||
|
||||
tenantResponses := make([]*mandantv1.GetTenantResponse, len(tenants))
|
||||
|
||||
for i, t := range tenants {
|
||||
tenantResponses[i] = &mandantv1.GetTenantResponse{
|
||||
Id: int64(t.ID),
|
||||
Name: t.Name,
|
||||
Plan: t.Plan,
|
||||
Logo: t.Logo,
|
||||
Color: t.Color,
|
||||
}
|
||||
}
|
||||
|
||||
return &mandantv1.ListProjectsResponse{
|
||||
Data: tenantResponses,
|
||||
Meta: &mandantv1.Metadata{
|
||||
TotalCount: int32(len(tenants)),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *mandantService) GetCurrentTenant(ctx context.Context, req *mandantv1.GetCurrentTenantRequest) (*mandantv1.GetTenantResponse, error) {
|
||||
s, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
||||
}
|
||||
|
||||
ma := query.Use(m.db).Mandant
|
||||
res, err := ma.Where(ma.ID.Eq(s.MandantId)).First()
|
||||
if err != nil {
|
||||
m.logger.Error("Error fetching current tenant", "error", err)
|
||||
return nil, connect.NewError(connect.CodeUnknown, err)
|
||||
}
|
||||
|
||||
return &mandantv1.GetTenantResponse{
|
||||
Id: int64(res.ID),
|
||||
Name: res.Name,
|
||||
Plan: res.Plan,
|
||||
Logo: res.Logo,
|
||||
Color: res.Color,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *mandantService) SetCurrentTenant(ctx context.Context, req *mandantv1.SetCurrentTenantRequest) (*mandantv1.SetCurrentTenantResponse, error) {
|
||||
s, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
||||
}
|
||||
|
||||
err := m.sr.SetMandantInSession(s.Token, uint(req.TenantId))
|
||||
if err != nil {
|
||||
m.logger.Error("Error setting mandant in session", "error", err)
|
||||
return nil, connect.NewError(connect.CodeUnknown, err)
|
||||
}
|
||||
|
||||
return &mandantv1.SetCurrentTenantResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
}
|
||||
48
routers/mandant/v1/mandant.proto
Normal file
48
routers/mandant/v1/mandant.proto
Normal file
@@ -0,0 +1,48 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mandant.v1;
|
||||
|
||||
message GetCurrentTenantRequest {
|
||||
}
|
||||
|
||||
message GetTenantRequest {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message GetTenantResponse {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string plan = 3;
|
||||
string logo = 4;
|
||||
string color = 5;
|
||||
}
|
||||
|
||||
message ListTenantRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListProjectsResponse {
|
||||
repeated GetTenantResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
message SetCurrentTenantRequest {
|
||||
int64 tenant_id = 1;
|
||||
}
|
||||
|
||||
message SetCurrentTenantResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
service MandantService {
|
||||
rpc GetCurrentTenant(GetCurrentTenantRequest) returns (GetTenantResponse);
|
||||
rpc GetAllTenants(ListTenantRequest) returns (ListProjectsResponse);
|
||||
rpc SetCurrentTenant(SetCurrentTenantRequest) returns (SetCurrentTenantResponse);
|
||||
}
|
||||
48
routers/message/v1/message.proto
Normal file
48
routers/message/v1/message.proto
Normal file
@@ -0,0 +1,48 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mandant.v1;
|
||||
|
||||
message GetCurrentTenantRequest {
|
||||
}
|
||||
|
||||
message GetTenantRequest {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message GetTenantResponse {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string plan = 3;
|
||||
string logo = 4;
|
||||
string color = 5;
|
||||
}
|
||||
|
||||
message ListTenantRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListProjectsResponse {
|
||||
repeated GetTenantResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
message SetCurrentTenantRequest {
|
||||
int64 tenant_id = 1;
|
||||
}
|
||||
|
||||
message SetCurrentTenantResponse {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
service MandantService {
|
||||
rpc GetCurrentTenant(GetCurrentTenantRequest) returns (GetTenantResponse);
|
||||
rpc GetAllTenants(ListTenantRequest) returns (ListProjectsResponse);
|
||||
rpc SetCurrentTenant(SetCurrentTenantRequest) returns (SetCurrentTenantResponse);
|
||||
}
|
||||
30
routers/messagebus/v1/messagebus.go
Normal file
30
routers/messagebus/v1/messagebus.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package messagebusv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
kfx "git.kocoder.xyz/kocoded/vt/fx"
|
||||
messagebusv1 "git.kocoder.xyz/kocoded/vt/gen/messagebus/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/messagebus/v1/messagebusv1connect"
|
||||
)
|
||||
|
||||
func NewMessagebusRoute() kfx.Handler {
|
||||
path, handler := messagebusv1connect.NewMessageBusServiceHandler(&messagebusService{})
|
||||
|
||||
return kfx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
type messagebusService struct {
|
||||
}
|
||||
|
||||
func (mbs *messagebusService) SubscribeToConnectInvalidationRequests(ctx context.Context, req *messagebusv1.SubscribeToConnectInvalidationRequestsRequest, res *connect.ServerStream[messagebusv1.MessageBusEntity]) error {
|
||||
for {
|
||||
err := res.Send(&messagebusv1.MessageBusEntity{QueryKey: "Hello World!"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
time.Sleep(time.Second * 2)
|
||||
}
|
||||
}
|
||||
18
routers/messagebus/v1/messagebus.proto
Normal file
18
routers/messagebus/v1/messagebus.proto
Normal file
@@ -0,0 +1,18 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package messagebus.v1;
|
||||
|
||||
enum MessageBusEntityType {
|
||||
OTHER = 0;
|
||||
INVALIDATION_REQUEST = 1;
|
||||
}
|
||||
|
||||
message MessageBusEntity {
|
||||
string queryKey = 1;
|
||||
}
|
||||
|
||||
message SubscribeToConnectInvalidationRequestsRequest {}
|
||||
|
||||
service MessageBusService {
|
||||
rpc SubscribeToConnectInvalidationRequests(SubscribeToConnectInvalidationRequestsRequest) returns (stream MessageBusEntity);
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type projectRouter struct {
|
||||
utils.Application
|
||||
currentMandant uint
|
||||
}
|
||||
|
||||
func RegisterProjectRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &projectRouter{currentMandant: 1, Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Get("/all", router.getAllProjects)
|
||||
r.Post("/new", router.createNewProject)
|
||||
r.Get("/:id<int>", router.getProject)
|
||||
r.Post("/:id<int>/edit", router.editProject)
|
||||
r.Delete("/:id<int>/delete", router.deleteProject)
|
||||
}
|
||||
|
||||
func (r *projectRouter) getAllProjects(c *fiber.Ctx) error {
|
||||
p := query.Projekt
|
||||
pph := c.Get("X-PER-PAGE")
|
||||
ofh := c.Get("X-OFFSET")
|
||||
|
||||
params := struct {
|
||||
Id string `params:"id"`
|
||||
Desc bool `params:"desc"`
|
||||
}{}
|
||||
|
||||
if err := c.QueryParser(¶ms); err != nil {
|
||||
r.Logger.Warn("Param Parser Error: ", "err", err)
|
||||
}
|
||||
|
||||
var pp, of int
|
||||
pp, err := strconv.Atoi(pph)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Per Page header not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
of, err = strconv.Atoi(ofh)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Offset header not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
query := p.Where().Limit(pp).Offset(of)
|
||||
|
||||
if params.Id != "" {
|
||||
f, ok := p.GetFieldByName(params.Id)
|
||||
if ok {
|
||||
if params.Desc {
|
||||
query = query.Order(f.Desc())
|
||||
} else {
|
||||
query = query.Order(f.Asc())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
query = query.Order(p.ID.Asc())
|
||||
}
|
||||
|
||||
projects, err := query.Order(p.Name.Asc()).Find()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
cnt, err := p.Count()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
res := &PaginatedProjects{Data: projects, Meta: struct {
|
||||
TotalProjectsCount int64 `json:"totalProjectsCount"`
|
||||
}{TotalProjectsCount: cnt}}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
type PaginatedProjects struct {
|
||||
Data []*model.Projekt `json:"data"`
|
||||
Meta struct {
|
||||
TotalProjectsCount int64 `json:"totalProjectsCount"`
|
||||
} `json:"meta"`
|
||||
}
|
||||
|
||||
func (r *projectRouter) getProject(c *fiber.Ctx) error {
|
||||
ids := c.Params("id")
|
||||
id, err := strconv.ParseUint(ids, 10, 32)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Id is not an int.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
p := query.Projekt
|
||||
|
||||
currentProject, err := p.Where(p.ID.Eq(uint(id))).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentProject)
|
||||
}
|
||||
|
||||
func (r *projectRouter) createNewProject(c *fiber.Ctx) error {
|
||||
p := query.Projekt
|
||||
project := &model.Projekt{}
|
||||
|
||||
if err := c.BodyParser(project); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := p.Create(project)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Couldn't create Projejct.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "list"}})
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "get"}, Id: int(project.ID)})
|
||||
|
||||
return c.JSON(project)
|
||||
}
|
||||
|
||||
func (r *projectRouter) editProject(c *fiber.Ctx) error {
|
||||
p := query.Projekt
|
||||
project := &model.Projekt{}
|
||||
|
||||
if err := c.BodyParser(project); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := p.Where(p.ID.Eq(project.ID)).Updates(project)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Couldn't create Projejct.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "list"}})
|
||||
utils.MessageBus.SendMBObject(int(project.MandantID), utils.MessageBusObject{Entity: []string{"projects", "get"}, Id: int(project.ID)})
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
|
||||
func (r *projectRouter) deleteProject(c *fiber.Ctx) error {
|
||||
ids := c.Params("id")
|
||||
id, err := strconv.ParseUint(ids, 10, 32)
|
||||
if err != nil {
|
||||
r.Logger.Warn("Id is not an int.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
p := query.Projekt
|
||||
|
||||
res, err := p.Where(p.ID.Eq(uint(id))).Delete()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Couldn't create Projejct.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(res)
|
||||
}
|
||||
125
routers/project/v1/project.go
Normal file
125
routers/project/v1/project.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package projectv1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"slices"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"git.kocoder.xyz/kocoded/vt/fx"
|
||||
projectv1 "git.kocoder.xyz/kocoded/vt/gen/project/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/project/v1/projectv1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/interceptors"
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewProjectRoute(db *gorm.DB, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
|
||||
path, handler := projectv1connect.NewProjectServiceHandler(&projectService{db: db}, connect.WithInterceptors(oidcInterceptor))
|
||||
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
type projectService struct{ db *gorm.DB }
|
||||
|
||||
// ListProjects implements projectv1connect.ProjectServiceHandler.
|
||||
func (s *projectService) ListProjects(ctx context.Context, req *projectv1.ListProjectsRequest) (*projectv1.ListProjectsResponse, error) {
|
||||
session, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
|
||||
}
|
||||
|
||||
p := query.Use(s.db).Projekt
|
||||
|
||||
query := p.Where(p.MandantID.Eq(session.MandantId)).Limit(int(req.PerPage)).Offset(int(req.Page))
|
||||
|
||||
if req.OrberBy != "" {
|
||||
f, ok := p.GetFieldByName(req.OrberBy)
|
||||
if ok {
|
||||
if !req.Asc {
|
||||
query = query.Order(f.Desc())
|
||||
} else {
|
||||
query = query.Order(f.Asc())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
query = query.Order(p.ID.Asc())
|
||||
}
|
||||
|
||||
projects, err := query.Find()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeUnknown, err)
|
||||
}
|
||||
|
||||
cnt, err := p.Where(p.MandantID.Eq(session.MandantId)).Count()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, err)
|
||||
}
|
||||
|
||||
data := make([]*projectv1.GetProjectResponse, len(projects))
|
||||
for i, p := range projects {
|
||||
data[i] = &projectv1.GetProjectResponse{
|
||||
Id: int64(p.ID),
|
||||
Name: p.Name,
|
||||
Description: p.Description,
|
||||
IsMaterialized: newPointerBoolean(true),
|
||||
IsPersonalized: newPointerBoolean(true),
|
||||
IsConfirmed: newPointerBoolean(true),
|
||||
IsPaid: nil,
|
||||
IsDone: s.IsDone(p),
|
||||
}
|
||||
}
|
||||
|
||||
return &projectv1.ListProjectsResponse{
|
||||
Data: data,
|
||||
Meta: &projectv1.Metadata{TotalCount: int32(cnt)},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func newPointerBoolean(val bool) *bool {
|
||||
b := val
|
||||
return &b
|
||||
}
|
||||
|
||||
func (s *projectService) IsDone(p *model.Projekt) *bool {
|
||||
t := query.Use(s.db).Task
|
||||
tasks, err := t.Where(t.ProjektID.Eq(p.ID)).Find()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(tasks) == 0 {
|
||||
return nil
|
||||
}
|
||||
if i := slices.IndexFunc(tasks, func(t *model.Task) bool {
|
||||
return !t.Status.IsDone()
|
||||
}); i != -1 {
|
||||
return newPointerBoolean(false)
|
||||
}
|
||||
return newPointerBoolean(true)
|
||||
}
|
||||
|
||||
func (s *projectService) GetProject(ctx context.Context, req *projectv1.GetProjectRequest) (*projectv1.GetProjectResponse, error) {
|
||||
session, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
|
||||
}
|
||||
|
||||
p := query.Use(s.db).Projekt
|
||||
|
||||
query, err := p.Where(p.ID.Eq(uint(req.Id))).Where(p.MandantID.Eq(session.MandantId)).First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &projectv1.GetProjectResponse{
|
||||
Id: int64(query.ID),
|
||||
Name: query.Name,
|
||||
Description: query.Description,
|
||||
IsMaterialized: newPointerBoolean(true),
|
||||
IsPersonalized: newPointerBoolean(true),
|
||||
IsConfirmed: newPointerBoolean(true),
|
||||
IsPaid: newPointerBoolean(true),
|
||||
IsDone: newPointerBoolean(true),
|
||||
}, nil
|
||||
}
|
||||
39
routers/project/v1/project.proto
Normal file
39
routers/project/v1/project.proto
Normal file
@@ -0,0 +1,39 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package project.v1;
|
||||
|
||||
message GetProjectRequest {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message GetProjectResponse {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string description = 3;
|
||||
optional bool is_materialized = 5;
|
||||
optional bool is_personalized = 6;
|
||||
optional bool is_confirmed = 7;
|
||||
optional bool is_paid = 8;
|
||||
optional bool is_done = 9;
|
||||
}
|
||||
|
||||
message ListProjectsRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListProjectsResponse {
|
||||
repeated GetProjectResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
service ProjectService {
|
||||
rpc GetProject(GetProjectRequest) returns (GetProjectResponse);
|
||||
rpc ListProjects(ListProjectsRequest) returns (ListProjectsResponse);
|
||||
}
|
||||
182
routers/todo/v1/todo.go
Normal file
182
routers/todo/v1/todo.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package todov1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"git.kocoder.xyz/kocoded/vt/fx"
|
||||
todov1 "git.kocoder.xyz/kocoded/vt/gen/todo/v1"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/todo/v1/todov1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/interceptors"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewTodoRoute(db *gorm.DB, logger *slog.Logger, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
|
||||
path, handler := todov1connect.NewTodoServiceHandler(&todoService{logger: logger, db: db}, connect.WithInterceptors(oidcInterceptor))
|
||||
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
type todoService struct {
|
||||
logger *slog.Logger
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func (ts *todoService) GetTodo(ctx context.Context, req *todov1.GetTodosRequest) (*todov1.GetTodosResponse, error) {
|
||||
s, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
||||
}
|
||||
|
||||
t := query.Use(ts.db).Task
|
||||
res, err := t.Where(t.ID.Eq(uint(req.Id))).Where(t.MandantID.Eq(s.MandantId)).First()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
tres := &todov1.GetTodosResponse{
|
||||
Id: int64(res.ID),
|
||||
Title: res.Titel,
|
||||
Description: res.Description,
|
||||
Status: todov1.Status(res.Status),
|
||||
}
|
||||
|
||||
return tres, nil
|
||||
|
||||
// return &todov1.GetTodosResponse{
|
||||
// Id: 1,
|
||||
// Title: "Sample Todo",
|
||||
// Description: "This is a sample todo item.",
|
||||
// Status: todov1.Status_Doing,
|
||||
// }, nil
|
||||
}
|
||||
|
||||
func (ts *todoService) ContributeToQuery(f *todov1.Filter, q query.ITaskDo) query.ITaskDo {
|
||||
t := query.Use(ts.db).Task
|
||||
|
||||
switch f.Field {
|
||||
case todov1.Field_FieldDescription, todov1.Field_FieldTitle:
|
||||
var field field.String
|
||||
if f.Field == todov1.Field_FieldDescription {
|
||||
field = t.Description
|
||||
} else {
|
||||
field = t.Titel
|
||||
}
|
||||
switch f.Operation {
|
||||
case todov1.Operation_Equals:
|
||||
q = q.Where(field.Eq(f.Value))
|
||||
case todov1.Operation_NotEquals:
|
||||
q = q.Where(field.Neq(f.Value))
|
||||
case todov1.Operation_GreaterThan:
|
||||
q = q.Where(field.Gt(f.Value))
|
||||
case todov1.Operation_LessThan:
|
||||
q = q.Where(field.Lt(f.Value))
|
||||
case todov1.Operation_Like:
|
||||
q = q.Where(field.Like(f.Value))
|
||||
}
|
||||
case todov1.Field_FieldId:
|
||||
i, err := strconv.Atoi(f.Value)
|
||||
if err != nil {
|
||||
slog.Warn("Value not an int", "err", err)
|
||||
return q
|
||||
}
|
||||
switch f.Operation {
|
||||
case todov1.Operation_Equals:
|
||||
q = q.Where(t.ID.Eq(uint(i)))
|
||||
case todov1.Operation_NotEquals:
|
||||
q = q.Where(t.ID.Neq(uint(i)))
|
||||
case todov1.Operation_GreaterThan:
|
||||
q = q.Where(t.ID.Gt(uint(i)))
|
||||
case todov1.Operation_LessThan:
|
||||
q = q.Where(t.ID.Lt(uint(i)))
|
||||
}
|
||||
case todov1.Field_FieldStatus:
|
||||
i, err := strconv.Atoi(f.Value)
|
||||
if err != nil {
|
||||
slog.Warn("Value not an int", "err", err)
|
||||
return q
|
||||
}
|
||||
switch f.Operation {
|
||||
case todov1.Operation_Equals:
|
||||
q = q.Where(t.Status.Eq(i))
|
||||
case todov1.Operation_NotEquals:
|
||||
q = q.Where(t.Status.Neq(i))
|
||||
case todov1.Operation_GreaterThan:
|
||||
q = q.Where(t.Status.Gt(i))
|
||||
case todov1.Operation_LessThan:
|
||||
q = q.Where(t.Status.Lt(i))
|
||||
}
|
||||
default:
|
||||
return q
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
func (ts *todoService) ListTodos(ctx context.Context, req *todov1.ListTodosRequest) (*todov1.ListTodosResponse, error) {
|
||||
ts.logger.Info("ListTodos called", "request", req)
|
||||
s, ok := interceptors.SessionFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
||||
}
|
||||
|
||||
t := query.Use(ts.db).Task
|
||||
taskQuery := t.Where(t.MandantID.Eq(s.MandantId))
|
||||
|
||||
for _, v := range req.Filters {
|
||||
taskQuery = ts.ContributeToQuery(v, taskQuery)
|
||||
}
|
||||
|
||||
taskQuery = taskQuery.Limit(int(req.PerPage)).Offset(int(req.Page))
|
||||
if req.OrberBy != "" {
|
||||
f, ok := t.GetFieldByName(req.OrberBy)
|
||||
if ok {
|
||||
if !req.Asc {
|
||||
taskQuery = taskQuery.Order(f.Desc())
|
||||
} else {
|
||||
taskQuery = taskQuery.Order(f.Asc())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
taskQuery = taskQuery.Order(t.ID.Asc())
|
||||
}
|
||||
|
||||
tasks, err := taskQuery.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
taskQuery = t.Where(t.MandantID.Eq(s.MandantId))
|
||||
|
||||
for _, v := range req.Filters {
|
||||
taskQuery = ts.ContributeToQuery(v, taskQuery)
|
||||
}
|
||||
|
||||
cnt, err := taskQuery.Count()
|
||||
|
||||
if err != nil {
|
||||
ts.logger.Info("Counting Todos failed", "request", req, "err", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
data := make([]*todov1.GetTodosResponse, len(tasks))
|
||||
for i, p := range tasks {
|
||||
data[i] = &todov1.GetTodosResponse{
|
||||
Id: int64(p.ID),
|
||||
Title: p.Titel,
|
||||
Description: p.Description,
|
||||
Status: todov1.Status(p.Status),
|
||||
}
|
||||
}
|
||||
|
||||
return &todov1.ListTodosResponse{
|
||||
Data: data,
|
||||
Meta: &todov1.Metadata{
|
||||
TotalCount: int32(cnt),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
64
routers/todo/v1/todo.proto
Normal file
64
routers/todo/v1/todo.proto
Normal file
@@ -0,0 +1,64 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package todo.v1;
|
||||
|
||||
enum Status {
|
||||
Todo = 0;
|
||||
NeedsMoreInfo = 1;
|
||||
Doing = 2;
|
||||
Done = 3;
|
||||
}
|
||||
|
||||
enum Field {
|
||||
FieldId = 0;
|
||||
FieldTitle = 1;
|
||||
FieldDescription = 2;
|
||||
FieldStatus = 3;
|
||||
}
|
||||
|
||||
enum Operation {
|
||||
Equals = 0;
|
||||
NotEquals = 1;
|
||||
GreaterThan = 2;
|
||||
LessThan = 3;
|
||||
Like = 4;
|
||||
}
|
||||
|
||||
message GetTodosRequest {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message GetTodosResponse {
|
||||
int64 id = 1;
|
||||
string title = 2;
|
||||
string description = 3;
|
||||
Status status = 4;
|
||||
}
|
||||
|
||||
message ListTodosRequest {
|
||||
int32 page = 1;
|
||||
int32 per_page = 2;
|
||||
string orber_by = 3;
|
||||
bool asc = 4;
|
||||
repeated Filter filters = 5;
|
||||
}
|
||||
|
||||
message Filter {
|
||||
Field field = 1;
|
||||
string value = 2;
|
||||
Operation operation = 3;
|
||||
}
|
||||
|
||||
message Metadata {
|
||||
int32 totalCount = 1;
|
||||
}
|
||||
|
||||
message ListTodosResponse {
|
||||
repeated GetTodosResponse data = 1;
|
||||
Metadata meta = 2;
|
||||
}
|
||||
|
||||
service TodoService {
|
||||
rpc GetTodo(GetTodosRequest) returns (GetTodosResponse);
|
||||
rpc ListTodos(ListTodosRequest) returns (ListTodosResponse);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"git.kocoder.xyz/kocoded/vt/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type userRouter struct {
|
||||
utils.Application
|
||||
}
|
||||
|
||||
func RegisterUserRouter(group fiber.Router, appCtx utils.Application) {
|
||||
router := &userRouter{Application: appCtx}
|
||||
|
||||
r := group.Use(utils.IsAuthenticated(appCtx))
|
||||
r.Get("/current", router.getCurrentUserInfo)
|
||||
}
|
||||
|
||||
func (r *userRouter) getCurrentUserInfo(c *fiber.Ctx) error {
|
||||
u := query.User
|
||||
|
||||
session := c.Locals("USER_KEY").(*utils.Session)
|
||||
|
||||
currentUser, err := u.Where(u.ID.Eq(session.UserID)).First()
|
||||
if err != nil {
|
||||
r.Logger.Warn("Current mandant not found.", "error", err)
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return c.JSON(currentUser)
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
glide "github.com/valkey-io/valkey-glide/go/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Application struct {
|
||||
Logger *slog.Logger
|
||||
DB *gorm.DB
|
||||
Client *glide.Client
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
Token string
|
||||
UserID uint
|
||||
MandantId uint
|
||||
}
|
||||
|
||||
func (s *Session) Deserialize(t string, m map[string]string) (*Session, error) {
|
||||
userid, err := strconv.Atoi(m["userid"])
|
||||
if err != nil {
|
||||
return nil, errors.New("Userid from cache not an int")
|
||||
}
|
||||
|
||||
mandantid, err := strconv.Atoi(m["mandantid"])
|
||||
if err != nil {
|
||||
return nil, errors.New("Mandantid from cache not an int")
|
||||
}
|
||||
|
||||
s.Token = t
|
||||
s.UserID = uint(userid)
|
||||
s.MandantId = uint(mandantid)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Session) Serialize() map[string]string {
|
||||
m := make(map[string]string)
|
||||
m["userid"] = strconv.Itoa(int(s.UserID))
|
||||
m["mandantid"] = strconv.Itoa(int(s.MandantId))
|
||||
return m
|
||||
}
|
||||
|
||||
func (a *Application) AddSession(s *Session) {
|
||||
// options.HSetExOptions{Expiry: options.NewExpiryIn(time.Hour * 2)}
|
||||
_, err := a.Client.HSet(context.Background(), s.Token, s.Serialize())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = a.Client.Expire(context.Background(), s.Token, time.Hour*2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Application) GetSessionFromToken(token string) (*Session, error) {
|
||||
s, err := a.Client.HGetAll(context.Background(), token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = a.Client.Expire(context.Background(), token, time.Hour*2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return (&Session{}).Deserialize(token, s)
|
||||
}
|
||||
|
||||
func (a *Application) RemoveSession(token string) {
|
||||
_, err := a.Client.HDel(context.Background(), token, []string{"userid", "mandantid"})
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/adaptor"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
func setCallbackCookie(w http.ResponseWriter, r *http.Request, name, value string) {
|
||||
setCallbackCookieExp(w, r, name, value, int(time.Hour.Seconds()))
|
||||
}
|
||||
|
||||
func setCallbackCookieExp(w http.ResponseWriter, r *http.Request, name, value string, maxAge int) {
|
||||
c := &http.Cookie{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Path: "/",
|
||||
MaxAge: maxAge,
|
||||
Secure: r.TLS != nil,
|
||||
HttpOnly: true,
|
||||
}
|
||||
http.SetCookie(w, c)
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
}
|
||||
|
||||
func CreateOIDCClient(ctx context.Context, app *fiber.App, appCtx Application) {
|
||||
provider, err := oidc.NewProvider(ctx, "https://keycloak.kocoder.xyz/realms/che")
|
||||
if err != nil {
|
||||
appCtx.Logger.Error("Error generating OIDC Provider. ", "error", err)
|
||||
}
|
||||
|
||||
oauthConfig := oauth2.Config{
|
||||
ClientID: os.Getenv("CLIENT_ID"),
|
||||
ClientSecret: os.Getenv("CLIENT_SECRET"),
|
||||
RedirectURL: os.Getenv("BACKEND_URI") + "/api/auth/callback",
|
||||
|
||||
Endpoint: provider.Endpoint(),
|
||||
|
||||
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, "profile", "email"},
|
||||
}
|
||||
|
||||
app.Get("/api/auth", adaptor.HTTPHandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
state, err := RandString(16)
|
||||
if err != nil {
|
||||
appCtx.Logger.Warn("Unable to create a state", "error", err)
|
||||
http.Error(w, "Unable to create a state", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
setCallbackCookie(w, r, "state", state)
|
||||
|
||||
http.Redirect(w, r, oauthConfig.AuthCodeURL(state), http.StatusFound)
|
||||
}))
|
||||
|
||||
app.Get("/api/auth/callback", adaptor.HTTPHandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
state, err := r.Cookie("state")
|
||||
if err != nil {
|
||||
appCtx.Logger.Warn("State cookie not found", "error", err)
|
||||
http.Error(w, "state not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Query().Get("state") != state.Value {
|
||||
appCtx.Logger.Warn("State cookie and header not matching", "error", err)
|
||||
http.Error(w, "states not matching", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
oauth2Token, err := oauthConfig.Exchange(ctx, r.URL.Query().Get("code"))
|
||||
if err != nil {
|
||||
appCtx.Logger.Warn("Failed to exchange token", "error", err)
|
||||
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
userInfo, err := provider.UserInfo(ctx, oauth2.StaticTokenSource(oauth2Token))
|
||||
if err != nil {
|
||||
appCtx.Logger.Warn("failed to get userinfo", "error", err)
|
||||
http.Error(w, "Failed to get userinfo: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
resp := struct {
|
||||
Token *oauth2.Token
|
||||
UserInfo *oidc.UserInfo
|
||||
}{oauth2Token, userInfo}
|
||||
|
||||
claims := &model.User{}
|
||||
err = resp.UserInfo.Claims(claims)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(claims)
|
||||
|
||||
user := &model.User{}
|
||||
if appCtx.DB.Where(model.User{Email: resp.UserInfo.Email}).Assign(claims).FirstOrCreate(user).Error != nil {
|
||||
appCtx.Logger.Warn("Failed to create user in DB")
|
||||
http.Error(w, "failed to create user", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
setCallbackCookieExp(w, r, "state", "", -1)
|
||||
|
||||
cookie, err := RandString(24)
|
||||
if err != nil {
|
||||
appCtx.Logger.Warn("Couldn't generate session-cookie.")
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
setCallbackCookieExp(w, r, "auth-cookie", cookie, int(time.Hour.Seconds()))
|
||||
appCtx.AddSession(&Session{Token: cookie, UserID: user.ID, MandantId: 1})
|
||||
|
||||
http.Redirect(w, r, os.Getenv("FRONTEND_URI")+"/dashboard", http.StatusFound)
|
||||
}))
|
||||
|
||||
app.Get("/api/auth/currentSession", func(c *fiber.Ctx) error {
|
||||
authToken := c.Cookies("auth-cookie")
|
||||
|
||||
session, err := appCtx.GetSessionFromToken(authToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(session)
|
||||
})
|
||||
|
||||
app.Get("/api/auth/logout", func(c *fiber.Ctx) error {
|
||||
authToken := c.Cookies("auth-cookie")
|
||||
|
||||
appCtx.RemoveSession(authToken)
|
||||
|
||||
cookie := new(fiber.Cookie)
|
||||
cookie.Name = "auth-cookie"
|
||||
cookie.Expires = time.Now().Add(-1 * time.Minute)
|
||||
|
||||
c.Cookie(cookie)
|
||||
|
||||
return c.Redirect(os.Getenv("FRONTEND_URI"))
|
||||
})
|
||||
}
|
||||
|
||||
type keyType struct{}
|
||||
|
||||
var UserKey keyType
|
||||
|
||||
func IsAuthenticated(appCtx Application) fiber.Handler {
|
||||
fmt.Println("Gettings Session")
|
||||
|
||||
return func(c *fiber.Ctx) error {
|
||||
authToken := c.Cookies("auth-cookie")
|
||||
fmt.Println("Gettings Session", "sessiontoken", authToken)
|
||||
session, err := appCtx.GetSessionFromToken(authToken)
|
||||
if err != nil {
|
||||
appCtx.Logger.Warn("Unauthorized GET Attempt", "reason", err)
|
||||
return c.SendStatus(fiber.StatusUnauthorized)
|
||||
}
|
||||
|
||||
fmt.Println("Saving Session", "session", session)
|
||||
c.Locals("USER_KEY", session)
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,43 @@
|
||||
package utils
|
||||
|
||||
// Keep (used in cmd/api/main.go)
|
||||
|
||||
// Cache utilities for Valkey Glide
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
glide "github.com/valkey-io/valkey-glide/go/v2"
|
||||
"github.com/valkey-io/valkey-glide/go/v2/config"
|
||||
)
|
||||
|
||||
func SetupCache(host, port, user, pass string) (*glide.Client, bool) {
|
||||
func NewCache(logger *slog.Logger) *glide.Client {
|
||||
user := os.Getenv("VALKEY_USER")
|
||||
pass := os.Getenv("VALKEY_PASS")
|
||||
host := os.Getenv("VALKEY_HOST")
|
||||
port := os.Getenv("VALKEY_PORT")
|
||||
p, err := strconv.Atoi(port)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("VALKEY_PORT is not a number")
|
||||
return nil, false
|
||||
logger.Error("VALKEY_PORT is not a number", "error", err, "port", port)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
config := config.NewClientConfiguration().WithAddress(&config.NodeAddress{Host: host, Port: p}).WithCredentials(config.NewServerCredentials(user, pass))
|
||||
|
||||
client, err := glide.NewClient(config)
|
||||
if err != nil {
|
||||
fmt.Println("There was an error: ", err)
|
||||
return nil, false
|
||||
logger.Error("There was an error in glide.NewClient!", "err", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
res, err := client.Ping(context.Background())
|
||||
_, err = client.Ping(context.Background())
|
||||
if err != nil {
|
||||
fmt.Println("There was an error: ", err)
|
||||
return nil, false
|
||||
logger.Error("There was an error pinging the client initially!", "err", err)
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(res) // PONG
|
||||
|
||||
return client, true
|
||||
return client
|
||||
}
|
||||
|
||||
35
utils/db.go
35
utils/db.go
@@ -1,21 +1,30 @@
|
||||
package utils
|
||||
|
||||
// Keep (used in cmd/api/main.go)
|
||||
|
||||
// Database utilities for GORM
|
||||
// using PostgreSQL driver and OpenTelemetry tracing
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"git.kocoder.xyz/kocoded/vt/model"
|
||||
"git.kocoder.xyz/kocoded/vt/query"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"gorm.io/plugin/opentelemetry/tracing"
|
||||
)
|
||||
|
||||
func SetupDatabase(dsn string, logger *slog.Logger) *gorm.DB {
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
func NewDB(logger *slog.Logger) *gorm.DB {
|
||||
db, err := gorm.Open(postgres.Open(os.Getenv("DB_DSN")), &gorm.Config{})
|
||||
if err != nil {
|
||||
logger.Error("Error connecting to the Database", "error", err)
|
||||
}
|
||||
|
||||
if err := db.Use(tracing.NewPlugin()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = db.SetupJoinTable(model.Ansprechpartner{}, "Firmen", model.FirmaAnsprechpartner{})
|
||||
if err != nil {
|
||||
logger.Error("Error setting up Join Tables", "error", err)
|
||||
@@ -24,26 +33,10 @@ func SetupDatabase(dsn string, logger *slog.Logger) *gorm.DB {
|
||||
if err != nil {
|
||||
logger.Error("Error setting up Join Tables", "error", err)
|
||||
}
|
||||
err = db.AutoMigrate(&model.Mandant{}, &model.User{}, &model.Ansprechpartner{}, &model.FirmaAnsprechpartner{}, &model.Firma{}, &model.Projekt{})
|
||||
err = db.AutoMigrate(&model.Mandant{}, &model.User{}, &model.Ansprechpartner{}, &model.FirmaAnsprechpartner{}, &model.Firma{}, &model.Projekt{}, &model.Task{})
|
||||
if err != nil {
|
||||
logger.Error("Error setting up Join Tables", "error", err)
|
||||
}
|
||||
|
||||
g := gen.NewGenerator(gen.Config{
|
||||
OutPath: "query",
|
||||
Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
|
||||
})
|
||||
|
||||
// gormdb, _ := gorm.Open(mysql.Open("root:@(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local"))
|
||||
g.UseDB(db) // reuse your gorm db
|
||||
|
||||
// Generate basic type-safe DAO API for struct `model.User` following conventions
|
||||
g.ApplyBasic(model.Mandant{}, model.User{}, model.Ansprechpartner{}, model.Dokument{}, model.Firma{}, model.Kalender{}, model.Kalendereintrag{}, model.Kostenstelle{}, model.Lager{}, model.Lagerplatz{}, model.Material{}, model.Nachricht{}, model.Projekt{}, model.Rechnung{}, model.Rechnungsposition{}, model.Scanobject{}, model.User{}, model.Zahlung{}, model.FirmaAnsprechpartner{})
|
||||
|
||||
// Generate the code
|
||||
g.Execute()
|
||||
|
||||
query.SetDefault(db)
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
26
utils/healthcheck.go
Normal file
26
utils/healthcheck.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package utils
|
||||
|
||||
// Keep (used in cmd/api/main.go)
|
||||
|
||||
// Healthcheck utilities for gRPC services
|
||||
// using connect-go and grpchealth
|
||||
import (
|
||||
"connectrpc.com/grpchealth"
|
||||
"git.kocoder.xyz/kocoded/vt/fx"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/project/v1/projectv1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/todo/v1/todov1connect"
|
||||
)
|
||||
|
||||
func NewHealthchecker() grpchealth.Checker {
|
||||
checker := grpchealth.NewStaticChecker()
|
||||
|
||||
checker.SetStatus(projectv1connect.ProjectServiceName, grpchealth.StatusServing)
|
||||
checker.SetStatus(todov1connect.TodoServiceName, grpchealth.StatusServing)
|
||||
|
||||
return checker
|
||||
}
|
||||
|
||||
func NewHealthCheckV1(healthChecker grpchealth.Checker) fx.Handler {
|
||||
path, handler := grpchealth.NewHandler(healthChecker)
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"log/slog"
|
||||
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
)
|
||||
|
||||
var MessageBus = &messagebus{mandanten: make(map[int][]*websocket.Conn)}
|
||||
|
||||
type messagebus struct {
|
||||
mandanten map[int][]*websocket.Conn
|
||||
}
|
||||
|
||||
func (mb *messagebus) AddConn(mid int, c *websocket.Conn) {
|
||||
mb.mandanten[mid] = append(mb.mandanten[mid], c)
|
||||
|
||||
ReadLoop(c)
|
||||
}
|
||||
|
||||
func ReadLoop(c *websocket.Conn) {
|
||||
for {
|
||||
var t int
|
||||
var r io.Reader
|
||||
var err error
|
||||
|
||||
if t, r, err = c.NextReader(); err != nil {
|
||||
c.Close()
|
||||
break
|
||||
}
|
||||
|
||||
bytes, err := io.ReadAll(r)
|
||||
|
||||
slog.Info("READLOOP: ", "Type", t, "value", bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func (mb *messagebus) SendMBObject(mid int, mbo MessageBusObject) {
|
||||
bytes, err := json.Marshal(mbo)
|
||||
if err != nil {
|
||||
slog.Info("marshal", "error", err)
|
||||
}
|
||||
|
||||
i := 0
|
||||
for _, c := range mb.mandanten[mid] {
|
||||
if err := c.WriteMessage(websocket.TextMessage, bytes); err != nil {
|
||||
slog.Info("conn to remove", "conns", mb.mandanten)
|
||||
mb.RemoveConn(mid, i)
|
||||
slog.Info("write", "error", err, "index", i)
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (mb *messagebus) RemoveConn(mid int, i int) {
|
||||
s := mb.mandanten[mid]
|
||||
s[i] = s[len(s)-1]
|
||||
mb.mandanten[mid] = s[:len(s)-1]
|
||||
slog.Info("conn removed", "conns", mb.mandanten)
|
||||
}
|
||||
|
||||
type MessageBusObject struct {
|
||||
Entity []string `json:"entity"`
|
||||
Id any `json:"id"`
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/compress"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
"github.com/gofiber/fiber/v2/middleware/helmet"
|
||||
"github.com/gofiber/fiber/v2/middleware/idempotency"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/gofiber/fiber/v2/middleware/monitor"
|
||||
"github.com/gofiber/fiber/v2/middleware/pprof"
|
||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||
"github.com/gofiber/fiber/v2/middleware/requestid"
|
||||
"github.com/gofiber/fiber/v2/middleware/skip"
|
||||
)
|
||||
|
||||
func RegisterMiddlewares(app *fiber.App) {
|
||||
app.Use(requestid.New())
|
||||
app.Use(compress.New())
|
||||
app.Use(helmet.New())
|
||||
app.Use(cors.New(cors.Config{
|
||||
AllowOrigins: os.Getenv("FRONTEND_URI"),
|
||||
AllowCredentials: true,
|
||||
}))
|
||||
// app.Use(csrf.New())
|
||||
// app.Use(healthcheck.New(healthcheck.Config{}))
|
||||
app.Use(idempotency.New())
|
||||
// app.Use(limiter.New())
|
||||
app.Use(logger.New())
|
||||
app.Use("/dbg/monitor", monitor.New())
|
||||
app.Use(pprof.New())
|
||||
app.Use(recover.New())
|
||||
app.Use(skip.New(AddPaginationParams, func(c *fiber.Ctx) bool {
|
||||
return c.Method() != fiber.MethodGet
|
||||
}))
|
||||
}
|
||||
26
utils/oidc.go
Normal file
26
utils/oidc.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
)
|
||||
|
||||
func NewOIDCProvider(logger *slog.Logger) *oidc.Provider {
|
||||
issuerUrl := os.Getenv("OIDC_ISSUER_URL")
|
||||
|
||||
provider, err := oidc.NewProvider(context.Background(), issuerUrl)
|
||||
|
||||
if err != nil {
|
||||
logger.Error("Error generating OIDC Provider. ", "error", err, "url", issuerUrl)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return provider
|
||||
}
|
||||
|
||||
func NewOIDCVerifier(provider *oidc.Provider) *oidc.IDTokenVerifier {
|
||||
return provider.Verifier(&oidc.Config{ClientID: "account"})
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type OffsetPaginationError struct {
|
||||
Page int
|
||||
Pages int
|
||||
NextPage int
|
||||
LastPage int
|
||||
}
|
||||
|
||||
func (p *OffsetPaginationError) Error() string {
|
||||
return "Not an error, just for offsetbased pagination."
|
||||
}
|
||||
|
||||
func NewOffsetPaginationError(page int, pages int) error {
|
||||
var nextPage int
|
||||
if page+1 <= pages {
|
||||
nextPage = page + 1
|
||||
} else {
|
||||
nextPage = -1
|
||||
}
|
||||
|
||||
return &OffsetPaginationError{Page: page, Pages: pages, NextPage: nextPage, LastPage: page - 1}
|
||||
}
|
||||
|
||||
type KeysetPaginationError struct {
|
||||
Key int
|
||||
NextKey int
|
||||
PreviousKey int
|
||||
}
|
||||
|
||||
func (p *KeysetPaginationError) Error() string {
|
||||
return "Not an error, just for Keysetbased pagination."
|
||||
}
|
||||
|
||||
func NewKeysetPaginationError(key int, next int, previous int) error {
|
||||
return &KeysetPaginationError{Key: key, NextKey: next, PreviousKey: previous}
|
||||
}
|
||||
|
||||
func AddPaginationParams(c *fiber.Ctx) error {
|
||||
err := c.Next()
|
||||
if err != nil {
|
||||
|
||||
var offset *OffsetPaginationError
|
||||
if errors.As(err, &offset) {
|
||||
c.Append("X-Page", strconv.Itoa(offset.Page))
|
||||
c.Append("X-Pages", strconv.Itoa(offset.Pages))
|
||||
c.Append("X-Next-Page", strconv.Itoa(offset.NextPage))
|
||||
c.Append("X-Last-Page", strconv.Itoa(offset.LastPage))
|
||||
return nil
|
||||
}
|
||||
|
||||
var keyset *KeysetPaginationError
|
||||
if errors.As(err, &keyset) {
|
||||
c.Append("X-Key", strconv.Itoa(keyset.Key))
|
||||
c.Append("X-Previous-Key", strconv.Itoa(keyset.PreviousKey))
|
||||
c.Append("X-Next-Key", strconv.Itoa(keyset.NextKey))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
)
|
||||
|
||||
func RandString(nByte int) (string, error) {
|
||||
b := make([]byte, nByte)
|
||||
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.RawURLEncoding.EncodeToString(b), nil
|
||||
}
|
||||
37
utils/reflection.go
Normal file
37
utils/reflection.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package utils
|
||||
|
||||
// Keep (used in cmd/api/main.go)
|
||||
|
||||
// Reflection utilities for gRPC services
|
||||
// using connect-go and grpcreflect
|
||||
import (
|
||||
"connectrpc.com/grpcreflect"
|
||||
"git.kocoder.xyz/kocoded/vt/fx"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/mandant/v1/mandantv1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/messagebus/v1/messagebusv1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/project/v1/projectv1connect"
|
||||
"git.kocoder.xyz/kocoded/vt/gen/todo/v1/todov1connect"
|
||||
)
|
||||
|
||||
func NewReflector() *grpcreflect.Reflector {
|
||||
strings := []string{
|
||||
todov1connect.TodoServiceName,
|
||||
projectv1connect.ProjectServiceName,
|
||||
mandantv1connect.MandantServiceName,
|
||||
messagebusv1connect.MessageBusServiceName,
|
||||
}
|
||||
|
||||
return grpcreflect.NewReflector(grpcreflect.NamerFunc(func() []string {
|
||||
return strings
|
||||
}))
|
||||
}
|
||||
|
||||
func NewReflectorV1(reflector *grpcreflect.Reflector) fx.Handler {
|
||||
path, handler := grpcreflect.NewHandlerV1(reflector)
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
|
||||
func NewReflectorV1Alpha1(reflector *grpcreflect.Reflector) fx.Handler {
|
||||
path, handler := grpcreflect.NewHandlerV1Alpha(reflector)
|
||||
return fx.NewRoute(path, handler)
|
||||
}
|
||||
Reference in New Issue
Block a user