### Installation Source: https://zeltjs.com/docs/getting-started/electron Install the necessary ZeltJS packages and Electron. ```bash pnpm add @zeltjs/core@0.6.1 @zeltjs/adapter-electron@0.6.1 pnpm add -D electron ``` -------------------------------- ### Install Zelt Core and Node Adapter Source: https://zeltjs.com/docs/getting-started/node Install the necessary Zelt packages for a Node.js application. ```bash pnpm add @zeltjs/core@0.6.1 @zeltjs/adapter-node@0.6.1 ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/getting-started/lambda Install the necessary Zelt.js packages and development dependencies for AWS Lambda. ```bash pnpm add @zeltjs/core@0.6.1 @zeltjs/adapter-lambda@0.6.1 pnpm add -D @types/aws-lambda esbuild ``` -------------------------------- ### Server Options Example Source: https://zeltjs.com/docs/getting-started/bun Example of configuring server options like port and hostname. ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onBun } from '@zeltjs/adapter-bun'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const bunApp = await onBun(app); // ---cut--- const server = bunApp.serve({ port: 8080, hostname: '127.0.0.1', }); ``` -------------------------------- ### Start the Server Source: https://zeltjs.com/docs/getting-started/node Create the main entry point to start the Zelt server. ```typescript import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onNode } from '@zeltjs/adapter-node'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const nodeApp = await onNode(app); const server = await nodeApp.listen({ port: 3000 }); console.log(`Server running at http://localhost:${server.address.port}`); ``` -------------------------------- ### Command Support Example Source: https://zeltjs.com/docs/getting-started/bun Example demonstrating how to integrate and execute CLI commands with ZeltJS on Bun. ```typescript // @noErrors import { createApp, Command, Arg, Controller, Get } from '@zeltjs/core'; import { onBun } from '@zeltjs/adapter-bun'; @Controller('/hello') class HelloController { @Get('/') greet() { return { message: 'Hello!' }; } } @Command('greet') class GreetCommand { constructor(private name = Arg(0)) {} run() { console.log(`Hello, ${this.name}!`); } } const app = createApp({ http: { controllers: [HelloController], }, commands: [GreetCommand], }); // ---cut--- const bunApp = await onBun(app); const result = await bunApp.execCommand(['greet', 'world']); console.log(result.exitCode); // 0 or 1 ``` -------------------------------- ### Hello World - Step 3: Call API from Renderer Source: https://zeltjs.com/docs/getting-started/electron Example of calling the Electron-hosted API from the renderer process. ```javascript const response = await fetch('api://localhost/hello/world'); const data = await response.json(); console.log(data.message); // "Hello, world!" ``` -------------------------------- ### Create the Application Source: https://zeltjs.com/docs/getting-started/node Wire up controllers and prepare the application for the Node.js runtime. ```typescript import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onNode } from '@zeltjs/adapter-node'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } export const app = createApp({ http: { controllers: [HelloController], }, }); export default await onNode(app); ``` -------------------------------- ### Install ZeltJS dependencies for Bun Source: https://zeltjs.com/docs/getting-started/bun Install the core ZeltJS library and the Bun adapter. ```bash bun add @zeltjs/core@0.6.1 @zeltjs/adapter-bun@0.6.1 ``` -------------------------------- ### Hello World: Create the Lambda Handler Source: https://zeltjs.com/docs/getting-started/lambda Create the Lambda handler file for the Hello World example. ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onLambda } from '@zeltjs/adapter-lambda'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); // ---cut--- const lambdaApp = await onLambda(app); export const handler = lambdaApp.handler; ``` -------------------------------- ### Lazy Initialization Example Source: https://zeltjs.com/docs/getting-started/bun Example demonstrating how to configure ZeltJS for lazy controller initialization on Bun. ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onBun } from '@zeltjs/adapter-bun'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); // ---cut--- const bunApp = await onBun(app, { warmup: false }); ``` -------------------------------- ### Run the Application Source: https://zeltjs.com/docs/getting-started/node Command to run the Zelt Node.js application using tsx. ```bash npx tsx src/main.ts ``` -------------------------------- ### Run the Server Source: https://zeltjs.com/docs/getting-started/bun Command to run the ZeltJS application on Bun. ```bash bun run src/index.ts ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Install the necessary Zelt packages and Wrangler CLI for Cloudflare Workers. ```bash pnpm add @zeltjs/core@0.6.1 @zeltjs/adapter-cloudflare-workers@0.6.1 pnpm add -D wrangler @cloudflare/workers-types ``` -------------------------------- ### Hello World Controller Source: https://zeltjs.com/docs/getting-started/bun Create a controller to handle 'hello' routes. ```typescript // @noErrors import { Controller, Get, pathParam } from '@zeltjs/core'; // ---cut--- @Controller('/hello') export class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } ``` -------------------------------- ### Node.js Specific Configs Source: https://zeltjs.com/docs/getting-started/node Overview of configuration options provided by the Node.js adapter. ```typescript import { ProcessEnvConfig, DotEnvConfig } from '@zeltjs/adapter-node'; // ProcessEnvConfig: Reads from process.env (default behavior) // DotEnvConfig: Reads from .env file void ProcessEnvConfig; void DotEnvConfig; ``` -------------------------------- ### Deployment Commands Source: https://zeltjs.com/docs/getting-started/lambda Build and deploy the application using SAM CLI. ```bash sam build sam deploy --guided ``` -------------------------------- ### Quick Example Source: https://zeltjs.com/docs A basic example demonstrating how to define a controller and a GET route in ZeltJS. ```typescript import { const Controller: (basePath: string) => ClassDecoratorFn @throws{E} Controller, const Get: (path: string) => MethodDecoratorFnGet } from '@zeltjs/core'; @function Controller(basePath: string): ClassDecoratorFn @throws{E} Controller('/hello') class class HelloControllerHelloController { @function Get(path: string): MethodDecoratorFnGet('/') ``` HelloController.greet(): { message: string; } ``` `greet() { return { `message: string`message: 'Hello, World!' }; } } ``` ``` -------------------------------- ### TypeScript Configuration Source: https://zeltjs.com/docs/getting-started/node Configure TypeScript for a Zelt Node.js project. ```json { "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "experimentalDecorators": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["src"] } ``` -------------------------------- ### Hello World Application Source: https://zeltjs.com/docs/getting-started/bun Create the main application instance, including the HelloController. ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } // ---cut--- export const app = createApp({ http: { controllers: [HelloController], }, }); ``` -------------------------------- ### Registering Configuration in App Source: https://zeltjs.com/docs/getting-started/node Registering configuration classes, like EnvConfig, in the Zelt application. ```typescript import { createApp, EnvConfig, Controller, Get, inject, EnvService } from '@zeltjs/core'; @Controller('/config') class ConfigController { constructor(private env = inject(EnvService)) {} @Get('/api-host') getApiHost() { return { apiHost: this.env.getString('API_HOST', 'localhost') }; } } export const app = createApp({ http: { controllers: [ConfigController], }, configs: [EnvConfig], }); ``` -------------------------------- ### Hello World - Step 1: Create the Application Source: https://zeltjs.com/docs/getting-started/electron Define a ZeltJS application with a 'HelloController'. ```typescript import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } export const app = createApp({ http: { controllers: [HelloController], }, }); ``` -------------------------------- ### Hello World Entry Point Source: https://zeltjs.com/docs/getting-started/bun Create the entry point for the Bun application, integrating the ZeltJS app with the Bun runtime. ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onBun } from '@zeltjs/adapter-bun'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); // ---cut--- const bunApp = await onBun(app); const server = bunApp.serve({ port: 3000 }); console.log(`Server running at http://${server.address.hostname}:${server.address.port}`); ``` -------------------------------- ### Step 2: Create the Application Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Create the application instance and wire up your controllers. ```typescript import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } export const app = createApp({ http: { controllers: [HelloController], }, }); ``` -------------------------------- ### Hello World - Step 2: Initialize in Main Process Source: https://zeltjs.com/docs/getting-started/electron Initialize the ZeltJS app within the Electron main process using the adapter. ```typescript // @noErrors import { app as electronApp, BrowserWindow, protocol } from 'electron'; import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onElectron } from '@zeltjs/adapter-electron'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const electronZelt = await onElectron(app); electronApp.whenReady().then(() => { protocol.handle('api', async (request) => { return electronZelt.fetch(request); }); const win = new BrowserWindow({ width: 800, height: 600 }); win.loadFile('index.html'); }); electronApp.on('window-all-closed', async () => { await electronZelt.shutdown(); electronApp.quit(); }); ``` -------------------------------- ### Update Controller to Use Service Source: https://zeltjs.com/docs/getting-started/node Modify the controller to inject and use the GreetingService. ```typescript import { Controller, Get, pathParam, inject, Injectable } from '@zeltjs/core'; @Injectable() class GreetingService { greet(name: string): string { return `Hello, ${name}!`; } } @Controller('/hello') export class HelloController { constructor(private greetingService = inject(GreetingService)) {} @Get('/:name') greet(name = pathParam('name')) { return { message: this.greetingService.greet(name) }; } } ``` -------------------------------- ### HTTP API (v2) Handler Source: https://zeltjs.com/docs/getting-started/lambda Example of configuring the Lambda handler for HTTP API (v2). ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onLambda } from '@zeltjs/adapter-lambda'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const lambdaApp = await onLambda(app); // ---cut--- export const handler = lambdaApp.handler; ``` -------------------------------- ### SAM Template Configuration Source: https://zeltjs.com/docs/getting-started/lambda Create the SAM template file for deploying the Lambda function. ```yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Globals: Function: Timeout: 30 Runtime: nodejs20.x Resources: HelloFunction: Type: AWS::Serverless::Function Properties: CodeUri: dist/ Handler: handler.handler Events: Api: Type: HttpApi Properties: Path: /{proxy+} Method: ANY Metadata: BuildMethod: esbuild BuildProperties: Minify: true Target: es2022 EntryPoints: - src/handler.ts Outputs: ApiEndpoint: Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" ``` -------------------------------- ### REST API (v1) Handler Source: https://zeltjs.com/docs/getting-started/lambda Example of configuring the Lambda handler for REST API (v1). ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onLambda } from '@zeltjs/adapter-lambda'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const lambdaApp = await onLambda(app); // ---cut--- export const handler = lambdaApp.handlerV1; ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/bullmq Install BullMQ and ioredis using pnpm. ```bash pnpm add bullmq ioredis ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/kv Install the @zeltjs/kv package using pnpm. ```bash pnpm add @zeltjs/kv ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/testing/unit Install the @zeltjs/testing package as a development dependency. ```bash pnpm add -D @zeltjs/testing ``` -------------------------------- ### Install @zeltjs/openapi with bun Source: https://zeltjs.com/docs/openapi Installation command for @zeltjs/openapi using bun. ```bash bun add @zeltjs/openapi ``` -------------------------------- ### Install @zeltjs/db Source: https://zeltjs.com/docs/db Install the database package using pnpm. ```bash pnpm add @zeltjs/db ``` -------------------------------- ### Install @zeltjs/openapi and @valibot/to-json-schema with bun Source: https://zeltjs.com/docs/openapi Installation command for @zeltjs/openapi and @valibot/to-json-schema using bun. ```bash bun add @zeltjs/openapi @valibot/to-json-schema ``` -------------------------------- ### Step 6: Run Locally Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Run the Zelt application locally using the Wrangler development server. ```bash npx wrangler dev ``` -------------------------------- ### Install @zeltjs/openapi with npm Source: https://zeltjs.com/docs/openapi Installation command for @zeltjs/openapi using npm. ```bash npm install @zeltjs/openapi ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/hono-client Install the @zeltjs/hono-client package using pnpm. ```bash pnpm add @zeltjs/hono-client ``` -------------------------------- ### Warmup Option - Lazy Initialization Source: https://zeltjs.com/docs/getting-started/electron Configure the Electron adapter for lazy initialization of controllers. ```typescript import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onElectron } from '@zeltjs/adapter-electron'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const electronZelt = await onElectron(app, { warmup: false }); ``` -------------------------------- ### Installation (bun) Source: https://zeltjs.com/docs/validation Install the Valibot validator for Zelt using bun. ```bash bun add @zeltjs/validator-valibot valibot ``` -------------------------------- ### Starting the Scheduler Source: https://zeltjs.com/docs/scheduler Illustrates how to explicitly start the scheduler after the Zelt.js application is ready using `startScheduler()`. ```typescript import { createApp, Controller, Get, Scheduled, Daily, Hourly } from '@zeltjs/core'; import { onNode } from '@zeltjs/adapter-node'; @Controller('/users') class UserController { @Get('/') findAll() { return { users: [] }; } } @Scheduled() class ReportScheduler { @Daily({ hour: 9 }) async sendDailyReport() {} @Hourly() async checkHealth() {} } const app = createApp({ http: { controllers: [UserController] }, schedulers: [ReportScheduler] }); const nodeApp = await onNode(app); // ---cut--- await nodeApp.startScheduler(); ``` -------------------------------- ### Step 1: Create the Controller Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Create a controller to handle incoming HTTP requests and define routes. ```typescript import { Controller, Get, pathParam } from '@zeltjs/core'; @Controller('/hello') export class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } ``` -------------------------------- ### Type Declaration File Example Source: https://zeltjs.com/docs/authentication/user-context Example of a `types/zelt.d.ts` file for type declarations. ```typescript // @noErrors // Reason: module augmentation requires full module resolution unavailable in Twoslash VFS // types/zelt.d.ts import '@zeltjs/core'; // ---cut--- declare module '@zeltjs/core' { interface RequestContextSchema { user: { id: string; name: string; email: string; avatarUrl?: string; }; authRoles: ('admin' | 'moderator' | 'user')[]; } } export {}; ``` -------------------------------- ### Injecting a Service into a Controller Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Demonstrates how to inject the GreetingService into HelloController using ZeltJS's dependency injection. ```typescript import { Controller, Get, pathParam, inject, Injectable } from '@zeltjs/core'; @Injectable() class GreetingService { greet(name: string): string { return `Hello, ${name}!`; } } @Controller('/hello') export class HelloController { constructor(private greetingService = inject(GreetingService)) {} @Get('/:name') greet(name = pathParam('name')) { return { message: this.greetingService.greet(name) }; } } ``` -------------------------------- ### Install @zeltjs/openapi with pnpm Source: https://zeltjs.com/docs/openapi Installation command for @zeltjs/openapi using pnpm. ```bash pnpm add @zeltjs/openapi ``` -------------------------------- ### Step 3: Create the Worker Entry Point Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Create the Cloudflare Workers entry point and prepare the app for the Workers runtime. ```typescript import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onCloudflareWorkers } from '@zeltjs/adapter-cloudflare-workers'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const workers = await onCloudflareWorkers(app); export default { fetch: workers.fetch }; ``` -------------------------------- ### Step 5: Configure TypeScript Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Configure TypeScript for the project, including module resolution and types. ```json { "compilerOptions": { "target": "ES2022", "module": "ESNext", "moduleResolution": "Bundler", "strict": true, "experimentalDecorators": true, "skipLibCheck": true, "types": ["@cloudflare/workers-types"] }, "include": ["src"] } ``` -------------------------------- ### Install @zeltjs/openapi and @valibot/to-json-schema with npm Source: https://zeltjs.com/docs/openapi Installation command for @zeltjs/openapi and @valibot/to-json-schema using npm. ```bash npm install @zeltjs/openapi @valibot/to-json-schema ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/eventbus Install the eventbus package and optionally the Redis adapter. ```bash pnpm add @zeltjs/eventbus ``` ```bash pnpm add @zeltjs/eventbus @zeltjs/redis ioredis ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/authentication/jwt Install the @zeltjs/auth-jwt package using pnpm. ```bash pnpm add @zeltjs/auth-jwt ``` -------------------------------- ### Install @zeltjs/openapi and @valibot/to-json-schema with pnpm Source: https://zeltjs.com/docs/openapi Installation command for @zeltjs/openapi and @valibot/to-json-schema using pnpm. ```bash pnpm add @zeltjs/openapi @valibot/to-json-schema ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/authentication/sessions Install the necessary packages for session management. ```bash pnpm add @zeltjs/auth-session @zeltjs/kv ``` -------------------------------- ### Installation (npm) Source: https://zeltjs.com/docs/validation Install the Valibot validator for Zelt using npm. ```bash npm install @zeltjs/validator-valibot valibot ``` -------------------------------- ### Step 4: Configure Wrangler Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Configure the Wrangler build tool with project details and compatibility settings. ```toml name = "my-zelt-worker" main = "src/index.ts" compatibility_date = "2024-01-01" compatibility_flags = ["nodejs_compat"] [vars] API_HOST = "https://api.example.com" ``` -------------------------------- ### Full CorsConfig Example Source: https://zeltjs.com/docs/http-security A comprehensive example demonstrating various CorsConfig options. ```typescript import { Config, CorsConfig } from '@zeltjs/core'; @Config class MyCorsConfig extends CorsConfig { override readonly origin = 'https://example.com'; override readonly credentials = true; override readonly allowHeaders = ['Content-Type', 'Authorization']; override readonly exposeHeaders = ['X-Request-Id']; override readonly maxAge = 86400; } ``` -------------------------------- ### Installation with OpenAPI Generation (bun) Source: https://zeltjs.com/docs/validation Install the Valibot validator and OpenAPI generation tools using bun. ```bash bun add @zeltjs/validator-valibot valibot @valibot/to-json-schema ``` -------------------------------- ### Installation (pnpm) Source: https://zeltjs.com/docs/validation Install the Valibot validator for Zelt using pnpm. ```bash pnpm add @zeltjs/validator-valibot valibot ``` -------------------------------- ### Custom Container Config Example Source: https://zeltjs.com/docs/testing/integration Example of creating a custom container configuration for PostgreSQL using the Lifecycle interface. ```typescript import { Config, inject, LifecycleManager, type Lifecycle } from '@zeltjs/core'; declare class GenericContainer { constructor(image: string); withEnvironment(env: Record): this; withExposedPorts(port: number): this; start(): Promise; } declare interface StartedTestContainer { getHost(): string; getMappedPort(port: number): number; stop(): Promise; } // ---cut--- @Config export class PostgresTestContainerConfig implements Lifecycle { private container: StartedTestContainer | undefined; private connectionUrl = ''; constructor(lifecycle = inject(LifecycleManager)) { lifecycle.register(this); } async startup(): Promise { this.container = await new GenericContainer('postgres:16-alpine') .withEnvironment({ POSTGRES_USER: 'test', POSTGRES_PASSWORD: 'test', POSTGRES_DB: 'testdb', }) .withExposedPorts(5432) .start(); const host = this.container.getHost(); const port = this.container.getMappedPort(5432); this.connectionUrl = `postgres://test:test@${host}:${port}/testdb`; } async shutdown(): Promise { await this.container?.stop(); } get url(): string { return this.connectionUrl; } } ``` -------------------------------- ### Role examples Source: https://zeltjs.com/docs/authorization/roles Examples of different types of roles: admin, team, and permission-based. ```typescript const adminRoles = ['admin', 'editor', 'viewer']; const teamRoles = ['owner', 'member', 'guest']; const permissionRoles = ['read:users', 'write:users', 'delete:users']; ``` -------------------------------- ### E2E Test Example Source: https://zeltjs.com/docs/testing/e2e This example demonstrates how to set up and run E2E tests for a Zelt.js application. It uses `onTest` to override configurations with test-specific ones, such as using a Redis test container. It also shows how to create a test client to interact with the application's API. ```typescript import { createApp, Controller, Get, Post, pathParam, response } from '@zeltjs/core'; import { validated } from '@zeltjs/validator-valibot'; import { onTest, type TestApp } from '@zeltjs/testing/vitest'; import { RedisConfig } from '@zeltjs/redis'; import { RedisTestContainerConfig } from '@zeltjs/redis/testing'; import * as v from 'valibot'; declare function hc(baseUrl: string, options?: { fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise }): T; declare function describe(name: string, fn: () => void): void; declare function it(name: string, fn: () => void | Promise): void; declare function beforeAll(fn: () => void | Promise): void; declare function expect(value: T): { toBe(expected: T): void; }; const UserBody = v.object({ name: v.string(), email: v.pipe(v.string(), v.email()) }); @Controller('/users') class UserController { @Get('/:id') findOne(id = pathParam('id')) { return { id, name: 'Alice', email: 'alice@example.com' }; } @Post('/') create(body = validated(UserBody), res = response()) { return res.json({ id: '1', ...body }, 201); } } type AppType = { users: { $post: (opts: { json: { name: string; email: string } }) => Promise }>; ':id': { $get: (opts: { param: { id: string } }) => Promise }> }; }; }; // ---cut--- // Production app - same as your real application const app = createApp({ configs: [RedisConfig], http: { controllers: [UserController] }, }); describe('API E2E', () => { let testApp: TestApp; let client: AppType; beforeAll(async () => { // onTest() overrides RedisConfig with RedisTestContainerConfig testApp = await onTest(app, { configs: [RedisTestContainerConfig], }); client = hc('http://localhost', { fetch: (input: RequestInfo | URL, init?: RequestInit) => testApp.fetch(new Request(input, init)), }); }); it('should create and retrieve user', async () => { const createRes = await client.users.$post({ json: { name: 'Alice', email: 'alice@example.com' }, }); expect(createRes.status).toBe(201); const { id } = await createRes.json(); const getRes = await client.users[':id'].$get({ param: { id }, }); expect(getRes.status).toBe(200); const user = await getRes.json(); expect(user.name).toBe('Alice'); }); }); ``` -------------------------------- ### Installation with OpenAPI Generation (npm) Source: https://zeltjs.com/docs/validation Install the Valibot validator and OpenAPI generation tools using npm. ```bash npm install @zeltjs/validator-valibot valibot @valibot/to-json-schema ``` -------------------------------- ### Installation Source: https://zeltjs.com/docs/kv-redis Install the Redis KV driver and its peer dependencies. ```bash pnpm add @zeltjs/kv-driver-redis pnpm add @zeltjs/core @zeltjs/kv ``` -------------------------------- ### Environment Variables Example Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Example of accessing environment variables using EnvService in a Cloudflare Worker. ```typescript import { Controller, Get, inject, EnvService } from '@zeltjs/core'; @Controller('/config') export class ConfigController { constructor(private env = inject(EnvService)) {} @Get('/api-host') getApiHost() { return { apiHost: this.env.getString('API_HOST', 'localhost') }; } } ``` -------------------------------- ### Install JWT or Session authentication packages Source: https://zeltjs.com/docs/authentication/overview Install the necessary packages for JWT or session-based authentication. ```bash # For JWT authentication pnpm add @zeltjs/auth-jwt # For session authentication pnpm add @zeltjs/auth-session @zeltjs/kv ``` -------------------------------- ### Installation with OpenAPI Generation (pnpm) Source: https://zeltjs.com/docs/validation Install the Valibot validator and OpenAPI generation tools using pnpm. ```bash pnpm add @zeltjs/validator-valibot valibot @valibot/to-json-schema ``` -------------------------------- ### Middleware Execution Order Example Source: https://zeltjs.com/docs/middleware Provides a code example demonstrating the execution order of global, controller, and method middleware. ```typescript import type { FunctionMiddleware } from '@zeltjs/core'; // ---cut--- const globalMw: FunctionMiddleware = async (c, next) => { console.log('1. global before'); await next(); console.log('6. global after'); }; const controllerMw: FunctionMiddleware = async (c, next) => { console.log('2. controller before'); await next(); console.log('5. controller after'); }; const methodMw: FunctionMiddleware = async (c, next) => { console.log('3. method before'); await next(); console.log('4. method after'); }; ``` -------------------------------- ### Defining a ZeltJS Service Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Example of how to define a service using the @Injectable decorator in ZeltJS. ```typescript import { Injectable } from '@zeltjs/core'; @Injectable() export class GreetingService { greet(name: string): string { return `Hello, ${name}!`; } } ``` -------------------------------- ### Binary Response Handling Source: https://zeltjs.com/docs/getting-started/lambda Example of how ZeltJS automatically handles binary responses by encoding them as base64, demonstrated with an image response. ```typescript // @noErrors import { Controller, Get, response } from '@zeltjs/core'; // ---cut--- @Controller('/files') export class FileController { @Get('/image') getImage() { const imageBuffer = new Uint8Array([/* ... */]); return response() .header('Content-Type', 'image/png') .body(imageBuffer); } } ``` -------------------------------- ### Configuring warmup option for Cloudflare Workers Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Example of how to set the warmup option to true when initializing the Cloudflare Workers adapter for ZeltJS. ```typescript import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onCloudflareWorkers } from '@zeltjs/adapter-cloudflare-workers'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); const workers = await onCloudflareWorkers(app, { warmup: true }); export default { fetch: workers.fetch }; ``` -------------------------------- ### Accessing secrets via EnvService Source: https://zeltjs.com/docs/getting-started/cloudflare-workers TypeScript example demonstrating how to inject and use EnvService to retrieve secrets within a ZeltJS service. ```typescript import { Injectable, EnvService, inject } from '@zeltjs/core'; @Injectable() class DatabaseService { constructor(private env = inject(EnvService)) {} get connectionUrl() { return this.env.getString('DATABASE_URL', ''); } } ``` -------------------------------- ### Time-Based Roles Source: https://zeltjs.com/docs/authorization/roles Example of filtering roles based on start and expiration times. ```typescript import { setUser } from '@zeltjs/core'; declare const user: { id: string; name: string; roles: string[]; roleGrants: Array<{ role: string; startsAt?: number; expiresAt?: number }>; }; // ---cut--- const roles = user.roles.filter(role => { const grant = user.roleGrants.find(g => g.role === role); if (!grant) return true; const now = Date.now(); if (grant.startsAt && now < grant.startsAt) return false; if (grant.expiresAt && now > grant.expiresAt) return false; return true; }); setUser(user, roles); ``` -------------------------------- ### Manual Setup Source: https://zeltjs.com/docs/testing/unit Import from the base package and call shutdownAll() manually if not using an adapter. ```typescript // @noErrors // Reason: import-only example for test framework setup import { onTest, createTestTarget, shutdownAll, type TestApp } from '@zeltjs/testing'; import { afterAll } from 'your-test-runner'; afterAll(shutdownAll); ``` -------------------------------- ### Node.js Entry Point Source: https://zeltjs.com/docs/scheduler Illustrates how to integrate and start the scheduler in a Node.js application using `@zeltjs/adapter-node`. ```typescript import { onNode } from '@zeltjs/adapter-node'; import { createApp, Scheduled, Daily } from '@zeltjs/core'; @Scheduled() class MyScheduler { @Daily({ hour: 9 }) async task() {} } const app = createApp({ http: { controllers: [] }, schedulers: [MyScheduler] }); // ---cut--- const nodeApp = await onNode(app); const handle = await nodeApp.listen(3000); // Start scheduled tasks await nodeApp.startScheduler(); process.on('SIGTERM', async () => { await nodeApp.stopScheduler(); await handle.shutdown(); }); ``` -------------------------------- ### Registering EnvConfig Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Registering EnvConfig in the application, which will be automatically replaced by CloudflareWorkersEnvConfig in the Workers runtime. ```typescript import { createApp, EnvConfig, Controller, Get, inject, EnvService } from '@zeltjs/core'; @Controller('/config') class ConfigController { constructor(private env = inject(EnvService)) {} @Get('/api-host') getApiHost() { return { apiHost: this.env.getString('API_HOST', 'localhost') }; } } export const app = createApp({ http: { controllers: [ConfigController], }, configs: [EnvConfig], }); ``` -------------------------------- ### Wrangler deploy command Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Command to deploy the ZeltJS worker to Cloudflare's global network. ```bash npx wrangler deploy ``` -------------------------------- ### App Configuration with Worker Startup Source: https://zeltjs.com/docs/bullmq Configuring the app and ensuring workers are instantiated at startup. ```typescript import { createApp, inject, Config, Env } from '@zeltjs/core'; type ConnectionOptions = { host?: string; port?: number }; declare class UserController {} declare class EmailWorker {} @Config class BullMQConfig { static readonly Token = BullMQConfig; constructor(private env = inject(Env)) {} get connection(): ConnectionOptions { return { host: 'localhost', port: 6379 }; } } // ---cut--- const app = createApp({ controllers: [UserController], configs: [BullMQConfig], }); // Instantiate worker to start processing app.ready().then(() => { inject(EmailWorker); }); ``` -------------------------------- ### Eager Initialization with Warmup Option Source: https://zeltjs.com/docs/getting-started/lambda Configure `onLambda` for eager initialization using the `warmup: true` option. ```typescript // @noErrors import { createApp, Controller, Get, pathParam } from '@zeltjs/core'; import { onLambda } from '@zeltjs/adapter-lambda'; @Controller('/hello') class HelloController { @Get('/:name') greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; } } const app = createApp({ http: { controllers: [HelloController] } }); // ---cut--- const lambdaApp = await onLambda(app, { warmup: true }); ``` -------------------------------- ### Wrangler secret put command Source: https://zeltjs.com/docs/getting-started/cloudflare-workers Command to securely store sensitive values like database URLs using Wrangler secrets. ```bash npx wrangler secret put DATABASE_URL ``` -------------------------------- ### Job Options Example Source: https://zeltjs.com/docs/bullmq Adding a job to a BullMQ queue with various options like delay, attempts, and priority. ```typescript import { Queue } from 'bullmq'; const queue = new Queue('reports', { connection: { host: 'localhost', port: 6379 } }); // ---cut--- await queue.add('report', { userId: 123 }, { delay: 60000, // Delay 1 minute attempts: 5, // Retry 5 times backoff: { type: 'exponential', delay: 2000 }, priority: 1, // Higher priority removeOnComplete: 100, // Keep last 100 completed removeOnFail: 50, // Keep last 50 failed }); ``` -------------------------------- ### Creating a Scheduler Source: https://zeltjs.com/docs/scheduler Demonstrates how to create a scheduler class using Zelt.js decorators like `@Scheduled`, `@Daily`, and `@Hourly`. ```typescript import { Scheduled, Cron, Daily, Hourly } from '@zeltjs/core'; @Scheduled() class ReportScheduler { @Daily({ hour: 9 }) async sendDailyReport() { console.log('Sending daily report...'); } @Hourly() async checkHealth() { console.log('Health check...'); } } ``` -------------------------------- ### Quick Overview of Dependency Injection Source: https://zeltjs.com/docs/dependency-injection Demonstrates basic usage of Injectable and inject for dependency injection in ZeltJS. ```typescript import { Injectable, inject } from '@zeltjs/core'; // ---cut--- @Injectable() export class DatabaseService { query(sql: string) { // ... } } @Injectable() export class UserRepository { constructor(private db = inject(DatabaseService)) {} findAll() { return this.db.query('SELECT * FROM users'); } } ``` -------------------------------- ### Install Testcontainers Source: https://zeltjs.com/docs/testing/integration Install the necessary packages for integration testing with Testcontainers. ```bash pnpm add -D @zeltjs/testing testcontainers ``` -------------------------------- ### Using in Controllers Source: https://zeltjs.com/docs/bullmq Example of enqueuing jobs from an HTTP controller using Zelt's dependency injection and validation. ```typescript import { Controller, Post, inject } from '@zeltjs/core'; import { validated } from '@zeltjs/validator-valibot'; import * as v from 'valibot'; declare class EmailService { sendWelcomeEmail(to: string): Promise; } // ---cut--- @Controller('/users') class UserController { constructor(private emailService = inject(EmailService)) {} @Post('/register') async register() { const body = validated(v.object({ email: v.string() })); // ... create user await this.emailService.sendWelcomeEmail(body.email); return { message: 'User registered' }; } } ``` -------------------------------- ### Loading .env Files Source: https://zeltjs.com/docs/configuration To load a .env file, import dotenv/config at the entry point of your application before anything else. ```typescript // @errors: 2882 import 'dotenv/config'; import { onNode } from '@zeltjs/adapter-node'; // ...rest of app setup ``` -------------------------------- ### destroySession Example Source: https://zeltjs.com/docs/authentication/sessions Example of destroying the session and clearing the cookie. ```typescript import { destroySession } from '@zeltjs/auth-session'; destroySession(); ``` -------------------------------- ### Registering Controllers in createApp Source: https://zeltjs.com/docs/controllers Example demonstrating how to register UserController and PostController within the createApp function. ```typescript import { createApp, Controller, Get, Post, pathParam, response } from '@zeltjs/core'; import { validated } from '@zeltjs/validator-valibot'; import * as v from 'valibot'; const CreateUserBody = v.object({ name: v.string(), email: v.pipe(v.string(), v.email()) }); @Controller('/users') class UserController { @Get('/') findAll() { return { users: [] }; } @Get('/:id') findOne(id = pathParam('id')) { return { id }; } @Post('/') create(body = validated(CreateUserBody), res = response()) { return res.json({ id: '1', ...body }, 201); } } @Controller('/posts') class PostController { @Get('/') findAll() { return { posts: [] }; } } // ---cut--- export const app = createApp({ http: { controllers: [UserController, PostController], }, }); ``` -------------------------------- ### Basic App Configuration Source: https://zeltjs.com/docs/bullmq Registering services and BullMQ configuration in the ZeltJS app. ```typescript import { createApp, Config, Env, inject } from '@zeltjs/core'; type ConnectionOptions = { host?: string; port?: number }; declare class UserController {} @Config class BullMQConfig { static readonly Token = BullMQConfig; constructor(private env = inject(Env)) {} get connection(): ConnectionOptions { return { host: 'localhost', port: 6379 }; } } // ---cut--- const app = createApp({ controllers: [UserController], configs: [BullMQConfig], }); export default app; ``` -------------------------------- ### createTestTarget Example Source: https://zeltjs.com/docs/testing/unit Example of using createTestTarget to instantiate a service and test its functionality. ```typescript import { describe, it, expect } from 'vitest'; import { createTestTarget } from '@zeltjs/testing'; import { ProcessEnvConfig } from '@zeltjs/adapter-node'; import { Injectable } from '@zeltjs/core'; @Injectable() class UserService { async create(data: { name: string }) { return data; } } // --- // ---cut--- describe('UserService', () => { it('should create user', async () => { const { target } = await createTestTarget(UserService, { configs: [ProcessEnvConfig], }); const user = await target.create({ name: 'Alice' }); expect(user.name).toBe('Alice'); }); }); ```