enh(general) BaseRouter docs; unified Storage; implement Cookies
This commit is contained in:
@@ -1,49 +1,112 @@
|
|||||||
import Logger from '../Utils/Logger';
|
import Logger from '../Utils/Logger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class BaseRouter
|
||||||
|
* @description Base class for creating routers
|
||||||
|
*/
|
||||||
export default class BaseRouter {
|
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 = {}) {
|
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) {
|
any(path, cb) {
|
||||||
this.all(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) {
|
all(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'all' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'all' });
|
||||||
return this;
|
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) {
|
get(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'get' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'get' });
|
||||||
return this;
|
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) {
|
post(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'post' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'post' });
|
||||||
return this;
|
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) {
|
put(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'put' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'put' });
|
||||||
return this;
|
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) {
|
patch(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'patch' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'patch' });
|
||||||
return this;
|
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) {
|
delete(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'delete' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'delete' });
|
||||||
return this;
|
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) {
|
head(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'head' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'head' });
|
||||||
return this;
|
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) {
|
options(path, cb) {
|
||||||
this.add(path, cb, { ...(arguments[2] || {}), method: 'options' });
|
this.add(path, cb, { ...(arguments[2] || {}), method: 'options' });
|
||||||
return this;
|
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