Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Wobe): add description for type on Wobe #15

Merged
merged 1 commit into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/wobe/src/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,19 @@ export class Context {
this.afterHandlerHook = route?.afterHandlerHook || []
}

/**
* Redirect to a specific URL
* @param url The URL to redirect
* @param status The status of the redirection
*/
redirect(url: string, status = 302) {
this.res.headers.set('Location', url)
this.res.status = status
}

/**
* Execute the handler of the route
*/
async executeHandler() {
this.state = 'beforeHandler'
// We need to run hook sequentially
Expand Down
4 changes: 4 additions & 0 deletions packages/wobe/src/HttpException.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Custom exception for HTTP errors
* Example usage: throw new HttpException(new Response('Not found', { status: 404 }))
*/
export class HttpException extends Error {
response: Response

Expand Down
87 changes: 86 additions & 1 deletion packages/wobe/src/Wobe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,25 @@ export type WobeHandler = (ctx: Context) => WobeHandlerOutput

export type WobePlugin = (wobe: Wobe) => void

/**
* Hook is the state of the request, it can be before the handler, after the handler or both
*/
export type Hook = 'beforeHandler' | 'afterHandler' | 'beforeAndAfterHandler'

/**
* WobeWebSocket is the configuration for the WebSocket server
* @param path The path of the WebSocket server
* @param compression Enable or disable the compression of the WebSocket server
* @param maxPayloadLength The maximum length of the payload
* @param idleTimeout The time before the WebSocket server is closed
* @param backpressureLimit The limit of the backpressure
* @param closeOnBackpressureLimit Close the WebSocket server if the backpressure limit is reached
* @param beforeWebSocketUpgrade Array of handlers before the WebSocket server is upgraded
* @param onOpen Handler when the WebSocket server is opened
* @param onMessage Handler when the WebSocket server receives a message
* @param onClose Handler when the WebSocket server is closed
* @param onDrain Handler when the WebSocket server is drained
*/
export interface WobeWebSocket {
path: string
compression?: boolean
Expand All @@ -62,7 +79,9 @@ const factoryOfRuntime = (): RuntimeAdapter => {
return NodeAdapter()
}

// TODO : Create assert before hook if it's specific to a type of hook (before, after, beforeAndAfter)
/**
* Wobe is the main class of the framework
*/
export class Wobe {
private options?: WobeOptions
private server: Server | null
Expand All @@ -83,13 +102,23 @@ export class Wobe {

private webSocket: WobeWebSocket | undefined = undefined

/**
* Constructor of the Wobe class
* @param options The options of the Wobe class
*/
constructor(options?: WobeOptions) {
this.options = options
this.hooks = []
this.server = null
this.router = new RadixTree()
}

/**
* get is the method to handle the GET requests
* @param path The path of the request
* @param handler The handler of the request
* @param hook The hook of the request (optional)
*/
get(path: string, handler: WobeHandler, hook?: WobeHandler) {
if (hook) this._addHook('beforeHandler', 'GET')(path, hook)

Expand All @@ -98,6 +127,12 @@ export class Wobe {
return this
}

/**
* post is the method to handle the POST requests
* @param path The path of the request
* @param handler The handler of the request
* @param hook The hook of the request (optional)
*/
post(path: string, handler: WobeHandler, hook?: WobeHandler) {
if (hook) this._addHook('beforeHandler', 'POST')(path, hook)

Expand All @@ -106,6 +141,12 @@ export class Wobe {
return this
}

/**
* put is the method to handle the PUT requests
* @param path The path of the request
* @param handler The handler of the request
* @param hook The hook of the request (optional)
*/
put(path: string, handler: WobeHandler, hook?: WobeHandler) {
if (hook) this._addHook('beforeHandler', 'PUT')(path, hook)

Expand All @@ -114,6 +155,12 @@ export class Wobe {
return this
}

/**
* delete is the method to handle the DELETE requests
* @param path The path of the request
* @param handler The handler of the request
* @param hook The hook of the request (optional)
*/
delete(path: string, handler: WobeHandler, hook?: WobeHandler) {
if (hook) this._addHook('beforeHandler', 'DELETE')(path, hook)

Expand All @@ -122,6 +169,12 @@ export class Wobe {
return this
}

/**
* all is the method to handle all the requests
* @param path The path of the request
* @param handler The handler of the request
* @param hook The hook of the request (optional)
*/
all(path: string, handler: WobeHandler, hook?: WobeHandler) {
if (hook) {
this.httpMethods.map((method) =>
Expand Down Expand Up @@ -157,6 +210,11 @@ export class Wobe {
return this
}

/**
* beforeAndAfterHandler is the method to handle the before and after handlers
* @param arg1 The path of the request or the handler
* @param handlers The handlers of the request
*/
beforeAndAfterHandler(
arg1: string | WobeHandler,
...handlers: WobeHandler[]
Expand All @@ -168,6 +226,11 @@ export class Wobe {
return this
}

/**
* beforeHandler is the method to handle the before handlers
* @param arg1 The path of the request or the handler
* @param handlers The handlers of the request
*/
beforeHandler(arg1: string | WobeHandler, ...handlers: WobeHandler[]) {
this.httpMethods.map((method) =>
this._addHook('beforeHandler', method)(arg1, ...handlers),
Expand All @@ -176,6 +239,11 @@ export class Wobe {
return this
}

/**
* afterHandler is the method to handle the after handlers
* @param arg1 The path of the request or the handler
* @param handlers The handlers of the request
*/
afterHandler(arg1: string | WobeHandler, ...handlers: WobeHandler[]) {
this.httpMethods.map((method) =>
this._addHook('afterHandler', method)(arg1, ...handlers),
Expand All @@ -184,12 +252,21 @@ export class Wobe {
return this
}

/**
* useWebSocket is the method to handle the WebSocket
* @param webSocketHandler The WebSocket handler
*/
useWebSocket(webSocketHandler: WobeWebSocket) {
this.webSocket = webSocketHandler

return this
}

/**
* usePlugin is the method to use a plugin
* @param plugin The plugin to use
* You can find more informations about plugins in the documentation (https://www.wobe.dev/doc/ecosystem/plugins)
*/
usePlugin(plugin: MaybePromise<WobePlugin>) {
if (plugin instanceof Promise) {
plugin.then((p) => {
Expand All @@ -204,6 +281,11 @@ export class Wobe {
return this
}

/**
* listen is the method to start the server
* @param port The port of the server
* @param callback The callback to execute after the server is started
*/
listen(
port: number,
callback?: (options: { hostname: string; port: number }) => void,
Expand Down Expand Up @@ -233,6 +315,9 @@ export class Wobe {
return this
}

/**
* stop is the method to stop the server
*/
stop() {
this.runtimeAdapter.stopServer(this.server)
}
Expand Down
30 changes: 30 additions & 0 deletions packages/wobe/src/WobeResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export class WobeResponse {
this.request = request
}

/**
* Set a cookie
* @param name The name of the cookie
* @param value The value of the cookie
* @param options The options of the cookie
*/
setCookie(name: string, value: string, options?: SetCookieOptions) {
let cookie = `${name}=${value};`

Expand All @@ -45,6 +51,10 @@ export class WobeResponse {
this.headers?.append('Set-Cookie', cookie)
}

/**
* Get a cookie
* @param cookieName The name of the cookie
*/
getCookie(cookieName: string) {
const cookies = this.request.headers.get('Cookie')

Expand All @@ -57,10 +67,19 @@ export class WobeResponse {
return cookie.split('=')[1]
}

/**
* Delete a cookie
* @param name The name of the cookie
*/
deleteCookie(name: string) {
this.setCookie(name, '', { expires: new Date(0) })
}

/**
* Send a JSON response
* @param content The json content of the response
* @returns The response
*/
sendJson(content: Record<string, any>) {
this.headers.set('content-type', 'application/json')
this.headers.set('charset', 'utf-8')
Expand All @@ -74,6 +93,11 @@ export class WobeResponse {
return this.response
}

/**
* Send a text response
* @param content The text content of the response
* @returns The response
*/
sendText(content: string) {
this.headers.set('content-type', 'text/plain')
this.headers.set('charset', 'utf-8')
Expand All @@ -87,6 +111,12 @@ export class WobeResponse {
return this.response
}

/**
* Send a response (text or json)
* @param content The content of the response
* @param object The object contains the status, statusText and headers of the response
* @returns The response
*/
send(
content: string | Record<string, any>,
{
Expand Down
3 changes: 3 additions & 0 deletions packages/wobe/src/hooks/bearerAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const prefix = 'Bearer'
const defaultHash = (token: string) =>
createHash('sha256').update(token).digest('base64')

/**
* bearerAuth is a hook that checks if the request has a valid Bearer token
*/
export const bearerAuth = ({
token,
hashFunction = defaultHash,
Expand Down
3 changes: 3 additions & 0 deletions packages/wobe/src/hooks/bodyLimit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ interface BodyLimitOptions {
maxSize: number
}

/**
* bodyLimit is a hook that checks if the request body is too large
*/
export const bodyLimit = (options: BodyLimitOptions): WobeHandler => {
return (ctx) => {
// The content-length header is not always present
Expand Down
3 changes: 3 additions & 0 deletions packages/wobe/src/hooks/cors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export interface CorsOptions {
exposeHeaders?: string[]
}

/**
* cors is a hook that adds the necessary headers to enable CORS
*/
export const cors = (options?: CorsOptions): WobeHandler => {
const defaults: CorsOptions = {
origin: '*',
Expand Down
4 changes: 4 additions & 0 deletions packages/wobe/src/hooks/csrf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const isSameOrigin = (optsOrigin: Origin, requestOrigin: string) => {
// Reliability on these headers comes from the fact that they cannot be altered programmatically
// as they fall under forbidden headers list, meaning that only the browser can set them.
// https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#using-standard-headers-to-verify-origin

/**
* csrf is a hook that checks if the request has a valid CSRF token
*/
export const csrf = (options: CsrfOptions): WobeHandler => {
return (ctx) => {
const requestOrigin = ctx.request.headers.get('origin') || ''
Expand Down
3 changes: 3 additions & 0 deletions packages/wobe/src/hooks/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const defaultLoggerFunction = ({
)
}

/**
* logger is a hook that logs the request method, url, and status code
*/
export const logger = (
{ loggerFunction }: LoggerOptions = {
loggerFunction: defaultLoggerFunction,
Expand Down
3 changes: 3 additions & 0 deletions packages/wobe/src/hooks/rateLimit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export interface RateLimitOptions {
numberOfRequests: number
}

/**
* rateLimit is a hook that limits the number of requests per interval
*/
export const rateLimit = ({
interval,
numberOfRequests,
Expand Down
3 changes: 3 additions & 0 deletions packages/wobe/src/hooks/secureHeaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export interface SecureHeadersOptions {
xDownloadOptions?: string
}

/**
* secureHeaders is a hook that sets secure headers (equivalent of helmet on express)
*/
export const secureHeaders = ({
contentSecurityPolicy,
crossOriginEmbedderPolicy,
Expand Down
3 changes: 3 additions & 0 deletions packages/wobe/src/tools/WobeStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ export interface WobeStoreOptions {
interval: number
}

/**
* WobeStore is a class that stores data for a certain amount of time
*/
export class WobeStore<T> {
private options: WobeStoreOptions
private store: Record<string, any>
Expand Down