Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
@bit-js/byte
Advanced tools
A simple, performance-focused web framework that works on Bun, Deno, Cloudflare Workers and browsers. ```ts import { Byte, send } from '@bit-js/byte';
A simple, performance-focused web framework that works on Bun, Deno, Cloudflare Workers and browsers.
import { Byte, send } from '@bit-js/byte';
export default new Byte()
.get('/', () => send.body('Hi'));
Context is an object represents the current request.
ctx.path
: The parsed request pathname, doesn't have a slash at the start.ctx.pathStart
: The start index of the pathname in the full URL string (req.url
). This property can be useful for subdomain matching.ctx.pathEnd
: The end index of the path. When query parameters are presented, path end is set to the start of the query, otherwise it is set to the length of the URL.ctx.params
: The parsed URL parameters. Defaults to undefined
with static routes.ctx.state
: This property stores validators result. Defaults to undefined
with routes that have no validators.ctx.req
: The original request object.Handlers are functions that accepts the request context as parameter and return a Response
object.
() => new Response('Hi');
(ctx) => new Response(ctx.params.id);
If your handler doesn't use the request context, in certain cases the router compiler will optimize the matcher to not pass in the request context as a parameter.
You can define routes with the syntax method(path, handler)
.
new Byte()
// Handle GET method
.get('/', () => new Response('Hi'))
// Handle PUT method
.put('/user/:id', (ctx) => new Response(ctx.params.id))
// Handle all request method
.any('/*', () => new Response('Not found'));
Parametric and wildcard patterns are supported.
'/:id' // Only one parameter
'/user/:id/name/:name' // Multiple parameter
'/nav/*' // Wildcard parameter
'/user/:id/*' // All patterns combined
Like other frameworks, Byte pass the parsed parameter values to ctx.params
, but wildcard parameter is named $
instead of *
.
Use fallback
to handle the request when the path does not match any registed route.
new Byte()
// Normal route
.get('/', () => new Response('Hi'))
// Fallback when all routes do not match
.fallback((ctx) => new Response(ctx.path));
Validators are functions that parse and validate incoming request data.
new Byte()
.get('/', {
body: async (ctx) => {
try {
// Parse body as text
return await ctx.req.text();
} catch (_) {
// Return a response directly
return new Response('Something went wrong');
}
}
}, ctx => new Response(ctx.state.body));
Parsed data is passed into ctx.state
as a property.
If a Response
object is returned from the validator, it will be used instead of the handler response.
If the validator returns a Promise
it should be properly marked as async
for the compiler to detect.
The validator name must be a valid JavaScript variable name.
Actions are functions that executes before validators.
new Byte()
.action((ctx) => {
// Preparations
})
.action((ctx) => {
// Do something else
});
If a Response
object is returned from any action function, it will be used directly.
Plugins are objects with a plug()
function that modify the app instance.
import type { Plugin } from '@bit-js/byte';
const plugin = {
plug(app) {
// Do something with the app instance
// Route types are not preserved
// You should not add route handlers
};
};
new Byte().use(plugin);
Plugins are meant to be used by third party libraries to add functionalities.
Byte provides a client implementation with type inference.
To use it, first export the type of your app.
const app = new Byte()
.get('/', () => send.body('Hi'))
.get('/user/:id', (ctx) => send.body(ctx.params.id))
.post('/text', {
body: async ctx => await ctx.req.text()
}, (ctx) => send.body(ctx.state.body))
export type App = typeof app;
Then use it in client code.
import type { App } from './app';
import { bit } from '@bit-js/byte';
const app = bit<App>('http://localhost:3000');
const msg = await app.get('/');
await msg.text(); // 'Hi'
const id = await app.get('/user/:id', {
params: { id: 90 }
});
await msg.text(); // '90'
const body = await app.post('/text', {
body: 'Hi'
});
await body.text(); // 'Hi'
You can also pass in a custom fetch
function.
const app = bit<App>('http://localhost:3000', myFetch);
Response utilities should be used for client type inference.
import { send } from '@bit-js/byte';
// new Response('Hi')
send.body('Hi');
// new Response('Hi', { headers: { 'Content-Type': 'text/plain' } })
send.text('Hi'):
// new Response(JSON.stringify({ hello: 'world' }), { headers: { 'Content-Type': 'application/json' } })
send.json({ hello: world });
// new Response(null, { headers: { Location: '/home' }, status: 302 })
send.link('/home', 302);
// SSE
send.events(readable);
All response utilities (except send.link
) has two arguments.
send(body: any, init?: ResponseInit): any;
If a ResponseInit
is passed in it will be merged with the corresponding headers.
// You should cache the header if it is static
send.body('Not found', { status: 404 });
Use body parsers to parse request body and handle errors.
import { parse } from '@bit-js/byte';
app.post('/text', {
body: parse.text({
// Do parsing with request body if specified
then(data) {
// If a `Response` object is returned.
// It will be used instead of the handler response.
},
// Handle error if specified
catch(error) {
// Should return a Response or Promise<Response>
}
})
});
Available parsers are:
parse.text
: Parse request body as text.parse.json
: Parse request body as JSON.parse.blob
: Parse request body as Blob
.parse.form
: Parse request body as FormData
.parse.buffer
: Parse request body as ArrayBuffer
.Use query parsers to get parameter values out of a query string.
import { query } from '@bit-js/byte';
// getID(ctx) -> Get a single value of parameter 'id' from query
// Return null if parameter does not exist in query string
const getID = query.value('id'); // string | null
// getCats(ctx) -> Get a multiple values of parameter 'category' from query
const getCats = query.values('category'); // string[]
// Parse query to key-value pair
const result = query.get(ctx);
The query parsers (except query.get
) utils do not decodeURIComponent
the result by default.
Set CORS headers on every requests.
import { cors } from '@bit-js/byte';
// Allow all origins
app.action(cors());
// Custom options
app.action(cors(options));
Available options are:
interface CORSOptions {
allowOrigin?: string; // Defaults to '*'
allowMethods?: string | string[];
exposeHeaders?: string | string[];
maxAge?: number;
allowCredentials?: boolean;
allowHeaders?: string | string[];
}
A CSRF protection layer by checking request origin.
import { csrf } from '@bit-js/byte';
// Check with current request URL origin
app.action(csrf());
// Custom options
app.action(csrf(options));
Available options are:
interface CSRFOptions {
origins?: string;
verify?: (origin: string) => boolean;
fallback?: (ctx: BaseContext) => any;
}
FAQs
A simple, performance-focused web framework that works on Bun, Deno, and browsers.
The npm package @bit-js/byte receives a total of 1 weekly downloads. As such, @bit-js/byte popularity was classified as not popular.
We found that @bit-js/byte demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.