Package Management
Lockness provides a powerful package management system that automatically
configures and integrates additional features into your application. Packages
are registered in deno.json and loaded dynamically at runtime.
Overview
The package system allows you to add functionality to your Lockness application
with zero configuration. Packages automatically register their CLI commands,
services, and configurations when listed in your deno.json.
Key Benefits:
- Zero configuration - just install and use
- Automatic CLI command registration
- Install scripts for automated setup
- Declarative package configuration
- Clean uninstallation
Configuration
Packages are declared in the lockness section of your deno.json:
{
"lockness": {
"packages": [
"drizzle",
"openapi",
"cache",
"socialite"
]
}
}
When your application starts, Lockness automatically:
- Loads each package from the list
- Registers their CLI commands
- Makes their services available via DI
Installing Packages
Option 1: Automated Installation (Recommended)
Use the package:install command for fully automated setup:
deno task cli package:install openapi
This command will:
- Add the package to
deno.json - Run the package's install script (if available)
- Create necessary files and configurations
- Display next steps and documentation links
Example output:
$ deno task cli package:install openapi
🌊 Installing @lockness/openapi...
✓ Added openapi to lockness.packages
✓ Created app/controller/docs_controller.ts
⚠️ Routes need to be regenerated:
Run: deno task routes:generate
✅ @lockness/openapi installed successfully!
📖 Next steps:
1. Start your dev server: deno task dev
2. Visit: http://localhost:8888/docs
3. Document your routes with @ApiDoc decorator
Option 2: Manual Configuration
Add the package manually and configure it yourself:
deno task cli package:add openapi
This only adds the package to your configuration. You'll need to follow the package's documentation for manual setup.
Option 3: Direct Script Execution
Run a package's install script directly from JSR:
deno run -A jsr:@lockness/openapi/install
Removing Packages
Remove a package from your configuration:
deno task cli package:remove openapi
Available Commands
| Command | Description |
|---|---|
package:install <name> | Install and configure a package with automated setup |
package:add <name> | Add package to configuration only (no setup) |
package:remove <name> | Remove package from configuration |
Official Packages
@lockness/drizzle
Category: Database
Drizzle ORM integration with migrations, seeders, and CLI commands.
deno task cli package:install drizzle
@lockness/openapi
Category: API
OpenAPI/Swagger documentation with automatic spec generation.
deno task cli package:install openapi
@lockness/cache
Category: Performance
Multi-driver caching system (Memory, Deno KV, Redis).
deno task cli package:install cache
@lockness/socialite
Category: Auth
OAuth2 authentication (Google, GitHub, Discord).
deno task cli package:install socialite
How It Works
When you start your application, the cli.ts file loads packages automatically:
import { Cli, loadPackageCommands, registerCoreCommands } from '@lockness/cli'
const cli = new Cli()
// Register core commands
registerCoreCommands(cli)
// Load commands from packages in deno.json
await loadPackageCommands(cli)
// Discover user commands
await cli.discoverCommands('./app/command')
The loadPackageCommands() function:
- Reads the
lockness.packagesarray fromdeno.json - Dynamically imports each package
- Looks for a
register*Commandsfunction - Calls the function to register CLI commands
Creating Your Own Package
You can create custom Lockness packages that integrate seamlessly with the package management system.
1. Export Register Function
// my-package/index.ts
import type { Cli } from '@lockness/cli'
export function registerMyPackageCommands(cli: Cli) {
cli.register('my:command', async () => {
console.log('Hello from my package!')
}, 'My custom command')
}
export { myPackageFunction } from './lib.ts'
2. Create Install Script (Optional)
// my-package/install.ts
import { addPackage } from '@lockness/cli'
async function main() {
console.log('🌊 Installing my-package...\n')
// Add to deno.json
await addPackage('my-package')
// Create config file
await Deno.writeTextFile(
'./config/my-package.ts',
'export const config = { enabled: true }',
)
console.log('✅ Installation complete!')
}
if (import.meta.main) {
await main()
}
3. Update Package Configuration
// deno.json
{
"name": "@myorg/my-package",
"exports": {
".": "./index.ts",
"./install": "./install.ts"
}
}
4. Development Standards
To maintain consistency and ensure compatibility across the Lockness ecosystem, all packages should follow these standards:
- mod.ts: Always use
mod.tsas the main entry point for your package. - tests/: Place all test files in a dedicated
tests/directory and use the*.test.tsnaming convention. - Imports: Use named workspace imports (e.g.,
@lockness/core) for cross-package dependencies. - JSR: Configure the
publishfield in yourdeno.jsonto include only source files.
See CLI documentation for complete documentation on creating install scripts.