Skip to content

Bejibun-Framework/bejibun-core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

159 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bejibun

GitHub top language NPM Downloads GitHub issues GitHub GitHub release (latest by date including pre-releases)

Core of Bejibun

Core of Bejibun Framework.

Usage

Installation

Install the package.

bun add @bejibun/core

Available Commands

To see list of available commands, run.

bun ace
bun ace help
bun ace --h
bun ace --help

To see help of specific command, run :

bun ace help migrate:latest
bun ace migrate:latest --h
bun ace migrate:latest --help

Database

Migrations

To fresh or drop all table and re-run the migrations, run :

bun ace migrate:fresh

Example :

This will DROP ALL tables and re-run ALL migrations. Are you want to continue? (Y/N): Y

✔ Rolled back all migrations
✔ Batch 1 finished
✔ 20250929_000001_tests.ts

To migrate the migrations, run :

bun ace migrate:latest

Example :

✔ Batch 1 finished
✔ 20250929_000001_tests.ts

To rollback the migrations, run :

bun ace migrate:rollback

Example :

This will ROLLBACK latest migrations. Are you want to continue? (Y/N): Y

✔ Batch 1 finished
✔ 20250929_000001_tests.ts

To see migrations status, run :

bun ace migrate:status

Example :

✔ Completed Migrations :
✔ No migrations were completed.

✔ Pending Migrations :
✔ 20250929_000001_tests.ts

Seeders

To execute seeder, run :

bun ace db:seed

Example :

✔ Seeding finished
✔ 20250929_000001_seeder_test.ts

Features

Controllers

Logical processes

Example :

import BaseController from "@bejibun/core/bases/BaseController";

export default class HelloController extends BaseController {
    public async hello(request: Bun.BunRequest): Promise<Response> {
        return super.response.setData({
            message: "Hello, world!",
            method: request.method
        }).send();
    }
}

Exception Handler

Handle any incoming errors

Example :

import ExceptionHandler from "@bejibun/core/exceptions/ExceptionHandler";

export default class Handler extends ExceptionHandler {
    public handle(error: any): globalThis.Response {
        // Your code goes here
        return super.handle(error);
    }
}

Middlewares

Handle any request before forwarding to controller

Example :

import type {HandlerType} from "@bejibun/core/types";
import Logger from "@bejibun/logger";

export default class TestMiddleware {
    public handle(handler: HandlerType): HandlerType {
        return async (request: Bun.BunRequest) => {
            Logger.setContext("TestMiddleware").debug(request.url);

            return handler(request);
        };
    }
}

Usage :

import Router from "@bejibun/core/facades/Router";
import YourController from "@/app/controllers/YourController";
import TestMiddleware from "@/app/middlewares/TestMiddleware";
import LoggerMiddleware from "@/app/middlewares/LoggerMiddleware";

export default Router.prefix("test")
    .middleware(
        new TestMiddleware(),
        new LoggerMiddleware()
    )
    .group([
        Router.get("redis", "TestController@redis"),
        Router.get("get", "TestController@get"),
        Router.get("detail/:id", "TestController@detail"),
        Router.post("add", "TestController@add"),
        Router.post("edit", "TestController@edit"),
        Router.delete("delete/:id", "TestController@delete"),
        Router.get("restore/:id", "TestController@restore"),

        Router.resource("path", YourController),
        Router.resource("path", YourController, {
            only: ["index", "store"] // "index" | "store" | "show" | "update" | "destroy"
        }),
        Router.resource("path", YourController, {
            except: ["index", "store"] // "index" | "store" | "show" | "update" | "destroy"
        })
    ]);

Validators

Validate any incoming requests

Example :

import type {ValidatorType} from "@bejibun/core/types/ValidatorType";
import BaseValidator from "@bejibun/core/bases/BaseValidator";
import TestModel from "@/app/models/TestModel";

export default class TestValidator extends BaseValidator {
    public static get detail(): ValidatorType {
        return super.validator.create({
            id: super.validator.number().min(1).exists(TestModel, "id")
        });
    }

    public static get add(): ValidatorType {
        return super.validator.create({
            name: super.validator.string()
        });
    }

    public static get edit(): ValidatorType {
        return super.validator.create({
            id: super.validator.number().min(1).exists(TestModel, "id"),
            name: super.validator.string()
        });
    }

    public static get delete(): ValidatorType {
        return super.validator.create({
            id: super.validator.number().min(1).exists(TestModel, "id")
        });
    }

    public static get restore(): ValidatorType {
        return super.validator.create({
            id: super.validator.number().min(1).exists(TestModel, "id", true)
        });
    }
}

Usage :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";

export default class TestController extends BaseController {
    public async detail(request: Bun.BunRequest): Promise<Response> {
        const body = await super.parse(request);
        await super.validate(TestValidator.detail, body);

        const test = await TestModel.findOrFail(body.id as number | string);

        return super.response.setData(test).send();
    }
}

