@wxn0brp/falcon-frame 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ import { Logger, LoggerOptions } from "@wxn0brp/lucerna-log";
2
2
  import http from "http";
3
3
  import { FFResponse } from "./res.js";
4
4
  import { FFRequest, Method, Middleware, RouteHandler } from "./types.js";
5
+ import { renderHTML } from "./render.js";
6
+ import { PluginSystem } from "./plugins.js";
5
7
  export declare class FalconFrame {
6
8
  middlewares: Middleware[];
7
9
  logger: Logger;
@@ -18,4 +20,4 @@ export declare class FalconFrame {
18
20
  getApp(): (req: any, res: any) => void;
19
21
  }
20
22
  export default FalconFrame;
21
- export { FFResponse, FFRequest, RouteHandler, };
23
+ export { FFResponse, FFRequest, RouteHandler, renderHTML, PluginSystem, };
package/dist/index.js CHANGED
@@ -4,6 +4,8 @@ import { handleStaticFiles } from "./helpers.js";
4
4
  import { handleRequest } from "./req.js";
5
5
  import { FFResponse } from "./res.js";
6
6
  import { FFRequest } from "./types.js";
7
+ import { renderHTML } from "./render.js";
8
+ import { PluginSystem } from "./plugins.js";
7
9
  export class FalconFrame {
8
10
  middlewares = [];
9
11
  logger;
@@ -66,4 +68,4 @@ export class FalconFrame {
66
68
  }
67
69
  }
68
70
  export default FalconFrame;
69
- export { FFResponse, FFRequest, };
71
+ export { FFResponse, FFRequest, renderHTML, PluginSystem, };
@@ -0,0 +1,43 @@
1
+ import { RouteHandler } from "./types.js";
2
+ type PluginId = string;
3
+ interface Plugin {
4
+ id: PluginId;
5
+ process: RouteHandler;
6
+ priority?: number;
7
+ }
8
+ export declare class PluginSystem {
9
+ private plugins;
10
+ private executionOrder;
11
+ /**
12
+ * Registers a new plugin in the system
13
+ * @param plugin - Plugin to register
14
+ * @param options - Options for positioning plugins
15
+ */
16
+ register(plugin: Plugin, options?: {
17
+ before?: PluginId;
18
+ after?: PluginId;
19
+ }): void;
20
+ /**
21
+ * Updates the execution order of plugins
22
+ * @param pluginId - ID of the plugin to position
23
+ * @param options - Options for positioning
24
+ */
25
+ private updateExecutionOrder;
26
+ /**
27
+ * Returns a RouteHandler that executes all registered plugins in the correct order
28
+ */
29
+ getRouteHandler(): RouteHandler;
30
+ /**
31
+ * Recursively executes plugins in the correct order
32
+ * @param req - Request object
33
+ * @param res - Response object
34
+ * @param next - Next function
35
+ * @param index - Current index in the execution order
36
+ */
37
+ private executePlugins;
38
+ /**
39
+ * Returns the list of plugins in the execution order
40
+ */
41
+ getPluginsInOrder(): Plugin[];
42
+ }
43
+ export {};
@@ -0,0 +1,81 @@
1
+ export class PluginSystem {
2
+ plugins = [];
3
+ executionOrder = [];
4
+ /**
5
+ * Registers a new plugin in the system
6
+ * @param plugin - Plugin to register
7
+ * @param options - Options for positioning plugins
8
+ */
9
+ register(plugin, options) {
10
+ if (this.plugins.some(p => p.id === plugin.id)) {
11
+ throw new Error(`Plugin with id '${plugin.id}' already registered`);
12
+ }
13
+ // Add plugin to the list
14
+ this.plugins.push(plugin);
15
+ // Update the execution order
16
+ this.updateExecutionOrder(plugin.id, options);
17
+ }
18
+ /**
19
+ * Updates the execution order of plugins
20
+ * @param pluginId - ID of the plugin to position
21
+ * @param options - Options for positioning
22
+ */
23
+ updateExecutionOrder(pluginId, options) {
24
+ if (!this.executionOrder.includes(pluginId)) {
25
+ if (options?.before) {
26
+ const index = this.executionOrder.indexOf(options.before);
27
+ if (index === -1) {
28
+ throw new Error(`Plugin '${options.before}' not found`);
29
+ }
30
+ this.executionOrder.splice(index, 0, pluginId);
31
+ }
32
+ else if (options?.after) {
33
+ const index = this.executionOrder.indexOf(options.after);
34
+ if (index === -1) {
35
+ throw new Error(`Plugin '${options.after}' not found`);
36
+ }
37
+ this.executionOrder.splice(index + 1, 0, pluginId);
38
+ }
39
+ else {
40
+ this.executionOrder.push(pluginId);
41
+ }
42
+ }
43
+ }
44
+ /**
45
+ * Returns a RouteHandler that executes all registered plugins in the correct order
46
+ */
47
+ getRouteHandler() {
48
+ return (req, res, next) => {
49
+ this.executePlugins(req, res, next, 0);
50
+ };
51
+ }
52
+ /**
53
+ * Recursively executes plugins in the correct order
54
+ * @param req - Request object
55
+ * @param res - Response object
56
+ * @param next - Next function
57
+ * @param index - Current index in the execution order
58
+ */
59
+ executePlugins(req, res, next, index) {
60
+ if (index >= this.executionOrder.length) {
61
+ next();
62
+ return;
63
+ }
64
+ const pluginId = this.executionOrder[index];
65
+ const plugin = this.plugins.find(p => p.id === pluginId);
66
+ if (!plugin) {
67
+ throw new Error(`Plugin '${pluginId}' not found`);
68
+ }
69
+ plugin.process(req, res, () => {
70
+ this.executePlugins(req, res, next, index + 1);
71
+ });
72
+ }
73
+ /**
74
+ * Returns the list of plugins in the execution order
75
+ */
76
+ getPluginsInOrder() {
77
+ return this.executionOrder
78
+ .map(id => this.plugins.find(p => p.id === id))
79
+ .filter((p) => p !== undefined);
80
+ }
81
+ }
@@ -0,0 +1,5 @@
1
+ interface RenderData {
2
+ [key: string]: string;
3
+ }
4
+ export declare function renderHTML(templatePath: string, data: RenderData): string;
5
+ export {};
package/dist/render.js ADDED
@@ -0,0 +1,16 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ export function renderHTML(templatePath, data) {
4
+ let template = fs.readFileSync(templatePath, "utf8");
5
+ // Inserting data, e.g. {{name}}
6
+ template = template.replace(/{{(.*?)}}/g, (_, key) => data[key.trim()] || "");
7
+ // Loading partials, e.g. <!-- include header -->
8
+ template = template.replace(/<!--\s*include\s*(.*?)\s*-->/g, (_, partialName) => {
9
+ const partialPath = path.join(path.dirname(templatePath), partialName + ".html");
10
+ if (fs.existsSync(partialPath))
11
+ return renderHTML(partialPath, data);
12
+ else
13
+ return `<!-- Partial "${partialName}" (${partialPath.replace(process.cwd() + "/", "")}) not found -->`;
14
+ });
15
+ return template;
16
+ }
package/dist/res.d.ts CHANGED
@@ -7,4 +7,5 @@ export declare class FFResponse extends http.ServerResponse {
7
7
  status(code: number): this;
8
8
  redirect(url: string): this;
9
9
  sendFile(filePath: string): this;
10
+ render(templatePath: string, data: any): this;
10
11
  }
package/dist/res.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import http from "http";
2
2
  import { getContentType } from "./helpers.js";
3
3
  import { createReadStream } from "fs";
4
+ import { renderHTML } from "./render.js";
4
5
  export class FFResponse extends http.ServerResponse {
5
6
  _ended = false;
6
7
  json(data) {
@@ -36,4 +37,9 @@ export class FFResponse extends http.ServerResponse {
36
37
  createReadStream(filePath).pipe(this);
37
38
  return this;
38
39
  }
40
+ render(templatePath, data) {
41
+ this.setHeader("Content-Type", "text/html");
42
+ this.end(renderHTML(templatePath, data));
43
+ return this;
44
+ }
39
45
  }
package/dist/test.js CHANGED
@@ -1,11 +1,27 @@
1
- import FalconFrame from "./index.js";
1
+ import FalconFrame, { PluginSystem } from "./index.js";
2
2
  const app = new FalconFrame({
3
3
  logLevel: "INFO",
4
4
  });
5
+ const pluginSystem = new PluginSystem();
6
+ pluginSystem.register({
7
+ id: "logger",
8
+ process: (req, res, next) => {
9
+ console.log(`Request to ${req.url} with body ${JSON.stringify(req.body)}`);
10
+ next();
11
+ }
12
+ });
13
+ pluginSystem.register({
14
+ id: "logger2",
15
+ process: (req, res, next) => {
16
+ req.body.test = "test";
17
+ next();
18
+ }
19
+ }, { before: "logger" });
5
20
  app.use((req, res, next) => {
6
21
  console.log(`[${req.method}] ${req.path}`);
7
22
  next();
8
23
  });
24
+ app.use(pluginSystem.getRouteHandler());
9
25
  app.static("/", "public");
10
26
  app.get("/hello", (req, res) => {
11
27
  const name = req.query.name || "World";
package/dist/types.d.ts CHANGED
@@ -9,7 +9,7 @@ export interface Cookies {
9
9
  [key: string]: string;
10
10
  }
11
11
  export interface Query {
12
- [key: string]: string | string[];
12
+ [key: string]: string;
13
13
  }
14
14
  export interface Body {
15
15
  [key: string]: any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wxn0brp/falcon-frame",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "author": "wxn0brP",