html-express-js 4.2.1 → 5.0.0

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/LICENSE CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-express-js",
3
- "version": "4.2.1",
3
+ "version": "5.0.0",
4
4
  "description": "An Express template engine to render HTML views using native JavaScript",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -51,23 +51,23 @@
51
51
  },
52
52
  "homepage": "https://github.com/markcellus/html-express-js#readme",
53
53
  "dependencies": {
54
- "glob": "^11.0.0"
54
+ "glob": "^13.0.6"
55
55
  },
56
56
  "devDependencies": {
57
- "@types/chai": "^5.0.0",
58
- "@types/express": "^5.0.0",
59
- "@types/mocha": "^10.0.6",
57
+ "@types/chai": "^5.2.3",
58
+ "@types/express": "^5.0.6",
59
+ "@types/mocha": "^10.0.10",
60
60
  "@types/reload": "^3.2.3",
61
- "@types/sinon": "^17.0.3",
62
- "chai": "^6.0.1",
63
- "chokidar": "^4.0.1",
64
- "express": "^5.1.0",
65
- "husky": "^9.0.7",
66
- "mocha": "^11.0.1",
67
- "prettier": "^3.0.3",
68
- "release-it": "19.0.4",
69
- "reload": "^3.2.0",
70
- "sinon": "^21.0.0",
71
- "typescript": "^5.4.3"
61
+ "@types/sinon": "^21.0.1",
62
+ "chai": "^6.2.2",
63
+ "chokidar": "^5.0.0",
64
+ "express": "^5.2.1",
65
+ "husky": "^9.1.7",
66
+ "mocha": "^11.7.5",
67
+ "prettier": "^3.8.1",
68
+ "release-it": "19.2.4",
69
+ "reload": "^3.4.3",
70
+ "sinon": "^21.0.3",
71
+ "typescript": "^6.0.2"
72
72
  }
73
73
  }
package/src/index.d.ts CHANGED
@@ -1,13 +1,31 @@
1
+ /**
2
+ * Generates HTML for the provided view and adds all includes to state object.
3
+ *
4
+ * @param {string | HTMLExpressView} view - The view function or path to view file
5
+ * @param {import('express').Request} req - The request to build the state from
6
+ * @param {Record<string, any>} [data] - Data provided to the view
7
+ * @returns {Promise<string>} HTML with includes available (appended to state)
8
+ */
9
+ export function buildStateViewHtml(view: string | HTMLExpressView, req: import("express").Request, data?: Record<string, any>): Promise<string>;
1
10
  /**
2
11
  * Renders a JS HTML file and adds all includes to state object.
3
12
  *
4
- * @param {string} filePath - The path to html file
13
+ * @param {string | HTMLExpressView} view - The path to html file
5
14
  * @param {import('express').Request} req
6
15
  * @param {import('express').Response} res
7
16
  * @param {Record<string, any>} [data]
8
17
  * @returns {Promise<string>} HTML with includes available (appended to state)
9
18
  */
10
- export function renderView(filePath: string, req: import("express").Request, res: import("express").Response, data?: Record<string, any>): Promise<string>;
19
+ export function renderView(view: string | HTMLExpressView, req: import("express").Request, res: import("express").Response, data?: Record<string, any>): Promise<string>;
20
+ /**
21
+ * Renders a JS HTML file and adds all includes to state object.
22
+ *
23
+ * @param {string | HTMLExpressView} view - The view function or path to html file
24
+ * @param {object} data - Data to be made available in view
25
+ * @param {Record<string, any>} [customState]
26
+ * @returns {Promise<string>} HTML with includes available (appended to state)
27
+ */
28
+ export function buildViewHtml(view: string | HTMLExpressView, data?: object, customState?: Record<string, any>): Promise<string>;
11
29
  /**
12
30
  * Template literal that supports string
13
31
  * interpolating in passed HTML.
@@ -55,7 +73,7 @@ export type HTMLExpressOptions = {
55
73
  */
56
74
  buildRequestState?: HTMLExpressBuildStateHandler | undefined;
57
75
  };
