kontas
TypeScript icon, indicating that this package has built-in type declarations

0.1.149Β β€’Β PublicΒ β€’Β Published

πŸš€ Kontas Framework Documentation

Kontas adalah framework web minimalis berbasis Bun yang fokus pada kesederhanaan & performa tinggi.

Table of Contents

  1. Getting Started

  2. Basic Features

  3. Intermediate Features

  4. Advanced Features

  5. Security Features

  6. Development Features

  7. Example Implementations

Getting Started

Installation

bun add kontas

Basic Setup

// app.ts
import { Kontas } from "kontas";

const app = new Kontas();
app.start(3000); // default port: 3000

Project Structure

Kontas menggunakan file-based routing yang simple & powerful:

  1. ./routes & ./middleware.ts (default)
  2. ./src/routes & ./src/middleware.ts (fallback)
  3. Custom path via config

Basic Features

Simple Routing

// routes/serve.ts
export async function GET(ctx: Context) {
    return { message: "Hello World!" };
}

Basic Response Types

  1. Object (auto-JSON)
return { status: "success" };
  1. Config Format
return {
    data: { status: "success" },
    config: {
        headers: { 'X-Custom': 'Value' },
        status: 201
    }
};
  1. Raw Response
return new Response('Hello', {
    headers: { 'Content-Type': 'text/plain' }
});

Simple Middleware

// middleware.ts
import type { MiddlewareFunction } from "kontas";

const auth: MiddlewareFunction = async (ctx) => {
    const token = ctx.request.headers.get('Authorization');
    if (!token) return new Response('Unauthorized', { status: 401 });
    ctx.user = { id: 1, role: 'user' };
};

export default [
    {
        middlewares: [auth],
        paths: ['/products']
    }
];

Intermediate Features

Dynamic Routes

// routes/users/[id]/serve.ts
export async function GET(ctx: Context) {
    const { id } = ctx.params;  // string
    return { userId: id };
}

Query Parameters

// routes/products/serve.ts
export async function GET(ctx: Context) {
    // /products?sort=desc&filter=active
    const sort = ctx.query.get('sort');      // 'desc'
    const filter = ctx.query.get('filter');  // 'active'
    
    // Multiple values
    // /products?tags=js&tags=ts
    const tags = ctx.query.getAll('tags');   // ['js', 'ts']
    
    return { sort, filter, tags };
}

Route Patterns

Kontas mendukung beberapa pattern routing:

  • /about -> Static route
  • /users/[id] -> Dynamic route
  • /blog/[...slug] -> Catch-all route
  • /products/[id]/reviews/[reviewId] -> Nested dynamic
  • Query string otomatis tersedia via ctx.query

Context API

Context<T> menyediakan:

  • params: Route parameters (string | string[])
  • query: URLSearchParams (dari query string)
  • request: Raw Request
  • body?: Request body (type T)
  • user?: Custom user data
  • headers: Response headers
  • setHeader(name, value): Set header
  • setStatus(status): Set status
  • status?: Response status

Error Handling

export async function GET(ctx: Context) {
    try {
        throw new Error('Something went wrong');
    } catch (err) {
        return {
            data: { error: err.message },
            config: { status: 500 }
        };
    }
}

Advanced Features

Complex Routing

Catch-all Routes

// routes/docs/[...slug]/serve.ts
export async function GET(ctx: Context) {
    const slug = ctx.params.slug;  // string[]
    return { path: slug.join('/') };
}

Advanced Configuration

const app = new Kontas({
    port: 3000,
    routesDir: './api/routes',
    cors: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type, Authorization',
        'Access-Control-Max-Age': '86400'
    }
});

Advanced Middleware

Pattern matching di paths:

  • /products = Exact match
  • /orders/* = Single wildcard
  • /api/** = Nested wildcard
  • */settings = Suffix match
  • **/profile = Nested suffix match
const middlewares: MiddlewareGroup[] = [
    {
        middlewares: [auth, rateLimit],
        paths: ['/api/**', '*/settings']
    }
];

Advanced Error Handling

Kontas menyediakan class Code utk handle error dgn format yg konsisten & otomatis.

// routes/products/serve.ts
import { Code, type Context } from "kontas";

export async function GET(ctx: Context) {
    // Cara 1: Langsung code aja (default 500)
    throw new Code('SOMETHING_WRONG');
    
    // Cara 2: Status + code
    throw new Code(403, 'FORBIDDEN');
    
    // Cara 3: Status + code + data tambahan
    throw new Code(400, 'INVALID_INPUT', { field: 'email' });
    
    // ❌ Invalid status - TypeScript error
    throw new Code(199, 'INVALID');  // Error: 199 not assignable to type HttpStatus
}

Error handler utk custom message:

// errorHandler.ts
import { Code } from "kontas";

