REPL

An interactive shell that boots your tekir app and lets you experiment with models, services, and database queries.

Introduction

The tekir REPL boots your application and drops you into an interactive JavaScript/TypeScript shell. All registered services (database, cache, auth, etc.) are available immediately. Use helpers like loadModels() to bring your models into scope, then query, create, and delete records directly from the shell.

The REPL is ideal for:

  • Exploring your database with model queries
  • Testing service methods (cache, mail, queue)
  • Debugging configuration values
  • Seeding data during development
  • Running one-off scripts against your app

Starting the REPL

tekir repl

The REPL boots your app (runs all providers), then shows a banner with available helpers:

tekir REPL v0.1

  await loadModels()    Load app models
  await loadServices()  Load app services
  .help                 REPL commands

Services: db, cache, redis, auth

tekir>

Loading Models

Call await loadModels() to scan app/models/ and load every model into the models namespace. Models are available by their camelCase name (e.g. User becomes models.user).

tekir> await loadModels()
Loaded 3 model(s): user, post, comment

tekir> models.user
[class User extends BaseModel]

tekir> await models.user.all()
[
  { id: 1, email: '[email protected]', fullName: 'Admin' },
  { id: 2, email: '[email protected]', fullName: 'Jane' }
]

Loading Services

await loadServices() imports your services.ts file and makes all exported service proxies available. Common services like db, cache, and auth are pre-loaded automatically if they are registered in your app.

tekir> await loadServices()
Loaded services: db, cache, mail, auth

tekir> await cache.get('site:name')
'tekir Framework'

tekir> config('app.name')
'My App'

Querying Data

Once models are loaded you can use the full model API. Top-level await is supported, no wrapper functions needed.

// Find a user by ID
tekir> const user = await models.user.find(1)
tekir> user.email
'[email protected]'

// Create a new user
tekir> await models.user.create({
...   fullName: 'Test User',
...   email: '[email protected]',
...   password: 'secret'
... })
{ id: 3, fullName: 'Test User', email: '[email protected]' }

// Delete a user
tekir> const u = await models.user.find(3)
tekir> await u.delete()
tekir> u.$isDeleted
true

// Raw database query
tekir> await db.query('SELECT COUNT(*) as count FROM users')
[{ count: 2 }]

Importing Files

Use .import to load any project file into the REPL context. Exports become available as variables.

// Import any project file into the REPL
tekir> .import app/validators/auth.ts
Imported: loginSchema, registerSchema

tekir> loginSchema.parse({ email: '[email protected]', password: 'secret' })
{ email: '[email protected]', password: 'secret' }

REPL Commands

Type .help to see all available commands:

tekir> .help

.help              Show all commands
.exit              Exit the REPL
.clear             Clear the screen
.models            List loaded models
.services          List available services
.import <path>     Import a project file
.editor            Enter multi-line editor mode (Ctrl+D to run)
.break             Cancel current multi-line input

Pre-loaded Services

The REPL automatically attempts to load common services from the DI container. Only services that are actually registered in your app will be available:

// These are available immediately, no loadServices() needed:
tekir> app           // the DI container
tekir> config        // config('key') accessor
tekir> logger        // Logger instance
tekir> db            // Database (if registered)
tekir> cache         // Cache (if registered)
tekir> redis         // Redis (if registered)
tekir> auth          // Auth manager (if registered)
tekir> drive         // Drive (if registered)
tekir> mail          // Mail (if registered)
tekir> emitter       // Event emitter (if registered)
tekir> queue         // Queue (if registered)
tekir> hash          // Hash (if registered)
tekir> encrypt       // Encryption (if registered)

History

Command history is persisted to .tekir/repl_history and loaded on each session. Use the Up/Down arrow keys to navigate previous commands. Multi-line input is supported: unclosed brackets automatically continue on the next line.

// History is persisted across sessions in .tekir/repl_history
// Use Up/Down arrows to navigate previous commands
// Multi-line input is supported with open brackets:

tekir> const users = await models.user
...   .query()
...   .where('active', true)
...   .limit(10)

// Top-level await works everywhere:
tekir> await fetch('https://api.example.com/health').then(r => r.json())
{ status: 'ok' }