58
- export type HTMLExpressViewState = Record<string, string> & {
76
+ export type HTMLExpressViewState = Record<string, any> & {
59
77
  includes: Record<string, string>;
60
78
  };
61
79
  export type HTMLExpressView<D extends Record<string, any> = Record<string, any>> = (data: D, state: HTMLExpressViewState) => string;
package/src/index.js CHANGED
@@ -20,7 +20,7 @@ import { stat } from 'fs/promises';
20
20
  */
21
21
 
22
22
  /**
23
- * @typedef {Record<string, string> & {
23
+ * @typedef {Record<string, any> & {
24
24
  * includes: Record<string, string>
25
25
  * }} HTMLExpressViewState
26
26
  */
@@ -54,17 +54,17 @@ let buildRequestState;
54
54
  let notFoundView = `404/index`;
55
55
 
56
56
  /**
57
- * Renders an HTML template in a file.
57
+ * Generates the HTML for a view function inside of the passed file.
58
58
  *
59
59
  * @private
60
- * @param {string} path - The path to html file
61
- * @param {object} [data]
62
- * @param {object} [state] - Page-level attributes
60
+ * @param {HTMLExpressView} view - The view function
61
+ * @param {Record<string, any>} [data]
62
+ * @param {HTMLExpressViewState} [state] - Page-level attributes
63
63
  * @returns {Promise<string>} HTML
64
64
  */
65
- async function renderFileTemplate(path, data, state) {
66
- const { view } = await import(path);
67
- const rendered = view(data, state);
65
+ async function renderViewHtml(view, data, state) {
66
+ state = state || { includes: {} };
67
+ const rendered = view(data || {}, state);
68
68
  let html = '';
69
69
  for (const chunk of rendered) {
70
70
  html += chunk;
@@ -72,18 +72,45 @@ async function renderFileTemplate(path, data, state) {
72
72
  return html;
73
73
  }
74
74
 
75
+ /**
76
+ * Generates the HTML for a view function inside of the passed file.
77
+ *
78
+ * @private
79
+ * @param {string} path - The path to html file
80
+ * @param {object} [data]
81
+ * @param {HTMLExpressViewState} [state] - Page-level attributes
82
+ * @returns {Promise<string>} HTML
83
+ */
84
+ async function buildView(path, data, state) {
85
+ const { view } = await import(path);
86
+ return renderViewHtml(view, data, state);
87
+ }
88
+
89
+ /**
90
+ * Generates HTML for the provided view and adds all includes to state object.
91
+ *
92
+ * @param {string | HTMLExpressView} view - The view function or path to view file
93
+ * @param {import('express').Request} req - The request to build the state from
94
+ * @param {Record<string, any>} [data] - Data provided to the view
95
+ * @returns {Promise<string>} HTML with includes available (appended to state)
96
+ */
97
+ export async function buildStateViewHtml(view, req, data = {}) {
98
+ const requestState = buildRequestState ? await buildRequestState(req) : {};
99
+ return buildViewHtml(view, data, requestState);
100
+ }
101
+
75
102
  /**
76
103
  * Renders a JS HTML file and adds all includes to state object.
77
104
  *
78
- * @param {string} filePath - The path to html file
105
+ * @param {string | HTMLExpressView} view - The path to html file
79
106
  * @param {import('express').Request} req
80
107
  * @param {import('express').Response} res
81
108
  * @param {Record<string, any>} [data]
82
109
  * @returns {Promise<string>} HTML with includes available (appended to state)
83
110
  */
84
- export async function renderView(filePath, req, res, data = {}) {
85
- const requestState = buildRequestState ? await buildRequestState(req) : {};
86
- const html = await buildViewHtml(filePath, data, requestState);
111
+ export async function renderView(view, req, res, data = {}) {
112
+ const html = await buildStateViewHtml(view, req, data);
113
+ res.set('Content-Type', 'text/html');
87
114
  res.send(html);
88
115
  return html;
89
116
  }
@@ -91,23 +118,27 @@ export async function renderView(filePath, req, res, data = {}) {
91
118
  /**
92
119
  * Renders a JS HTML file and adds all includes to state object.
93
120
  *
94
- * @param {string} filePath - The path to html file
121
+ * @param {string | HTMLExpressView} view - The view function or path to html file
95
122
  * @param {object} data - Data to be made available in view
96
123
  * @param {Record<string, any>} [customState]
97
124
  * @returns {Promise<string>} HTML with includes available (appended to state)
98
125
  */
99
- async function buildViewHtml(filePath, data = {}, customState = {}) {
126
+ export async function buildViewHtml(view, data = {}, customState = {}) {
100
127
  /**
101
- * @type {Record<string, any>}
128
+ * @type {HTMLExpressViewState}
102
129
  */
103
130
  const state = { ...customState, includes: {} };
104
131
 
105
132
  const includeFilePaths = await glob(`${includesDir}/*.js`);
106
133
  for await (const includePath of includeFilePaths) {
107
134
  const key = basename(includePath, '.js');
108
- state.includes[key] = await renderFileTemplate(includePath, data, state);
135
+ state.includes[key] = await buildView(includePath, data, state);
136
+ }
137
+ if (typeof view === 'string') {
138
+ const filePath = view;
139
+ return await buildView(`${viewsDir}/${filePath}.js`, data, state);
109
140
  }
110
- return await renderFileTemplate(`${viewsDir}/${filePath}.js`, data, state);
141
+ return await renderViewHtml(view, data, state);
111
142
  }
112
143
 
113
144
  /**