enh(general) BaseRouter docs; unified Storage; implement Cookies
This commit is contained in:
@@ -1,49 +1,112 @@
|
||||
import Logger from '../Utils/Logger';
|
||||
|
||||
/**
|
||||
* @class BaseRouter
|
||||
* @description Base class for creating routers
|
||||
*/
|
||||
export default class BaseRouter {
|
||||
/**
|
||||
* Add a route with the specified path, callback, and options.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @param {object} [options={}] - Additional options for the route.
|
||||
*/
|
||||
add(path, cb, options = {}) {
|
||||
Logger.error('add method not implemented');
|
||||
throw new Error('add method not implemented!')
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches any HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
*/
|
||||
any(path, cb) {
|
||||
this.all(path, cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches all HTTP methods.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
all(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'all' });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches the GET HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
get(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'get' });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches the POST HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
post(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'post' });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches the PUT HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
put(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'put' });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches the PATCH HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
patch(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'patch' });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches the DELETE HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
delete(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'delete' });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches the HEAD HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
head(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'head' });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route that matches the OPTIONS HTTP method.
|
||||
* @param {string} path - The route path.
|
||||
* @param {function} cb - The callback function to handle the route.
|
||||
* @returns {BaseRouter} The current instance of BaseRouter for chaining.
|
||||
*/
|
||||
options(path, cb) {
|
||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'options' });
|
||||
return this;
|
||||
|
||||
74
src/Utils/Cookie.js
Normal file
74
src/Utils/Cookie.js
Normal file
@@ -0,0 +1,74 @@
|
||||
export default class Cookie {
|
||||
/**
|
||||
* Reads cookies from a Request object and returns a Map of cookie values.
|
||||
* @param {Request} request - The Request object to read cookies from.
|
||||
* @returns {Map} - A Map containing the cookie values.
|
||||
*/
|
||||
static read(request, settings = {}) {
|
||||
const cookie = new Map();
|
||||
if (request.headers.has('Cookie')) {
|
||||
const cookiePairs = request.headers.get('Cookie').toString().split('; ');
|
||||
|
||||
for (const pair of cookiePairs) {
|
||||
const [name, value] = pair.split('=');
|
||||
cookie.set(name, decodeURIComponent(value));
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(settings).forEach(k => cookie.set(k, settings[k]));
|
||||
|
||||
return cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a Map of cookie values to a Response object's headers.
|
||||
* @param {Response} response - The Response object to write cookies to.
|
||||
* @param {object} cookies - An object containing cookie values.
|
||||
* @param {object} [settings={}] - Additional cookie settings (e.g., expires, path, domain).
|
||||
*/
|
||||
static write(response, data, settings = {}) {
|
||||
const cookiePairs = [];
|
||||
|
||||
for (const [name, value] of [...data]) {
|
||||
const encodedValue = encodeURIComponent(value);
|
||||
cookiePairs.push(`${name}=${encodedValue}`);
|
||||
}
|
||||
|
||||
const cookieString = cookiePairs.join('; ');
|
||||
|
||||
let cookie = `${cookieString}`;
|
||||
// Append additional cookie settings if present
|
||||
for (const [settingName, settingValue] of Object.entries(settings)) {
|
||||
cookie += `; ${settingName}`;
|
||||
if (settingValue !== true) {
|
||||
cookie += `=${settingValue}`;
|
||||
}
|
||||
}
|
||||
|
||||
response.headers.set('Set-Cookie', cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a cookie value with the specified name and optional settings.
|
||||
* @param {Response} response - The Response object to set the cookie on.
|
||||
* @param {string} name - The name of the cookie.
|
||||
* @param {string} value - The value of the cookie.
|
||||
* @param {object} [settings={}] - Additional cookie settings (e.g., expires, path, domain).
|
||||
*/
|
||||
static set(response, name, value, settings = {}) {
|
||||
const cookies = CookieHandler.read(response.request);
|
||||
cookies[name] = value;
|
||||
CookieHandler.write(response, cookies, settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cookie with the specified name by setting its expiration to a past date.
|
||||
* @param {Response} response - The Response object to delete the cookie from.
|
||||
* @param {string} name - The name of the cookie to delete.
|
||||
*/
|
||||
static delete(response, name) {
|
||||
const cookies = CookieHandler.read(response.request);
|
||||
delete cookies[name];
|
||||
CookieHandler.write(response, cookies, { expires: new Date(0) });
|
||||
}
|
||||
}
|
||||
74
src/Utils/Storage.js
Normal file
74
src/Utils/Storage.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import { resolve } from 'path';
|
||||
import { mkdir, exists, readdir } from 'fs/promises';
|
||||
|
||||
/**
|
||||
* Storage class for handling file operations.
|
||||
*/
|
||||
export default class Storage {
|
||||
#options = new Map([
|
||||
['baseDir', undefined],
|
||||
]);
|
||||
|
||||
/**
|
||||
* Constructor for the Storage class.
|
||||
* @param {Object|Map} options - Configuration options for the Storage instance.
|
||||
*/
|
||||
constructor(options) {
|
||||
if(typeof options == 'object' && options.constructor?.name == 'Object') {
|
||||
options = new Map(Object.entries(options));
|
||||
}
|
||||
|
||||
for(const k of this.#options.keys()) {
|
||||
if(!options.has(k)) continue;
|
||||
this.#options.set(k, options.get(k));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a directory exists at the specified path.
|
||||
* @param {string} path - The path of the directory to ensure.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async ensureDir(path) {
|
||||
if(!path || typeof(path) != 'string') return;
|
||||
path = this.resolve(path);
|
||||
if(!(await exists(path))) {
|
||||
await mkdir(path, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a relative path to an absolute path based on the configured base directory.
|
||||
* @param {string} path - The relative path to resolve.
|
||||
* @returns {string} The resolved absolute path.
|
||||
*/
|
||||
resolve(path) {
|
||||
return resolve(this.#options.get('baseDir'), path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data to a file at the specified path.
|
||||
* @param {string} path - The path of the file to write.
|
||||
* @param {string|Buffer} data - The data to write to the file.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async write(path, data) {
|
||||
path = this.resolve(path);
|
||||
const file = Bun.file(path);
|
||||
return await Bun.write(file, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of a file at the specified path.
|
||||
* @param {string} path - The path of the file to read.
|
||||
* @returns {Promise<string>} The contents of the file as a string.
|
||||
* @throws {Error} If the file does not exist.
|
||||
*/
|
||||
async read(path) {
|
||||
path = this.resolve(path);
|
||||
const file = Bun.file(path);
|
||||
if(!(await file.exists())) throw new Error('file does not exist');
|
||||
|
||||
return await file.text();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user