Common changes for simplicity

Changed fastify handler to handle the actual registration of the rout file with the routeinfo. changed all ' to " instead moves types and interfaces to the respective folders and files
This commit is contained in:
creations 2024-08-09 07:10:21 -04:00
parent 7d77e73030
commit 1ccf80474c
11 changed files with 88 additions and 54 deletions

2
.gitignore vendored
View file

@ -90,7 +90,7 @@ web_modules/
.node_repl_history
# Output of 'npm pack'
# Output of "npm pack"
*.tgz

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 Creation's // [creations@creations.works]
Copyright (c) 2024 Creation"s // [creations@creations.works]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,6 +1,6 @@
# TS Fastify Example
This is just an example/template to get you started with Fastify and TypeScript. It starts off using EJS, but you can use something else if you'd like.
This is just an example/template to get you started with Fastify and TypeScript. It starts off using EJS, but you can use something else if you"d like.
## Getting Started

BIN
bun.lockb Normal file

Binary file not shown.

View file

@ -1,23 +1,7 @@
import { dirname, join } from "path";
import { fileURLToPath } from "url";
export interface IEnvironment {
development: boolean;
fastify: {
host: string;
port: number;
};
paths: {
src: string;
www: {
root: string;
views: string;
public: string;
}
};
}
import type{ IEnvironment } from "../interfaces/environment";
const __dirname : string = join(dirname(fileURLToPath(import.meta.url)), "..");

17
interfaces/environment.ts Normal file
View file

@ -0,0 +1,17 @@
export interface IEnvironment {
development: boolean;
fastify: {
host: string;
port: number;
};
paths: {
src: string;
www: {
root: string;
views: string;
public: string;
}
};
}

7
interfaces/routes.ts Normal file
View file

@ -0,0 +1,7 @@
import type { TMethod } from "../types/routes";
export interface IRouteInfo {
enabled: boolean;
path: string;
method: TMethod | TMethod[];
}

View file

@ -8,7 +8,7 @@ import { join } from "path";
import { environment } from "../../config/environment";
// types
import type { FastifyInstance, FastifyReply, FastifyRequest, RouteShorthandMethod } from "fastify";
import type { FastifyInstance } from "fastify";
import type { Stats } from "fs";
import type { AddressInfo } from "net";
@ -31,8 +31,6 @@ class FastifyManager {
});
}
private async registerPlugins() : Promise<void> {
console.log(environment.paths.www.views);
// official plugins
this.server.register(fastifyView, {
engine: {
@ -55,9 +53,8 @@ class FastifyManager {
// dynamic route loading
private async loadRoutes(): Promise<void> {
// you can specify a route path, prefix, and whether to load routes recursively e.g. ["routes", "/", true] will load all routes in the /routes directory with the prefix / and recursively load all routes in subdirectories
const routePaths: [string, string, boolean][] = [
["routes", '/', false]
["routes", "/", false]
];
for (const [routePath, prefix, recursive] of routePaths) {
@ -73,12 +70,39 @@ class FastifyManager {
for (const file of files) {
try {
const route = await import(file);
if (route.default) {
this.server.register(route.default, { prefix });
const routeModule = await import(file);
const { default: routeData } = routeModule;
if ( !routeData || !routeData.routeInfo || !routeData.route ) {
console.error(`Failed to load route from ${file}:`, "Route data is missing");
continue;
}
if (routeData.routeInfo.enabled && routeData.route) {
const { routeInfo, route } = routeData;
let routePath = routeInfo.path || "/";
// Handle prefix and leading/trailing slashes
if (prefix) {
routePath = routePath === "/" ? prefix : join(prefix, routePath);
}
// Normalize the path to avoid duplicate slashes
routePath = routePath.replace(/\/+/g, "/");
const methods = Array.isArray(routeInfo.method) ? routeInfo.method : [routeInfo.method];
for (const method of methods) {
this.server.route({
method,
url: routePath,
handler: route
});
}
}
} catch (err) {
console.error("Failed to load route", file, "error:", err);
console.error(`Failed to load route from ${file}:`, err);
}
}
}
@ -115,7 +139,7 @@ class FastifyManager {
const [_address, _port, scheme]: [string, number, string] = (() : [string, number, string] => {
const address: string | AddressInfo | null = this.server.server.address();
const resolvedAddress: [string, number] = (address && typeof address === 'object') ? [( address.address.startsWith("::") || address.address === "0.0.0.0") ? "localhost" : address.address, address.port] : ["localhost", this.port];
const resolvedAddress: [string, number] = (address && typeof address === "object") ? [( address.address.startsWith("::") || address.address === "0.0.0.0") ? "localhost" : address.address, address.port] : ["localhost", this.port];
const resolvedScheme: string = resolvedAddress[0] === "localhost" ? "http" : "https";
return [...resolvedAddress, resolvedScheme];

View file

@ -1,6 +1,6 @@
import { readFile } from 'fs/promises';
import { readFile } from "fs/promises";
import type { FastifyInstance, FastifyPluginAsync } from 'fastify';
import type { FastifyInstance, FastifyPluginAsync } from "fastify";
import type { FastifyRequest } from "fastify/types/request";
import type { FastifyReply } from "fastify/types/reply";
@ -17,16 +17,16 @@ const faviconPlugin: FastifyPluginAsync<FaviconOptions> = async (fastify: Fastif
console.error("Error reading favicon:", err);
}
fastify.get('/favicon.ico', async (_request: FastifyRequest, reply: FastifyReply): Promise<void> => {
fastify.get("/favicon.ico", async (_request: FastifyRequest, reply: FastifyReply): Promise<void> => {
if (faviconData) {
reply.header('Content-Type', 'image/x-icon')
.header('Cache-Control', 'public, max-age=86400') // 1 day
reply.header("Content-Type", "image/x-icon")
.header("Cache-Control", "public, max-age=86400") // 1 day
.send(faviconData);
} else {
reply.status(404).send({
code: 404,
error: 'FILE_NOT_FOUND',
message: 'Favicon not found'
error: "FILE_NOT_FOUND",
message: "Favicon not found"
});
}
});

View file

@ -1,17 +1,18 @@
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import type { FastifyReply, FastifyRequest } from "fastify";
import type { IRouteInfo } from "../../../interfaces/routes";
const route : (fastify: FastifyInstance) => Promise<void> = async (fastify: FastifyInstance) : Promise<void> => {
const handleRequest: (request : FastifyRequest, reply : FastifyReply) => Promise<void> = async (request : FastifyRequest, reply : FastifyReply) : Promise<void> => {
const routeInfo: IRouteInfo = {
enabled: true,
path: "/",
method: "GET"
};
return reply.view("index.ejs", {
h1: "Hello, World!",
p: "This is a placeholder page.",
discord: "https://discord.gg/DxFhhbr2pm",
});
}
fastify.get("/", handleRequest);
async function route(request : FastifyRequest, reply : FastifyReply) : Promise<string> {
return reply.viewAsync("index", {
h1: "Hello, World!",
p: "This is a placeholder page.",
discord: "https://discord.gg/DxFhhbr2pm",
});
}
export default route as (fastify: FastifyInstance) => Promise<void>;
export default { routeInfo, route }

1
types/routes.ts Normal file
View file

@ -0,0 +1 @@
export type TMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";