najm-core
v1.2.12
Published
Core framework package for Najm — a decorator-driven TypeScript API framework built on Hono.js with dependency injection via diject.
Downloads
1,233
Readme
najm-core
Core framework package for Najm — a decorator-driven TypeScript API framework built on Hono.js with dependency injection via diject.
Install
bun add najm-core diject hono reflect-metadataWhat You Get
Server— Main HTTP server class with plugin system, DI container, lifecycle hooks- Merged plugins —
params,router,middleware,resolutionare auto-registered on first boot - DI re-exports —
Service,Controller,Repository,Inject,DI,Scopefrom diject - Tokens —
REQUEST_ID,SERVER_OPTS,APP,BASE_PATH,LOGGER - Logging —
LoggerService,@Log()decorator - Scanner —
ScannerService,@Scan(),registerScanInjector - Boot —
BootServicelifecycle management - Errors —
HttpError,AppError,DBError,GuardError,RouterError
Usage
import 'reflect-metadata';
import { Server, Service, Controller, Get, Post, Body, Params } from 'najm-core';
@Service()
class UserService {
getUsers() {
return [{ id: 1, name: 'Alice' }];
}
}
@Controller('/users')
class UserController {
constructor(private users: UserService) {}
@Get('/')
list() {
return this.users.getUsers();
}
@Get('/:id')
get(@Params('id') id: string) {
return { id, name: 'User ' + id };
}
@Post('/')
create(@Body() data: any) {
return { created: true, ...data };
}
}
await new Server()
.load(UserController, UserService)
.listen(3000);Plugin Architecture
import { Server } from 'najm-core';
import { plugin } from 'najm-core';
export const myPlugin = (config?: any) =>
plugin('my-plugin')
.version('1.0.0')
.services(MyPluginService)
.config(MY_CONFIG, config ?? {})
.build();
await new Server()
.use(myPlugin({ option: 'value' }))
.load(MyController)
.listen(3000);TypeScript Configuration
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}Production Notes
reflect-metadatamust be imported before any decorated class loads- Auto-registered plugins (
params,router,middleware,resolution) boot with default settings on firstlisten()orfetch()call - Use
new Server({ isolated: true })in tests to get a fresh DI container - In bundled environments (Next.js, Vite SSR), use
.load(moduleObject)instead of.scan()
