Skip to content

VSKI v0.4.0

  • Backend Expand Operation Fixed:
    • The expand operation now correctly handles relations created via the frontend dashboard
    • Backend previously only checked for collectionId in relation field options
    • Now falls back to toCollection which is used by the frontend when creating collections
    • Fixes silent failures where expand would return just the ID instead of expanded objects
  • Relation Field Selector Display:

    • Relation fields in the add/edit record modal now display as a small table
    • Shows the first non-system field value (excluding id, created, updated)
    • Displays last 4 characters of the record ID for easy identification
    • No longer relies on defaultSearchField which may not be set
  • Edit Record Relation Fields:

    • Fixed crash when editing records with expanded relation fields
    • Relation fields are now properly normalized when loading records for editing
    • Expanded objects are converted to IDs
    • Array relations extract IDs from each expanded item
    • Resolves “Objects are not valid as a React child” error

Download binary for your platform:

Terminal window
# Linux (standalone with embedded UI)
wget https://vski.sh/x/platform/releases/download/v0.4.0/vski-standalone
chmod +x vski-standalone
./vski-standalone
# Linux (API-only)
wget https://vski.sh/x/platform/releases/download/v0.4.0/vski
chmod +x vski
./vski

Pull and run official Docker image:

Terminal window
# Light version (API only, no embedded UI)
docker pull vski.sh/x/vski:latest
# Standalone version (with embedded web UI)
docker pull vski.sh/x/vski:latest-standalone
# Pull specific version
docker pull vski.sh/x/vski:v0.4.0
docker pull vski.sh/x/vski:v0.4.0-standalone
# Run light version with default configuration
docker run -p 3000:3000 -v $(pwd)/data:/app/data vski.sh/x/vski:latest
# Run standalone version with embedded web UI
docker run -p 3000:3000 -v $(pwd)/data:/app/data vski.sh/x/vski:latest-standalone

Create a .env file:

DATA_DIR=./data
SERVER_PORT=3000
JWT_SECRET=your-secret-key
// Query records with expanded relations (now works correctly)
const response = await fetch('http://localhost:3000/api/collections/posts/records?expand=author,comments', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
});
const data = await response.json();
console.log(data.items[0].expand.author); // Expanded object, not just ID

Creating Collections with Relations (Frontend)

Section titled “Creating Collections with Relations (Frontend)”
// Frontend creates collections with toCollection option
const collection = {
name: 'posts',
schema: [
{
name: 'author',
type: 'relation',
options: {
toCollection: 'users', // Now correctly handled by backend
maxSelect: 1
}
}
]
};
await fetch('http://localhost:3000/api/collections', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_JWT_TOKEN'
},
body: JSON.stringify(collection)
});
Terminal window
# Clone repository
git clone https://vski.sh/x/platform.git
cd platform/vski
# Build production binary
make build
# Build release binary (with UPX compression)
make build-release
# Run binary
./bin/vski

All changes are backward compatible. Existing collections and records will work without any changes.

None.

The expand parameter now correctly returns expanded objects for cross-database relations:

Before (buggy):

{
"id": "post1",
"author": "user123", // Just the ID
"expand": {
"author": "user123" // Still just the ID, not expanded
}
}

After (fixed):

{
"id": "post1",
"author": "user123",
"expand": {
"author": {
"id": "user123",
"email": "user@example.com",
"name": "John Doe",
"created": "2026-02-21T12:00:00Z",
"updated": "2026-02-21T12:00:00Z"
}
}
}
Terminal window
cd vski
make build
make e2e TEST=44_crossdb_expand_test.ts # Test cross-database expand
make e2e # Run all E2E tests
Terminal window
# Create two collections with relation
curl -X POST http://localhost:3000/api/collections \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "users",
"schema": [
{"name": "id", "type": "text", "system": true, "primary": true},
{"name": "name", "type": "text"}
]
}'
curl -X POST http://localhost:3000/api/collections \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "posts",
"schema": [
{"name": "id", "type": "text", "system": true, "primary": true},
{"name": "title", "type": "text"},
{"name": "author", "type": "relation", "options": {"toCollection": "users", "maxSelect": 1}}
]
}'
# Create records
curl -X POST http://localhost:3000/api/collections/users/records \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"id": "user1", "name": "John"}'
curl -X POST http://localhost:3000/api/collections/posts/records \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"id": "post1", "title": "Hello", "author": "user1"}'
# Test expand (should return expanded user object)
curl 'http://localhost:3000/api/collections/posts/records?expand=author' \
-H "Authorization: Bearer YOUR_TOKEN"

Full documentation available at: https://vski.sh/x/platform

  • Backend expand operation now correctly handles toCollection option in relation fields
  • Fixed silent failures where expand would return just ID instead of expanded objects
  • Relation field selector in frontend now displays as small table with field value and ID
  • Fixed crash when editing records with expanded relation fields
  • Relation fields are now properly normalized (object to ID) when loading for editing
  • Resolved “Objects are not valid as a React child” error in record edit modal
  • Frontend relation picker no longer requires defaultSearchField to be set
  • Frontend automatically detects first non-system field for display
  • Last 4 characters of ID shown instead of full ID for better readability
  • Modified internal/repositories/record_repository.go:634 to check both collectionId and toCollection
  • Updated web/components/ui/record-form.tsx to normalize relation fields on record load
  • Enhanced relation field display logic to work with any expanded object structure