Models

Database table model

Example :

import type {Timestamp, NullableTimestamp} from "@bejibun/core/bases/BaseModel";
import BaseModel from "@bejibun/core/bases/BaseModel";

export default class TestModel extends BaseModel {
    public static tableName: string = "tests";
    public static idColumn: string = "id";

    declare id: bigint;
    declare name: string;
    declare created_at: Timestamp;
    declare updated_at: Timestamp;
    declare deleted_at: NullableTimestamp;
}

Fetch All

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";

export default class TestController extends BaseController {
    public async get(request: Bun.BunRequest): Promise<Response> {
        const tests = await TestModel.all();

        return super.response.setData(tests).send();
    }
}

Find or Fail

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";

export default class TestController extends BaseController {
    public async detail(request: Bun.BunRequest): Promise<Response> {
        const body = await super.parse(request);
        await super.validate(TestValidator.detail, body);

        const test = await TestModel.findOrFail(body.id as number | string);

        return super.response.setData(test).send();
    }
}

Create

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";

export default class TestController extends BaseController {
    public async add(request: Bun.BunRequest): Promise<Response> {
        const body = await super.parse(request);
        await super.validate(TestValidator.add, body);

        const tests = await TestModel.create({
            name: body.name as string
        });

        return super.response.setData(tests).send();
    }
}

Update

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";

export default class TestController extends BaseController {
    public async edit(request: Bun.BunRequest): Promise<Response> {
        const body = await super.parse(request);
        await super.validate(TestValidator.edit, body);

        const tests = await TestModel.find(body.id as number | string)
            .update({
                name: body.name as string
            });

        return super.response.setData(tests).send();
    }
}

Soft Delete

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";

export default class TestController extends BaseController {
    public async delete(request: Bun.BunRequest): Promise<Response> {
        const body = await super.parse(request);
        await super.validate(TestValidator.delete, body);

        const tests = await TestModel.find(body.id as number | string).delete();

        return super.response.setData(tests).send();
    }
}

Force Delete

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";
import TestValidator from "@/app/validators/TestValidator";

export default class TestController extends BaseController {
    public async delete(request: Bun.BunRequest): Promise<Response> {
        const body = await super.parse(request);
        await super.validate(TestValidator.delete, body);

        const tests = await TestModel.find(body.id as number | string).forceDelete();

        return super.response.setData(tests).send();
    }
}

With Trashed

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";

export default class TestController extends BaseController {
    public async get(request: Bun.BunRequest): Promise<Response> {
        const tests = await TestModel.withTrashed();

        return super.response.setData(tests).send();
    }
}

Only Trashed

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";

export default class TestController extends BaseController {
    public async get(request: Bun.BunRequest): Promise<Response> {
        const tests = await TestModel.onlyTrashed();

        return super.response.setData(tests).send();
    }
}

Restore

Example :

import BaseController from "@bejibun/core/bases/BaseController";
import TestModel from "@/app/models/TestModel";

export default class TestController extends BaseController {
    public async restore(request: Bun.BunRequest): Promise<Response> {
        const body = await super.parse(request);
        await super.validate(TestValidator.restore, body);

        const tests = await TestModel.find(body.id as number | string).restore();

        return super.response.setData(tests).send();
    }
}

Database

Migrations

Example :

import type {Knex} from "knex";
import TestModel from "@/app/models/TestModel";

export function up(knex: Knex): void {
    return knex.schema.createTable(TestModel.table, (table: Knex.TableBuilder) => {
        table.bigIncrements("id");
        table.string("name");
        table.timestamps(true, true);
        table.timestamp("deleted_at");
    });
}

export function down(knex: Knex): void {
    return knex.schema.dropTable(TestModel.table);
}

Seeders

Example :

import type {Knex} from "knex";
import TestModel from "@/app/models/TestModel";

export async function seed(knex: Knex): Promise<void> {
    for (const name of ["Name 1", "Name 2", "Name 3"]) {
        await TestModel.query(knex).insert({
            name: name
        });
    }
}

Bootstrap

Any startup loads

import Database from "@bejibun/database";
import {Model} from "objection";
import BaseModel from "@/bases/BaseModel";

(BaseModel as any as typeof Model).knex(Database.knex());

Storage

A filesystem facade, with built-in disk management including disks configuration and build disk at runtime.

  • Standard Use
import Storage from "@bejibun/core/facades/Storage";

await Storage.exists("path/to/your/file.ext"); // Check if the file exists
await Storage.missing("path/to/your/file.ext"); // Check if the file doesn't exists
await Storage.get("path/to/your/file.ext"); // Get data content
await Storage.put("path/to/your/file.ext", "content"); // Store content to file
await Storage.delete("path/to/your/file.ext"); // Delete file
  • With Specified Disk
