Skip to content

Instantly share code, notes, and snippets.

@Zxce3
Created January 8, 2025 21:14
Show Gist options
  • Save Zxce3/96363ac331dc535fe7b90f5b7897e960 to your computer and use it in GitHub Desktop.
Save Zxce3/96363ac331dc535fe7b90f5b7897e960 to your computer and use it in GitHub Desktop.
Just Something
package main
import (
"log"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/plugins/ghupdate"
"github.com/pocketbase/pocketbase/plugins/jsvm"
"github.com/pocketbase/pocketbase/plugins/migratecmd"
"github.com/pocketbase/pocketbase/tools/hook"
)
// createPublicDir ensures the pb_public directory exists
func createPublicDir(publicDir string) error {
return os.MkdirAll(publicDir, 0755)
}
// generateIndexHTML creates the index.html file
func generateIndexHTML(publicDir string) error {
indexHTML := `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to PocketBase</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
}
.hero {
background-color: white;
border-radius: 8px;
padding: 2rem;
margin-top: 2rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #333;
margin-bottom: 1rem;
}
p {
color: #666;
margin-bottom: 1rem;
}
.cta-button {
display: inline-block;
background-color: #3b82f6;
color: white;
padding: 0.75rem 1.5rem;
border-radius: 4px;
text-decoration: none;
transition: background-color 0.2s;
}
.cta-button:hover {
background-color: #2563eb;
}
</style>
</head>
<body>
<div class="container">
<div class="hero">
<h1>Welcome to PocketBase</h1>
<p>Your backend is up and running successfully! This is a simple landing page served from the pb_public directory.</p>
<p>Start building your application by:</p>
<ul>
<li>Accessing the admin UI at <a href="//_">/_/</a></li>
<li>Exploring the API at <a href="//_.html">/_/api-docs</a></li>
<li>Reading the <a href="https://pocketbase.io/docs/" target="_blank">documentation</a></li>
</ul>
<a href="/_/" class="cta-button">Go to Admin UI</a>
</div>
</div>
</body>
</html>`
return os.WriteFile(filepath.Join(publicDir, "index.html"), []byte(indexHTML), 0644)
}
func main() {
app := pocketbase.New()
// ---------------------------------------------------------------
// Optional plugin flags:
// ---------------------------------------------------------------
var hooksDir string
app.RootCmd.PersistentFlags().StringVar(
&hooksDir,
"hooksDir",
"",
"the directory with the JS app hooks",
)
var hooksWatch bool
app.RootCmd.PersistentFlags().BoolVar(
&hooksWatch,
"hooksWatch",
true,
"auto restart the app on pb_hooks file change",
)
var hooksPool int
app.RootCmd.PersistentFlags().IntVar(
&hooksPool,
"hooksPool",
15,
"the total prewarm goja.Runtime instances for the JS app hooks execution",
)
var migrationsDir string
app.RootCmd.PersistentFlags().StringVar(
&migrationsDir,
"migrationsDir",
"",
"the directory with the user defined migrations",
)
var automigrate bool
app.RootCmd.PersistentFlags().BoolVar(
&automigrate,
"automigrate",
true,
"enable/disable auto migrations",
)
var publicDir string
app.RootCmd.PersistentFlags().StringVar(
&publicDir,
"publicDir",
defaultPublicDir(),
"the directory to serve static files",
)
var indexFallback bool
app.RootCmd.PersistentFlags().BoolVar(
&indexFallback,
"indexFallback",
true,
"fallback the request to index.html on missing static path (eg. when pretty urls are used with SPA)",
)
app.RootCmd.ParseFlags(os.Args[1:])
// Create public directory and generate index.html
if err := createPublicDir(publicDir); err != nil {
log.Fatal("Failed to create public directory:", err)
}
if err := generateIndexHTML(publicDir); err != nil {
log.Fatal("Failed to generate index.html:", err)
}
// ---------------------------------------------------------------
// Plugins and hooks:
// ---------------------------------------------------------------
// load jsvm (pb_hooks and pb_migrations)
jsvm.MustRegister(app, jsvm.Config{
MigrationsDir: migrationsDir,
HooksDir: hooksDir,
HooksWatch: hooksWatch,
HooksPoolSize: hooksPool,
})
// migrate command (with js templates)
migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{
TemplateLang: migratecmd.TemplateLangJS,
Automigrate: automigrate,
Dir: migrationsDir,
})
// GitHub selfupdate
ghupdate.MustRegister(app, app.RootCmd, ghupdate.Config{})
// static route to serves files from the provided public dir
app.OnServe().Bind(&hook.Handler[*core.ServeEvent]{
Func: func(e *core.ServeEvent) error {
if !e.Router.HasRoute(http.MethodGet, "/{path...}") {
e.Router.GET("/{path...}", apis.Static(os.DirFS(publicDir), indexFallback))
}
return e.Next()
},
Priority: 999,
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}
// the default pb_public dir location is relative to the executable
func defaultPublicDir() string {
if strings.HasPrefix(os.Args[0], os.TempDir()) {
// most likely ran with go run
return "./pb_public"
}
return filepath.Join(os.Args[0], "../pb_public")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment