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
-
- }
-}