diff --git a/project/.gitignore b/bootstrap/.gitignore similarity index 100% rename from project/.gitignore rename to bootstrap/.gitignore diff --git a/project/Makefile b/bootstrap/Makefile similarity index 82% rename from project/Makefile rename to bootstrap/Makefile index 881dec3..d1cb3cf 100644 --- a/project/Makefile +++ b/bootstrap/Makefile @@ -41,11 +41,14 @@ live/sync_assets: dev: @make -j5 live/templ live/server live/tailwind live/sync_assets -reset: - @GOOSE_DRIVER=postgres GOOSE_DBSTRING=$(dsn) goose -dir=$(migrationPath) reset +db-status: + GOOSE_DRIVER=$(DB_DRIVER) GOOSE_DBSTRING=$(DB_NAME) goose status -up: - @GOOSE_DRIVER=postgres GOOSE_DBSTRING=$(dsn) goose -dir=$(migrationPath) up +db-reset: + @GOOSE_DRIVER=$(DB_DRIVER) GOOSE_DBSTRING=$(DB_NAME) goose -dir=$(MIGRATION_DIR) reset -seed: - @go run scripts/seed/main.go \ No newline at end of file +db-up: + @GOOSE_DRIVER=$(DB_DRIVER) GOOSE_DBSTRING=$(DB_NAME) goose -dir=$(MIGRATION_DIR) up + +db-seed: + @go run cmd/scripts/seed/main.go \ No newline at end of file diff --git a/project/assets/app.css b/bootstrap/app/assets/app.css similarity index 100% rename from project/assets/app.css rename to bootstrap/app/assets/app.css diff --git a/bootstrap/app/conf/conf.go b/bootstrap/app/conf/conf.go new file mode 100644 index 0000000..bcc5f2b --- /dev/null +++ b/bootstrap/app/conf/conf.go @@ -0,0 +1,3 @@ +package conf + +// Application config diff --git a/bootstrap/app/db/db.go b/bootstrap/app/db/db.go new file mode 100644 index 0000000..872c510 --- /dev/null +++ b/bootstrap/app/db/db.go @@ -0,0 +1,34 @@ +package db + +import ( + "log" + "os" + + "github.com/anthdm/gothkit/pkg/db" + "github.com/anthdm/gothkit/pkg/kit" + + _ "github.com/mattn/go-sqlite3" + "github.com/uptrace/bun" + "github.com/uptrace/bun/dialect/sqlitedialect" + "github.com/uptrace/bun/extra/bundebug" +) + +var Query *bun.DB + +func init() { + config := db.Config{ + Driver: os.Getenv("DB_DRIVER"), + Name: os.Getenv("DB_NAME"), + Password: os.Getenv("DB_PASSWORD"), + User: os.Getenv("DB_USER"), + Host: os.Getenv("DB_HOST"), + } + db, err := db.New(config) + if err != nil { + log.Fatal(err) + } + Query = bun.NewDB(db, sqlitedialect.New()) + if kit.IsDevelopment() { + Query.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true))) + } +} diff --git a/project/public/favicon.ico b/bootstrap/app/db/migrations/.keep similarity index 100% rename from project/public/favicon.ico rename to bootstrap/app/db/migrations/.keep diff --git a/bootstrap/app/handlers/auth.go b/bootstrap/app/handlers/auth.go new file mode 100644 index 0000000..86fde2a --- /dev/null +++ b/bootstrap/app/handlers/auth.go @@ -0,0 +1,13 @@ +package handlers + +import ( + "net/http" + + "example-app/app/types" + + "github.com/anthdm/gothkit/pkg/kit" +) + +func HandleAuthentication(w http.ResponseWriter, r *http.Request) (kit.Auth, error) { + return types.AuthUser{}, nil +} diff --git a/bootstrap/app/handlers/landing.go b/bootstrap/app/handlers/landing.go new file mode 100644 index 0000000..06724a5 --- /dev/null +++ b/bootstrap/app/handlers/landing.go @@ -0,0 +1,13 @@ +package handlers + +import ( + "example-app/app/db" + "example-app/app/views/landing" + + "github.com/anthdm/gothkit/pkg/kit" +) + +func HandleLandingIndex(kit *kit.Kit) error { + db.Query.NewSelect().Scan(kit.Request.Context()) + return kit.Render(landing.Index()) +} diff --git a/bootstrap/app/routes.go b/bootstrap/app/routes.go new file mode 100644 index 0000000..1712836 --- /dev/null +++ b/bootstrap/app/routes.go @@ -0,0 +1,61 @@ +package app + +import ( + "example-app/app/handlers" + "example-app/app/views/errors" + "log/slog" + + "github.com/anthdm/gothkit/pkg/kit" + "github.com/anthdm/gothkit/pkg/kit/middleware" + "github.com/go-chi/chi/v5" + + chimiddleware "github.com/go-chi/chi/v5/middleware" +) + +// Define your global middleware +func InitializeMiddleware(router *chi.Mux) { + router.Use(chimiddleware.Logger) + router.Use(chimiddleware.Recoverer) + router.Use(middleware.WithRequestURL) +} + +// Define your routes in here +func InitializeRoutes(router *chi.Mux) { + // Comment out to configure your authentication + authConfig := kit.AuthenticationConfig{ + AuthFunc: handlers.HandleAuthentication, + RedirectURL: "/login", + } + + // Routes that "might" have an authenticated user + router.Group(func(app chi.Router) { + app.Use(kit.WithAuthentication(authConfig, false)) // strict set to false + + // Routes + app.Get("/", kit.Handler(handlers.HandleLandingIndex)) + }) + + // Authenticated routes + // + // Routes that "must" have an authenticated user or else they + // will be redirected to the configured redirectURL, set in the + // AuthenticationConfig. + router.Group(func(app chi.Router) { + app.Use(kit.WithAuthentication(authConfig, true)) // strict set to true + + // Routes + // app.Get("/path", kit.Handler(myHandler.HandleIndex)) + }) +} + +// NotFoundHandler that will be called when the requested path could +// not be found. +func NotFoundHandler(kit *kit.Kit) error { + return kit.Render(errors.Error404()) +} + +// ErrorHandler that will be called on errors return from application handlers. +func ErrorHandler(kit *kit.Kit, err error) { + slog.Error("internal server error", "err", err.Error(), "path", kit.Request.URL.Path) + kit.Render(errors.Error500()) +} diff --git a/bootstrap/app/types/auth.go b/bootstrap/app/types/auth.go new file mode 100644 index 0000000..ee4eb51 --- /dev/null +++ b/bootstrap/app/types/auth.go @@ -0,0 +1,14 @@ +package types + +// AuthUser represents an user that might be authenticated. +type AuthUser struct { + ID int + Email string + LoggedIn bool +} + +// Check should return true if the user is authenticated. +// See handlers/auth.go. +func (user AuthUser) Check() bool { + return user.ID > 0 && user.LoggedIn +} diff --git a/project/views/components/navigation.templ b/bootstrap/app/views/components/navigation.templ similarity index 100% rename from project/views/components/navigation.templ rename to bootstrap/app/views/components/navigation.templ diff --git a/project/views/errors/404.templ b/bootstrap/app/views/errors/404.templ similarity index 85% rename from project/views/errors/404.templ rename to bootstrap/app/views/errors/404.templ index 59bbe26..d5eaae5 100644 --- a/project/views/errors/404.templ +++ b/bootstrap/app/views/errors/404.templ @@ -1,10 +1,10 @@ package errors import ( - "example-app/views/layouts" + "example-app/app/views/layouts" ) -templ Error400() { +templ Error404() { @layouts.BaseLayout() {
404
diff --git a/project/views/errors/500.templ b/bootstrap/app/views/errors/500.templ similarity index 88% rename from project/views/errors/500.templ rename to bootstrap/app/views/errors/500.templ index 31b5c1c..61a6b97 100644 --- a/project/views/errors/500.templ +++ b/bootstrap/app/views/errors/500.templ @@ -1,6 +1,6 @@ package errors -import "example-app/views/layouts" +import "example-app/app/views/layouts" templ Error500() { @layouts.BaseLayout() { diff --git a/bootstrap/app/views/landing/index.templ b/bootstrap/app/views/landing/index.templ new file mode 100644 index 0000000..cca2a97 --- /dev/null +++ b/bootstrap/app/views/landing/index.templ @@ -0,0 +1,18 @@ +package landing + +import ( + "github.com/anthdm/gothkit/pkg/view" + "example-app/app/views/layouts" +) + +templ Index() { + @layouts.App() { +
+

Ship stuff with small teams

+
+
{ view.URL(ctx).Path }
+ if view.Auth(ctx).Check() { +
You are authenticated
+ } + } +} diff --git a/project/views/layouts/app_layout.templ b/bootstrap/app/views/layouts/app_layout.templ similarity index 77% rename from project/views/layouts/app_layout.templ rename to bootstrap/app/views/layouts/app_layout.templ index 1d13a79..6cb2d15 100644 --- a/project/views/layouts/app_layout.templ +++ b/bootstrap/app/views/layouts/app_layout.templ @@ -1,6 +1,6 @@ package layouts -import "example-app/views/components" +import "example-app/app/views/components" templ App() { @BaseLayout() { diff --git a/project/views/layouts/base_layout.templ b/bootstrap/app/views/layouts/base_layout.templ similarity index 100% rename from project/views/layouts/base_layout.templ rename to bootstrap/app/views/layouts/base_layout.templ diff --git a/project/cmd/app/main.go b/bootstrap/cmd/app/main.go similarity index 55% rename from project/cmd/app/main.go rename to bootstrap/cmd/app/main.go index 5837795..6607af8 100644 --- a/project/cmd/app/main.go +++ b/bootstrap/cmd/app/main.go @@ -1,33 +1,30 @@ package main import ( - "log" - "log/slog" + "example-app/app" + "fmt" "net/http" "os" - "example-app/db" - + "github.com/anthdm/gothkit/pkg/kit" "github.com/go-chi/chi/v5" ) func main() { - db, err := db.New() - if err != nil { - log.Fatal(err) - } - - _ = db - - // Routes configuration router := chi.NewMux() - if true { - router.Handle("/*", disableCache(staticDev())) - } - initializeRoutes(router, db) - listenAddr := os.Getenv("HTTP_LISTEN_ADDR") - slog.Info("application started", "listenAddr", listenAddr) + app.InitializeMiddleware(router) + + if kit.IsDevelopment() { + router.Handle("/public/*", disableCache(staticDev())) + } + + kit.UseErrorHandler(app.ErrorHandler) + router.HandleFunc("/*", kit.Handler(app.NotFoundHandler)) + + app.InitializeRoutes(router) + + fmt.Printf("application running in %s at %s\n", kit.Env(), "http://localhost:7331") http.ListenAndServe(os.Getenv("HTTP_LISTEN_ADDR"), router) } diff --git a/bootstrap/cmd/scripts/seed/main.go b/bootstrap/cmd/scripts/seed/main.go new file mode 100644 index 0000000..60b2520 --- /dev/null +++ b/bootstrap/cmd/scripts/seed/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("there are no seeds.") +} diff --git a/bootstrap/go.mod b/bootstrap/go.mod new file mode 100644 index 0000000..64de1ff --- /dev/null +++ b/bootstrap/go.mod @@ -0,0 +1,29 @@ +module example-app + +go 1.22.0 + +require ( + github.com/anthdm/gothkit v0.0.0-00010101000000-000000000000 + github.com/go-chi/chi/v5 v5.0.12 +) + +require ( + github.com/fatih/color v1.16.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + golang.org/x/sys v0.19.0 // indirect +) + +require ( + github.com/a-h/templ v0.2.707 // indirect + github.com/mattn/go-sqlite3 v1.14.22 + github.com/uptrace/bun v1.2.1 + github.com/uptrace/bun/dialect/sqlitedialect v1.2.1 + github.com/uptrace/bun/extra/bundebug v1.2.1 +) + +replace github.com/anthdm/gothkit => ../gothkit diff --git a/bootstrap/go.sum b/bootstrap/go.sum new file mode 100644 index 0000000..d6e0145 --- /dev/null +++ b/bootstrap/go.sum @@ -0,0 +1,33 @@ +github.com/a-h/templ v0.2.707 h1:T1Gkd2ugbRglZ9rYw/VBchWOSZVKmetDbBkm4YubM7U= +github.com/a-h/templ v0.2.707/go.mod h1:5cqsugkq9IerRNucNsI4DEamdHPsoGMQy99DzydLhM8= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= +github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +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/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/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +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-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= +github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= +github.com/uptrace/bun v1.2.1 h1:2ENAcfeCfaY5+2e7z5pXrzFKy3vS8VXvkCag6N2Yzfk= +github.com/uptrace/bun v1.2.1/go.mod h1:cNg+pWBUMmJ8rHnETgf65CEvn3aIKErrwOD6IA8e+Ec= +github.com/uptrace/bun/dialect/sqlitedialect v1.2.1 h1:IprvkIKUjEjvt4VKpcmLpbMIucjrsmUPJOSlg19+a0Q= +github.com/uptrace/bun/dialect/sqlitedialect v1.2.1/go.mod h1:mMQf4NUpgY8bnOanxGmxNiHCdALOggS4cZ3v63a9D/o= +github.com/uptrace/bun/extra/bundebug v1.2.1 h1:85MYpX3QESYI02YerKxUi1CD9mHuLrc2BXs1eOCtQus= +github.com/uptrace/bun/extra/bundebug v1.2.1/go.mod h1:sfGKIi0HSGxsTC/sgIHGwpnYduHHYhdMeOIwurgSY+Y= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/project/package-lock.json b/bootstrap/package-lock.json similarity index 100% rename from project/package-lock.json rename to bootstrap/package-lock.json diff --git a/project/package.json b/bootstrap/package.json similarity index 100% rename from project/package.json rename to bootstrap/package.json diff --git a/bootstrap/public/favicon.ico b/bootstrap/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/project/public/styles.css b/bootstrap/public/styles.css similarity index 100% rename from project/public/styles.css rename to bootstrap/public/styles.css diff --git a/project/tailwind.config.js b/bootstrap/tailwind.config.js similarity index 100% rename from project/tailwind.config.js rename to bootstrap/tailwind.config.js diff --git a/gothkit/pkg/db/db.go b/gothkit/pkg/db/db.go new file mode 100644 index 0000000..6d611ad --- /dev/null +++ b/gothkit/pkg/db/db.go @@ -0,0 +1,31 @@ +package db + +import ( + "database/sql" + "fmt" +) + +const ( + DriverSqlite3 = "sqlite3" +) + +type Config struct { + Driver string + Name string + Host string + User string + Password string +} + +func New(cfg Config) (*sql.DB, error) { + switch cfg.Driver { + case DriverSqlite3: + name := cfg.Name + if len(name) == 0 { + name = "app_db" + } + return sql.Open(cfg.Driver, name) + default: + return nil, fmt.Errorf("invalid database driver (%s): currently only sqlite3 is supported", cfg.Driver) + } +} diff --git a/gothkit/pkg/kit/kit.go b/gothkit/pkg/kit/kit.go index c6f8ff6..ae0f33a 100644 --- a/gothkit/pkg/kit/kit.go +++ b/gothkit/pkg/kit/kit.go @@ -5,6 +5,7 @@ import ( "encoding/json" "log/slog" "net/http" + "os" "github.com/a-h/templ" ) @@ -24,15 +25,14 @@ type Auth interface { } var ( - auth Auth = defaultAuth{} - errorHandler = func(kit *Kit, err error) { + errorHandler = func(kit *Kit, err error) { kit.Text(http.StatusInternalServerError, err.Error()) } ) -type defaultAuth struct{} +type DefaultAuth struct{} -func (defaultAuth) Check() bool { return false } +func (DefaultAuth) Check() bool { return false } type Kit struct { Response http.ResponseWriter @@ -40,19 +40,28 @@ type Kit struct { } func UseErrorHandler(h ErrorHandlerFunc) { errorHandler = h } -func SetAuth(a Auth) { auth = a } func (kit *Kit) Auth() Auth { value, ok := kit.Request.Context().Value(AuthKey{}).(Auth) if !ok { slog.Warn("kit authentication not set") - return auth + return DefaultAuth{} } return value } -func (kit *Kit) Redirect(status int, url string) { +func (kit *Kit) Redirect(status int, url string) error { http.Redirect(kit.Response, kit.Request, url, status) + return nil +} + +func (kit *Kit) HXRedirect(status int, url string) error { + if len(kit.Request.Header.Get("HX-Request")) > 0 { + kit.Response.Header().Set("HX-Redirect", url) + kit.Response.WriteHeader(http.StatusSeeOther) + return nil + } + return kit.Redirect(status, url) } func (kit *Kit) JSON(status int, v any) error { @@ -123,3 +132,15 @@ func WithAuthentication(config AuthenticationConfig, strict bool) func(http.Hand }) } } + +func IsDevelopment() bool { + return os.Getenv("KIT_ENV") == "development" +} + +func IsProduction() bool { + return os.Getenv("KIT_ENV") == "production" +} + +func Env() string { + return os.Getenv("KIT_ENV") +} diff --git a/gothkit/pkg/kit/middleware/middleware.go b/gothkit/pkg/kit/middleware/middleware.go index 1ec8bbd..9cedfdb 100644 --- a/gothkit/pkg/kit/middleware/middleware.go +++ b/gothkit/pkg/kit/middleware/middleware.go @@ -1,14 +1,15 @@ package middleware -// func Authenticated(next http.Handler) http.Handler { -// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { -// kit := &kit.Kit{ -// Response: w, -// Request: r, -// } -// if !kit.Auth().LoggedIn { +import ( + "context" + "net/http" +) -// } -// next.ServeHTTP(w, r.WithContext(ctx)) -// }) -// } +type RequestURLKey struct{} + +func WithRequestURL(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), RequestURLKey{}, r.URL) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} diff --git a/gothkit/pkg/view/view.go b/gothkit/pkg/view/view.go new file mode 100644 index 0000000..811fba1 --- /dev/null +++ b/gothkit/pkg/view/view.go @@ -0,0 +1,31 @@ +package view + +import ( + "context" + "net/url" + + "github.com/anthdm/gothkit/pkg/kit" + "github.com/anthdm/gothkit/pkg/kit/middleware" +) + +// Auth is a view helper function that returns the currency Auth. +// If Auth is not set a default auth will be returned +func Auth(ctx context.Context) kit.Auth { + value, ok := ctx.Value(kit.AuthKey{}).(kit.Auth) + if !ok { + return kit.DefaultAuth{} + } + return value +} + +// URL is a view helper that returns the current URL. +// The request path can be acccessed with: +// view.URL(ctx).Path +func URL(ctx context.Context) *url.URL { + value, ok := ctx.Value(middleware.RequestURLKey{}).(*url.URL) + if !ok { + return &url.URL{} + } + return value + +} diff --git a/install.sh b/install.sh index dac6154..25acc30 100755 --- a/install.sh +++ b/install.sh @@ -1 +1,14 @@ -echo "this is working fine" \ No newline at end of file +#!/bin/bash + +echo "enter the name of you project: " +read varname + +git clone git@github.com:anthdm/gothkit.git _gothkit +cd _gothkit +mv bootstrap ../$varname +cd .. +rm -rf _gothkit +echo "" +echo "project installed successfully" +echo "your project folder is available => cd $varname" + diff --git a/project/cmd/app/routes.go b/project/cmd/app/routes.go deleted file mode 100644 index 8f59252..0000000 --- a/project/cmd/app/routes.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "database/sql" - "log/slog" - "net/http" - - "github.com/anthdm/gothkit/pkg/kit" - "github.com/go-chi/chi/v5" - - "example-app/handlers" - "example-app/views/errors" -) - -// Define your routes in here -func initializeRoutes(router *chi.Mux, db *sql.DB) { - // Configure the error handler - kit.UseErrorHandler(func(kit *kit.Kit, err error) { - slog.Error("internal server error", "err", err.Error(), "path", kit.Request.URL.Path) - kit.Render(errors.Error500()) - }) - - // Comment out to configure your authentication - authConfig := kit.AuthenticationConfig{ - AuthFunc: handleAuthentication, - RedirectURL: "/login", - } - - landingHandler := handlers.NewLandingHandler(db) - // Routes that "might" have an authenticated user - router.Group(func(app chi.Router) { - app.Use(kit.WithAuthentication(authConfig, false)) // strict set to false - - // Routes - app.Get("/", kit.Handler(landingHandler.HandleIndex)) - }) - - // Routes that "must" have an authenticated user or else they - // will be redirected to the configured redirectURL, set in the - // AuthenticationConfig. - router.Group(func(app chi.Router) { - app.Use(kit.WithAuthentication(authConfig, true)) // strict set to true - - // Routes - // app.Get("/path", kit.Handler(myHandler.HandleIndex)) - }) -} - -type AuthUser struct { - ID int - Email string - LoggedIn bool -} - -func (user AuthUser) Check() bool { - return user.ID > 0 && user.LoggedIn -} - -func handleAuthentication(w http.ResponseWriter, r *http.Request) (kit.Auth, error) { - return AuthUser{}, nil -} diff --git a/project/db/db.go b/project/db/db.go deleted file mode 100644 index a4c8fee..0000000 --- a/project/db/db.go +++ /dev/null @@ -1,28 +0,0 @@ -package db - -import ( - "database/sql" - "fmt" - "os" - - _ "github.com/mattn/go-sqlite3" -) - -const ( - DriverSqlite3 = "sqlite3" -) - -func New() (*sql.DB, error) { - driver := os.Getenv("DB_DRIVER") - - switch driver { - case DriverSqlite3: - name := os.Getenv("DB_NAME") - if len(name) == 0 { - name = "gothkit" - } - return sql.Open(driver, name) - default: - return nil, fmt.Errorf("invalid database driver (%s): currently only sqlite3 is supported", driver) - } -} diff --git a/project/go.mod b/project/go.mod deleted file mode 100644 index 36273e4..0000000 --- a/project/go.mod +++ /dev/null @@ -1,15 +0,0 @@ -module example-app - -go 1.22.0 - -require ( - github.com/anthdm/gothkit v0.0.0-00010101000000-000000000000 - github.com/go-chi/chi/v5 v5.0.12 -) - -require ( - github.com/a-h/templ v0.2.707 // indirect - github.com/mattn/go-sqlite3 v1.14.22 -) - -replace github.com/anthdm/gothkit => ../gothkit diff --git a/project/go.sum b/project/go.sum deleted file mode 100644 index 915f235..0000000 --- a/project/go.sum +++ /dev/null @@ -1,8 +0,0 @@ -github.com/a-h/templ v0.2.707 h1:T1Gkd2ugbRglZ9rYw/VBchWOSZVKmetDbBkm4YubM7U= -github.com/a-h/templ v0.2.707/go.mod h1:5cqsugkq9IerRNucNsI4DEamdHPsoGMQy99DzydLhM8= -github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= -github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -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/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= diff --git a/project/handlers/landing.go b/project/handlers/landing.go deleted file mode 100644 index 9f9510f..0000000 --- a/project/handlers/landing.go +++ /dev/null @@ -1,22 +0,0 @@ -package handlers - -import ( - "database/sql" - "example-app/views/landing" - - "github.com/anthdm/gothkit/pkg/kit" -) - -type LandingHandler struct { - db *sql.DB -} - -func NewLandingHandler(db *sql.DB) *LandingHandler { - return &LandingHandler{ - db: db, - } -} - -func (h *LandingHandler) HandleIndex(kit *kit.Kit) error { - return kit.Render(landing.Index()) -} diff --git a/project/views/landing/index.templ b/project/views/landing/index.templ deleted file mode 100644 index 49bdaa6..0000000 --- a/project/views/landing/index.templ +++ /dev/null @@ -1,11 +0,0 @@ -package landing - -import "example-app/views/layouts" - -templ Index() { - @layouts.App() { -
-

Ship stuff with small teams

-
- } -}