import Storage from "@bejibun/core/facades/Storage";

await Storage.disk("public").exists("path/to/your/file.ext");
await Storage.disk("public").missing("path/to/your/file.ext");
await Storage.disk("public").get("path/to/your/file.ext");
await Storage.disk("public").put("path/to/your/file.ext", "content");
await Storage.disk("public").delete("path/to/your/file.ext");
  • New Disk at Runtime
import Storage from "@bejibun/core/facades/Storage";

await Storage.build({
    driver: "local", // "local" | DiskDriverEnum.Local
    root: App.Path.storagePath("custom")
}).exists("path/to/your/file.ext");
await Storage.build({
    driver: "local",
    root: App.Path.storagePath("custom")
}).missing("path/to/your/file.ext");
await Storage.build({
    driver: "local",
    root: App.Path.storagePath("custom")
}).get("path/to/your/file.ext");
await Storage.build({
    driver: "local",
    root: App.Path.storagePath("custom")
}).put("path/to/your/file.ext", "content");
await Storage.build({
    driver: "local",
    root: App.Path.storagePath("custom")
}).delete("path/to/your/file.ext");

Queue

Run processes at background.

// Immediately
await TestJob.dispatch(/*any params here*/).send();

// With delay
await TestJob.dispatch(/*any params here*/).delay(60 * 10 /*10 minutes*/).send();

Decorator

All available decorators.

@ApiDoc

@ApiDoc({
    description: "Hello with Name",
    request: {
        params: [
            {
                name: "name",
                in: "path",
                required: true,
                schema: {
                    type: "string"
                }
            }
        ]
    }
})
public async helloName(request: Bun.BunRequest): Promise<Response> {
    const body = await super.parse(request);
    await super.validate(HelloValidator.helloName, body);

    return super.response.setData({
        message: `Hello, ${body.name}!`,
    }).send();
}

Scheduler

Run code in period.

// commands/Kernel.ts
import type Schedule from "@bejibun/core/facades/Schedule";

export default class Kernel {
    public schedule(schedule: Schedule): void {
        // Your code goes here
        schedule.command("hello:world").everyMinute();
    }
}

WebSocket

Setup websocket like router.

import Router from "@bejibun/core/facades/Router";

export default Router.prefix("chat").group([
    Router.websocket("/", "ChatWebSocket@handle")
]);
import BaseWebSocket from "@bejibun/core/bases/BaseWebSocket";

export default class HelloWebSocket extends BaseWebSocket {
    public async handle(ws: Bun.ServerWebSocket<any>, message: string | Buffer<ArrayBuffer>): Promise<void> {
        for (const connection of super.connections) {
            if (connection.data.id !== ws.data.id) {
                if (connection.readyState === 1) {
                    connection.send(message);
                }
            }
        }
    }
}

Global Functions

Config

config("disk.default");

Env

env("APP_KEY");

Redis

Documentation : @bejibun/redis

Cors

Documentation : @bejibun/cors

Cache

Documentation : @bejibun/cache

Ace

Any commands for development

Usage: ace [options] [command]

Ace for your commander
Author: Havea Crenata <havea.crenata@gmail.com>

Options:
  -v, --version                Show the current version
  -h, --help                   display help for command

Commands:
  db:seed                      Run database seeders
  hello:world                  Run hello world
  install <packages...>        Install package dependencies
  maintenance:down [options]   Turn app into maintenance mode
  maintenance:up               Turn app into live mode
  make:command <file>          Create a new command file
  make:controller <file>       Create a new controller file
  make:job <file>              Create a new job file
  make:middleware <file>       Create a new middleware file
  make:migration <file>        Create a new migration file
  make:model <file>            Create a new model file
  make:seeder <file>           Create a new seeder file
  make:validator <file>        Create a new validator file
  migrate:fresh [options]      Rollback all migrations and re-run migrations
  migrate:latest               Run latest migration
  migrate:rollback [options]   Rollback the latest migrations
  migrate:status [options]     List migrations status
  package:configure [options]  Configure package after installation
  queue:flush                  Flush all of the failed queue jobs
  queue:retry                  Retry a failed queue job
  queue:work                   Start processing jobs on the queue as a daemon
  help [command]               display help for command

Examples:
  $ bun ace --help
  $ bun ace --version
  $ bun ace migrate:latest

Contributors

☕ Support / Donate

If you find this project helpful and want to support it, you can donate via crypto :

EVM Solana
0xdABe8750061410D35cE52EB2a418c8cB004788B3 GAnoyvy9p3QFyxikWDh9hA3fmSk2uiPLNWyQ579cckMn

Or you can buy this $BJBN (Bejibun) tokens here, beware of bots.

About

Core of Bejibun Framework

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors