> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/pocketbase/pocketbase/llms.txt
> Use this file to discover all available pages before exploring further.

# Utilities

> Helper utilities and tools in PocketBase

PocketBase provides various utility packages and helpers for common tasks.

## Security utilities

### Random string generation

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/security"

// Generate random string with default alphabet
randomStr := security.RandomString(32)

// Generate with custom alphabet
customStr := security.RandomStringWithAlphabet(16, "0123456789ABCDEF")

// Pseudorandom (not cryptographically secure, but faster)
pseudoStr := security.PseudorandomString(32)
```

### Hashing

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/security"

// MD5 hash
hash := security.MD5("text to hash")

// SHA256 hash  
hash := security.SHA256("text to hash")

// SHA512 hash
hash := security.SHA512("text to hash")
```

### Password hashing

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/security"

// Hash a password (uses bcrypt)
hashed, err := security.HashPassword("mypassword123")
if err != nil {
    log.Fatal(err)
}

// Verify password
if security.CompareHashAndPassword(hashed, "mypassword123") {
    log.Println("Password is correct")
}
```

## JWT tokens

### Creating tokens

```go theme={null}
import (
    "time"
    "github.com/pocketbase/pocketbase/tools/security"
)

// Create a JWT token
token, err := security.NewJWT(
    map[string]any{
        "userId": "123",
        "email":  "user@example.com",
    },
    "your-secret-key",
    time.Now().Add(24 * time.Hour).Unix(), // expiry
)
if err != nil {
    log.Fatal(err)
}

log.Println("Token:", token)
```

### Parsing tokens

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/security"

tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

token, err := security.ParseUnverifiedJWT(tokenString)
if err != nil {
    log.Fatal(err)
}

// Access claims
userId := token.Get("userId")
email := token.Get("email")
```

### Verifying tokens

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/security"

token, err := security.ParseJWT(tokenString, "your-secret-key")
if err != nil {
    log.Fatal("Invalid or expired token")
}

log.Println("Valid token for:", token.Get("userId"))
```

## List utilities

### Working with slices

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/list"

// Check if item exists in slice
slice := []string{"apple", "banana", "orange"}
if list.ExistInSlice("banana", slice) {
    log.Println("Found banana")
}

// Convert to unique string slice
data := []any{"a", "b", "a", "c", "b"}
unique := list.ToUniqueStringSlice(data)
// Result: ["a", "b", "c"]

// Subtract slices
slice1 := []string{"a", "b", "c"}
slice2 := []string{"b", "d"}
result := list.SubtractSlice(slice1, slice2)
// Result: ["a", "c"]
```

## Type utilities

### DateTime

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/types"

// Create DateTime from string
dt, err := types.ParseDateTime("2024-01-15 14:30:00.000Z")
if err != nil {
    log.Fatal(err)
}

// Current DateTime
now := types.NowDateTime()

// Convert to time.Time
timeObj := dt.Time()

// Format as string
str := dt.String()
```

### JSON types

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/types"

// JSONArray
jsonArray := types.JSONArray[string]{"a", "b", "c"}

// JSONMap
jsonMap := types.JSONMap[any]{
    "key1": "value1",
    "key2": 123,
}

// JSONRaw (for storing raw JSON)
raw := types.JSONRaw(`{"custom": "data"}`)
```

### Pointer helper

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/types"

// Create pointer to value
strPtr := types.Pointer("hello")
intPtr := types.Pointer(123)
boolPtr := types.Pointer(true)

// Useful for optional fields
collection.ListRule = types.Pointer("@request.auth.id != ''")
```

## Store

Thread-safe in-memory key-value store:

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/store"

// Create store
s := store.New[string, any](nil)

// Set values
s.Set("key1", "value1")
s.Set("key2", 123)

// Get value
value := s.Get("key1")

// Get with existence check
value, exists := s.GetOk("key1")
if exists {
    log.Println("Found:", value)
}

// Get all
allData := s.GetAll()

// Has key
if s.Has("key1") {
    log.Println("Key exists")
}

// Remove
s.Remove("key1")

// Reset with new data
s.Reset(map[string]any{
    "new_key": "new_value",
})
```

## Filesystem utilities

### File upload from URL

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/filesystem"

file, err := filesystem.NewFileFromURL(
    "https://example.com/image.jpg",
)
if err != nil {
    log.Fatal(err)
}

// Use with record
record.Set("avatar", file)
app.Save(record)
```

## Template utilities

### Template rendering

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/template"

registry := template.NewRegistry()

// Load templates
tpl, err := registry.LoadFiles(
    "templates/welcome.html",
    "templates/footer.html",
)
if err != nil {
    log.Fatal(err)
}

// Render with data
html, err := tpl.Render(map[string]any{
    "name":  "John",
    "title": "Welcome",
})
if err != nil {
    log.Fatal(err)
}
```

### Template from string

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/template"

registry := template.NewRegistry()

tpl, err := registry.LoadString("Hello {{.name}}!")
if err != nil {
    log.Fatal(err)
}

result, _ := tpl.Render(map[string]any{
    "name": "World",
})
// Result: "Hello World!"
```

## Inflector

String manipulation utilities:

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/inflector"

// Columnify - format for SQL column names
colName := inflector.Columnify("UserName")
// Result: "userName"

// Sentenize - convert to sentence
sentence := inflector.Sentenize("hello_world")
// Result: "Hello world"

// Pluralize
plural := inflector.Pluralize("post")
// Result: "posts"

// Singularize  
singular := inflector.Singularize("users")
// Result: "user"
```

## Search utilities

### Building search providers

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/search"

// Create search provider
provider := search.NewProvider(fieldResolver)

// Parse search/filter string
result, err := provider.Parse("title ~ 'test' && status = 'active'")
if err != nil {
    log.Fatal(err)
}

// Apply to query
app.DB().Select("*").From("posts").AndWhere(result.BuildExpr())
```

## Cron utilities

### Scheduling tasks

```go theme={null}
// Add cron job
app.Cron().Add("daily_cleanup", "0 0 * * *", func() {
    log.Println("Running daily cleanup")
    // Cleanup logic
})

// Remove job
app.Cron().Remove("daily_cleanup")

// Check if job exists
if app.Cron().Has("daily_cleanup") {
    log.Println("Job is scheduled")
}
```

Cron expression format:

```
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday = 0)
│ │ │ │ │
* * * * *
```

### Common cron patterns

```go theme={null}
// Every minute
app.Cron().Add("task", "* * * * *", handler)

// Every hour
app.Cron().Add("task", "0 * * * *", handler)

// Every day at midnight
app.Cron().Add("task", "0 0 * * *", handler)

// Every Monday at 9 AM
app.Cron().Add("task", "0 9 * * 1", handler)

// First day of month
app.Cron().Add("task", "0 0 1 * *", handler)
```

## Routine utilities

Background task execution:

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/routine"

// Fire and forget
routine.FireAndForget(func() {
    // Long-running task
    time.Sleep(5 * time.Second)
    log.Println("Background task completed")
})
```

## Archive utilities

Create and extract archives:

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/archive"

// Create ZIP archive
err := archive.Create(
    []string{"file1.txt", "file2.txt"},
    "archive.zip",
)
if err != nil {
    log.Fatal(err)
}

// Extract archive
err = archive.Extract("archive.zip", "./destination")
if err != nil {
    log.Fatal(err)
}
```

## Tokenizer

Parse and tokenize strings:

```go theme={null}
import "github.com/pocketbase/pocketbase/tools/tokenizer"

tokenizer := tokenizer.NewFromString("hello world test")

for {
    token := tokenizer.Scan()
    if token.Type == tokenizer.EOF {
        break
    }
    log.Println("Token:", token.Literal)
}
```

## Best practices

### Use appropriate utilities

```go theme={null}
// Good - use list utilities
if list.ExistInSlice(item, slice) {
    // ...
}

// Bad - manual loop
found := false
for _, v := range slice {
    if v == item {
        found = true
        break
    }
}
```

### Cache expensive operations

```go theme={null}
// Cache in app store
key := "expensive_result"
if !app.Store().Has(key) {
    result := expensiveOperation()
    app.Store().Set(key, result)
}

result := app.Store().Get(key)
```

### Use type-safe stores

```go theme={null}
// Good - type-safe
type UserCache struct {
    *store.Store[string, *core.Record]
}

cache := &UserCache{
    Store: store.New[string, *core.Record](nil),
}

cache.Set("user_123", userRecord)
```