export default function errorHandler(error: Code) {
    const { errorCode } = error;
    
    // success: false udh otomatis dari Code class
    switch(errorCode) {
        case 'NOT_FOUND':
            return {
                message: 'Data tidak ditemukan!',
                data: error.data // Optional
            };
            
        case 'INVALID_CREDENTIAL':
            return {
                message: 'Username atau password salah!'
            };
            
        case 'FORBIDDEN':
            return {
                message: 'Kamu gk punya akses!'
            };
            
        default:
            return {
                message: 'Ada kesalahan di server!'
            };
    }
}

Features:

  • Format error yg konsisten & otomatis
  • Type-safe HTTP status codes (200, 201, 400, 401, etc)
  • Custom error message per kode
  • Auto set success: false
  • Support data tambahan via error.data
  • Type-safe dgn TypeScript
  • Hot reload support

Response Format (otomatis):

{
    "success": false,
    "message": "Pesan error sesuai kode",
    "data": {} // Optional data tambahan
}

Valid HTTP Status Codes:

  • 200, 201 (Success)
  • 400, 401, 403, 404, 405 (Client Error)
  • 500, 502, 503, 504 (Server Error)

Security Features

Rate Limiting

Basic Setup

const app = new Kontas({
    rateLimit: {
        windowMs: 15 * 60 * 1000,  // 15 menit
        max: 100  // max 100 requests per window
    }
});

Advanced Config

const app = new Kontas({
    rateLimit: {
        windowMs: 60 * 1000,  // 1 menit
        max: 30,  // max 30 requests per minute
        message: 'Terlalu banyak request!',
        statusCode: 429,  // Too Many Requests
        skipFailedRequests: true,  // Skip non-2xx responses
        skipSuccessfulRequests: false,
        keyGenerator: (ctx) => {
            // Custom key (e.g., by API key)
            return ctx.request.headers.get('x-api-key') || 'anonymous';
        }
    }
});

Rate Limit Info Headers:

  • X-RateLimit-Limit: Max requests per window
  • X-RateLimit-Remaining: Sisa requests
  • X-RateLimit-Reset: Timestamp reset (ms)
  • Retry-After: Seconds to wait (saat limit tercapai)

Security Headers

Basic Setup

const app = new Kontas({
    securityHeaders: {
        xFrameOptions: 'DENY',  // Prevent clickjacking
        xContentTypeOptions: 'nosniff',  // Prevent MIME-type sniffing
        xXSSProtection: '1; mode=block',  // Enable XSS protection
        referrerPolicy: 'strict-origin-when-cross-origin'
    }
});

Advanced Config

const app = new Kontas({
    securityHeaders: {
        // Prevent clickjacking
        xFrameOptions: 'DENY',
        
        // Prevent MIME-type sniffing
        xContentTypeOptions: 'nosniff',
        
        // Force HTTPS (HSTS)
        strictTransportSecurity: {
            maxAge: 31536000,  // 1 tahun
            includeSubDomains: true,
            preload: true
        },
        
        // XSS protection
        xXSSProtection: '1; mode=block',
        
        // Control referrer info
        referrerPolicy: 'strict-origin-when-cross-origin',
        
        // Content Security Policy
        contentSecurityPolicy: {
            'default-src': ["'self'"],
            'script-src': ["'self'", "'unsafe-inline'"],
            'style-src': ["'self'", "'unsafe-inline'"],
            'img-src': ["'self'", 'data:', 'https:'],
            'font-src': ["'self'"],
            'connect-src': ["'self'", 'https://api.example.com']
        },
        
        // Permissions Policy
        permissionsPolicy: {
            camera: ['none'],
            microphone: ['none'],
            geolocation: ['self'],
            'payment-features': ['self']
        }
    }
});

Available Security Headers:

  • X-Frame-Options: Mencegah clickjacking attacks
  • X-Content-Type-Options: Mencegah MIME-type sniffing
  • Strict-Transport-Security: Memaksa pake HTTPS
  • X-XSS-Protection: Browser built-in XSS protection
  • Referrer-Policy: Kontrol info referrer
  • Content-Security-Policy: Kontrol resource loading
  • Permissions-Policy: Kontrol fitur browser

CSRF Protection

Basic Setup

const app = new Kontas({
    csrf: {
        enabled: true,
        secret: 'your-random-secret-key'  // WAJIB diganti!
    }
});

Advanced Config

const app = new Kontas({
    csrf: {
        enabled: true,
        secret: 'your-random-secret-key',
        
        // Custom names
        cookieName: 'my-csrf-token',
        headerName: 'x-my-csrf-token',
        
        // Cookie settings
        cookieOptions: {
            httpOnly: true,
            secure: true,
            sameSite: 'Strict',
            path: '/',
            maxAge: 3600  // 1 jam
        },
        
        // Skip CSRF check untuk paths tertentu
        ignorePaths: [
            '/webhook',
            '/api/public/*'
        ],
        
        // Skip CSRF check untuk methods tertentu
        ignoreMethods: ['GET', 'HEAD', 'OPTIONS']
    }
});

Client Side Setup

Dengan Fetch:

// CSRF token otomatis ada di cookie
fetch('/api/data', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'x-csrf-token': 'token-from-cookie'  // WAJIB sama dengan cookie
    },
    body: JSON.stringify(data)
});

Dengan Axios:

// Axios bisa auto handle CSRF
axios.defaults.withCredentials = true;  // Enable cookies

CSRF Features:

  • Double submit cookie pattern
  • Zero server-side storage
  • Auto-refresh token per request
  • Configurable per path/method
  • Secure defaults (httpOnly, secure, etc)

Input Sanitization

Basic Setup

const app = new Kontas({
    sanitizer: {
        enabled: true,
        rules: {
            removeXSS: true,
            stripTags: true,
            escapeHTML: true
        }
    }
});

Advanced Config

const app = new Kontas({
    sanitizer: {
        enabled: true,
        rules: {
            // Basic security
            removeXSS: true,      // <script>alert(1)</script> -> alert(1)
            stripTags: true,      // <p>text</p> -> text
            escapeHTML: true,     // <>&'" -> &lt;&gt;&amp;&#39;&quot;
            
            // Content cleaning
            trimSpaces: true,     // "  text  " -> "text"
            removeEmoji: true,    // "hello πŸ‘‹" -> "hello "
            maxLength: 1000,      // Truncate panjang string
            
            // Allow specific HTML
            allowedTags: ['b', 'i', 'em', 'strong'],
            allowedAttributes: {
                'a': ['href', 'title'],
                'img': ['src', 'alt']
            },
            
            // Custom rules
            customRules: [
                {
                    pattern: /badword/gi,
                    replace: '****'
                }
            ]
        },
        
        // Skip sanitize untuk paths tertentu
        ignorePaths: [
            '/admin/*',
            '/api/trusted/*'
        ],
        
        // Atau sanitize HANYA paths tertentu
        onlyPaths: [
            '/api/comments/*',
            '/api/posts/*'
        ]
    }
});

Input Sanitization Features:

  • Auto sanitize request body
  • XSS & injection protection
  • Path-based rules
  • Custom sanitization rules
  • Support JSON & form data
  • Recursive object sanitization

Example Input & Output:

// Input dari client
const input = {
    title: '<script>alert("xss")</script>Hello!',
    desc: '  <b>Some text</b> with emoji πŸ‘‹  ',
    html: '<p onclick="evil()">Click me</p>',
    comment: 'Contains badword here'
};

// Output setelah sanitize
const output = {
    title: 'Hello!',  // script removed
    desc: 'Some text with emoji',  // tags stripped & emoji removed
    html: '<p>Click me</p>',  // onclick removed
    comment: 'Contains **** here'  // custom rule applied
};

Development Features

Hot Reload

const app = new Kontas({
    dev: {
        hotReload: true,
        watchDirs: ['routes', 'middleware']
    }
});

Port Management

const app = new Kontas({
    port: 3000,
    portFallback: true  // Auto switch if port is taken
});

Route Summary

const app = new Kontas({
    dev: {
        showRoutes: true  // Display all registered routes
    }
});

Example Implementations

Dynamic Route + Query

// routes/users/[id]/posts/[postId]/serve.ts
export async function GET(ctx: Context) {
    // URL: /users/123/posts/456?sort=desc
    const { id, postId } = ctx.params;
    const sort = ctx.query.get('sort');
    
    return { userId: id, postId, sort };
}

Catch-all Route

// routes/docs/[...slug]/serve.ts
export async function GET(ctx: Context) {
    // URL: /docs/api/v1/users
    const slug = ctx.params.slug; // ['api', 'v1', 'users']
    return { path: slug.join('/') };
}

File Upload

export async function POST(ctx: Context) {
    const form = await ctx.request.formData();
    const file = form.get('file') as File;
    await Bun.write('./uploads/' + file.name, file);
    return { filename: file.name };
}

Error Handling

export async function GET(ctx: Context) {
    try {
        throw new Error('Something went wrong');
    } catch (err) {
        return {
            data: { error: err.message },
            config: { status: 500 }
        };
    }
}

Coming Soon

  • File Upload Validation
  • Database Integration
  • WebSocket Support
  • Advanced Caching
  • GraphQL Support

πŸ”₯ Development Features

  • Hot Reload: Auto-reload routes & middleware saat ada perubahan
  • Port Management: Auto-detect & switch ke port available
  • Route Summary: Display registered routes & methods
  • Error Handling: Detailed error messages & validations

Need Help?

Jika Anda memiliki pertanyaan atau masalah:

  • Buat issue di repository GitHub kami
  • Bergabung dengan komunitas Discord kami
  • Kunjungi dokumentasi online kami
  • Hubungi tim support kami

Readme

Keywords

none

Package Sidebar

Install

npm i kontas

Weekly Downloads

6,616

Version

0.1.149

License

none

Unpacked Size

51.4 kB

Total Files

20

Last publish

Collaborators

  • hens-msn
  • okamhdt