ghtml 3.0.7 → 3.0.8

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
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Gürgün Dayıoğlu
3
+ Copyright (c) 2023 Gürgün Dayıoğlu
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/bench/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  /* eslint-disable no-unused-vars */
2
+
2
3
  import { html } from "../src/index.js";
3
4
  import { Bench } from "tinybench";
4
5
  import { writeFileSync } from "node:fs";
5
6
  import { Buffer } from "node:buffer";
6
7
 
7
8
  let result = "";
9
+
8
10
  const bench = new Bench({ time: 500 });
9
11
 
10
12
  bench.add("simple HTML formatting", () => {
@@ -112,7 +114,7 @@ await bench.warmup();
112
114
  await bench.run();
113
115
 
114
116
  const table = bench.table();
115
- console.table(table);
117
+ globalThis.console.table(table);
116
118
 
117
119
  writeFileSync(
118
120
  "bench/results.json",
@@ -1 +1 @@
1
- console.warn("Hello World!");
1
+ globalThis.console.warn("Hello World!");
@@ -6,8 +6,8 @@
6
6
  "build": "ghtml --roots=assets/ --refs=routes/ --prefix=/p/assets/"
7
7
  },
8
8
  "dependencies": {
9
- "@fastify/static": "^7.0.1",
10
- "fastify": "^4.26.1",
9
+ "@fastify/static": "^8.0.1",
10
+ "fastify": "^5.0.0",
11
11
  "ghtml": "file:../../"
12
12
  }
13
13
  }
@@ -1,3 +1,5 @@
1
+ /* eslint-disable n/no-missing-import, require-await */
2
+
1
3
  import { html } from "ghtml";
2
4
 
3
5
  export default async (fastify) => {
@@ -1,10 +1,12 @@
1
+ /* eslint-disable n/no-missing-import */
2
+
1
3
  import Fastify from "fastify";
2
4
 
3
5
  const fastify = Fastify();
4
6
 
5
7
  // Plugins
6
8
  await fastify.register(import("@fastify/static"), {
7
- root: new URL("assets/", import.meta.url).pathname,
9
+ root: new globalThis.URL("assets/", import.meta.url).pathname,
8
10
  prefix: "/p/assets/",
9
11
  wildcard: false,
10
12
  index: false,
@@ -20,5 +22,5 @@ fastify.listen({ port: 5050 }, (err, address) => {
20
22
  throw err;
21
23
  }
22
24
 
23
- console.warn(`Server listening at ${address}`);
25
+ globalThis.console.warn(`Server listening at ${address}`);
24
26
  });
package/bin/src/index.js CHANGED
@@ -18,7 +18,7 @@ const parseArguments = (args) => {
18
18
  }
19
19
 
20
20
  if (!roots || !refs) {
21
- console.error(
21
+ globalThis.console.error(
22
22
  'Usage: npx ghtml --roots="base/path/to/scan/assets/1/,base/path/to/scan/assets/2/" --refs="views/path/to/append/hashes/1/,views/path/to/append/hashes/2/" [--prefix="/optional/prefix/"]',
23
23
  );
24
24
  process.exit(1);
@@ -31,10 +31,10 @@ const main = async () => {
31
31
  const { roots, refs, prefix } = parseArguments(process.argv.slice(2));
32
32
 
33
33
  try {
34
- console.warn(`Generating hashes and updating file paths...`);
35
- console.warn(`Scanning files in: ${roots}`);
36
- console.warn(`Updating files in: ${refs}`);
37
- console.warn(`Using prefix: ${prefix}`);
34
+ globalThis.console.warn(`Generating hashes and updating file paths...`);
35
+ globalThis.console.warn(`Scanning files in: ${roots}`);
36
+ globalThis.console.warn(`Updating files in: ${refs}`);
37
+ globalThis.console.warn(`Using prefix: ${prefix}`);
38
38
 
39
39
  await generateHashesAndReplace({
40
40
  roots,
@@ -42,9 +42,11 @@ const main = async () => {
42
42
  prefix,
43
43
  });
44
44
 
45
- console.warn("Hash generation and file updates completed successfully.");
45
+ globalThis.console.warn(
46
+ "Hash generation and file updates completed successfully.",
47
+ );
46
48
  } catch (error) {
47
- console.error(`Error occurred: ${error.message}`);
49
+ globalThis.console.error(`Error occurred: ${error.message}`);
48
50
  process.exit(1);
49
51
  }
50
52
  };
package/bin/src/utils.js CHANGED
@@ -1,3 +1,5 @@
1
+ /* eslint-disable no-await-in-loop */
2
+
1
3
  import { Glob } from "glob";
2
4
  import { createHash } from "node:crypto";
3
5
  import { readFile, writeFile } from "node:fs/promises";
@@ -44,12 +46,12 @@ const updateFilePathsWithHashes = async (
44
46
  for (const [path, hash] of fileHashes) {
45
47
  const fullPath = prefix + path;
46
48
  const escapedPath = fullPath.replace(
47
- /[$()*+.?[\\\]^{|}]/g,
49
+ /[$()*+.?[\\\]^{|}]/gu,
48
50
  String.raw`\$&`,
49
51
  );
50
52
  const regex = new RegExp(
51
53
  `(?<path>${escapedPath})(\\?(?<queryString>[^#"'\`]*))?`,
52
- "g",
54
+ "gu",
53
55
  );
54
56
 
55
57
  content = content.replace(
@@ -0,0 +1,3 @@
1
+ import grules from "grules";
2
+
3
+ export default [...grules];
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Replace your template engine with fast JavaScript by leveraging the power of tagged templates.",
4
4
  "author": "Gürgün Dayıoğlu",
5
5
  "license": "MIT",
6
- "version": "3.0.7",
6
+ "version": "3.0.8",
7
7
  "type": "module",
8
8
  "bin": "./bin/src/index.js",
9
9
  "main": "./src/index.js",
@@ -27,9 +27,9 @@
27
27
  "devDependencies": {
28
28
  "@fastify/pre-commit": "^2.1.0",
29
29
  "c8": "^10.1.2",
30
- "grules": "^0.23.3",
30
+ "grules": "^0.25.0",
31
31
  "tinybench": "^2.9.0",
32
- "typescript": ">=5.5.4"
32
+ "typescript": ">=5.6.2"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",
package/src/html.js CHANGED
@@ -1,3 +1,5 @@
1
+ /* eslint-disable no-await-in-loop, require-unicode-regexp */
2
+
1
3
  const escapeRegExp = /["&'<=>]/g;
2
4
 
3
5
  const escapeFunction = (string) => {
@@ -35,24 +37,18 @@ const escapeFunction = (string) => {
35
37
  };
36
38
 
37
39
  /**
38
- * The `html` function is designed to tag template literals and automatically escape their expressions.
39
- * @param {TemplateStringsArray} literals Tagged template literals.
40
- * @param {...any} expressions Expressions to interpolate.
41
- * @returns {string} The processed HTML string.
40
+ * @param {TemplateStringsArray} literals literals
41
+ * @param {...any} expressions expressions
42
+ * @returns {string} string
42
43
  */
43
44
  export const html = (literals, ...expressions) => {
44
45
  let accumulator = "";
45
46
 
46
47
  for (let i = 0; i !== expressions.length; ++i) {
47
48
  let literal = literals.raw[i];
48
- let string =
49
- typeof expressions[i] === "string"
50
- ? expressions[i]
51
- : expressions[i] == null
52
- ? ""
53
- : Array.isArray(expressions[i])
54
- ? expressions[i].join("")
55
- : `${expressions[i]}`;
49
+ let string = Array.isArray(expressions[i])
50
+ ? expressions[i].join("")
51
+ : String(expressions[i] ?? "");
56
52
 
57
53
  if (literal && literal.charCodeAt(literal.length - 1) === 33) {
58
54
  literal = literal.slice(0, -1);
@@ -67,11 +63,10 @@ export const html = (literals, ...expressions) => {
67
63
  };
68
64
 
69
65
  /**
70
- * The `htmlGenerator` function acts as the generator version of the `html` function.
71
- * @param {TemplateStringsArray} literals Tagged template literals.
72
- * @param {...any} expressions Expressions to interpolate.
73
- * @yields Processed HTML strings.
74
- * @returns {Generator<string, void, void>} The HTML generator.
66
+ * @param {TemplateStringsArray} literals literals
67
+ * @param {...any} expressions expressions
68
+ * @yields {string} string
69
+ * @returns {Generator<string, void, void>} Generator<string, void, void>
75
70
  */
76
71
  export const htmlGenerator = function* (literals, ...expressions) {
77
72
  for (let i = 0; i !== expressions.length; ++i) {
@@ -81,12 +76,12 @@ export const htmlGenerator = function* (literals, ...expressions) {
81
76
 
82
77
  if (typeof expression === "string") {
83
78
  string = expression;
84
- } else if (expression == null) {
79
+ } else if (expression === undefined || expression === null) {
85
80
  string = "";
86
81
  } else {
87
82
  if (expression[Symbol.iterator]) {
88
83
  const isRaw =
89
- literal !== "" && literal.charCodeAt(literal.length - 1) === 33;
84
+ Boolean(literal) && literal.charCodeAt(literal.length - 1) === 33;
90
85
 
91
86
  if (isRaw) {
92
87
  literal = literal.slice(0, -1);
@@ -100,22 +95,18 @@ export const htmlGenerator = function* (literals, ...expressions) {
100
95
  if (typeof expression === "string") {
101
96
  string = expression;
102
97
  } else {
103
- if (expression == null) {
98
+ if (expression === undefined || expression === null) {
104
99
  continue;
105
100
  }
106
101
 
107
102
  if (expression[Symbol.iterator]) {
108
103
  for (expression of expression) {
109
- if (typeof expression === "string") {
110
- string = expression;
111
- } else {
112
- if (expression == null) {
113
- continue;
114
- }
115
-
116
- string = `${expression}`;
104
+ if (expression === undefined || expression === null) {
105
+ continue;
117
106
  }
118
107
 
108
+ string = String(expression);
109
+
119
110
  if (string) {
120
111
  if (!isRaw) {
121
112
  string = escapeFunction(string);
@@ -128,7 +119,7 @@ export const htmlGenerator = function* (literals, ...expressions) {
128
119
  continue;
129
120
  }
130
121
 
131
- string = `${expression}`;
122
+ string = String(expression);
132
123
  }
133
124
 
134
125
  if (string) {
@@ -143,7 +134,7 @@ export const htmlGenerator = function* (literals, ...expressions) {
143
134
  continue;
144
135
  }
145
136
 
146
- string = `${expression}`;
137
+ string = String(expression);
147
138
  }
148
139
 
149
140
  if (literal && literal.charCodeAt(literal.length - 1) === 33) {
@@ -163,11 +154,10 @@ export const htmlGenerator = function* (literals, ...expressions) {
163
154
  };
164
155
 
165
156
  /**
166
- * This version of HTML generator should be preferred for asynchronous and streaming use cases.
167
- * @param {TemplateStringsArray} literals Tagged template literals.
168
- * @param {...any} expressions Expressions to interpolate.
169
- * @yields Processed HTML strings.
170
- * @returns {AsyncGenerator<string, void, void>} The HTML generator.
157
+ * @param {TemplateStringsArray} literals literals
158
+ * @param {...any} expressions expressions
159
+ * @yields {string} string
160
+ * @returns {AsyncGenerator<string, void, void>} AsyncGenerator<string, void, void>
171
161
  */
172
162
  export const htmlAsyncGenerator = async function* (literals, ...expressions) {
173
163
  for (let i = 0; i !== expressions.length; ++i) {
@@ -177,12 +167,12 @@ export const htmlAsyncGenerator = async function* (literals, ...expressions) {
177
167
 
178
168
  if (typeof expression === "string") {
179
169
  string = expression;
180
- } else if (expression == null) {
170
+ } else if (expression === undefined || expression === null) {
181
171
  string = "";
182
172
  } else {
183
173
  if (expression[Symbol.iterator] || expression[Symbol.asyncIterator]) {
184
174
  const isRaw =
185
- literal !== "" && literal.charCodeAt(literal.length - 1) === 33;
175
+ Boolean(literal) && literal.charCodeAt(literal.length - 1) === 33;
186
176
 
187
177
  if (isRaw) {
188
178
  literal = literal.slice(0, -1);
@@ -196,7 +186,7 @@ export const htmlAsyncGenerator = async function* (literals, ...expressions) {
196
186
  if (typeof expression === "string") {
197
187
  string = expression;
198
188
  } else {
199
- if (expression == null) {
189
+ if (expression === undefined || expression === null) {
200
190
  continue;
201
191
  }
202
192
 
@@ -205,16 +195,12 @@ export const htmlAsyncGenerator = async function* (literals, ...expressions) {
205
195
  expression[Symbol.asyncIterator]
206
196
  ) {
207
197
  for await (expression of expression) {
208
- if (typeof expression === "string") {
209
- string = expression;
210
- } else {
211
- if (expression == null) {
212
- continue;
213
- }
214
-
215
- string = `${expression}`;
198
+ if (expression === undefined || expression === null) {
199
+ continue;
216
200
  }
217
201
 
202
+ string = String(expression);
203
+
218
204
  if (string) {
219
205
  if (!isRaw) {
220
206
  string = escapeFunction(string);
@@ -227,7 +213,7 @@ export const htmlAsyncGenerator = async function* (literals, ...expressions) {
227
213
  continue;
228
214
  }
229
215
 
230
- string = `${expression}`;
216
+ string = String(expression);
231
217
  }
232
218
 
233
219
  if (string) {
@@ -242,7 +228,7 @@ export const htmlAsyncGenerator = async function* (literals, ...expressions) {
242
228
  continue;
243
229
  }
244
230
 
245
- string = `${expression}`;
231
+ string = String(expression);
246
232
  }
247
233
 
248
234
  if (literal && literal.charCodeAt(literal.length - 1) === 33) {
@@ -3,8 +3,8 @@ import { readFileSync } from "node:fs";
3
3
  const cache = new Map();
4
4
 
5
5
  /**
6
- * @param {string} path The path to the file to render.
7
- * @returns {string} The content of the file.
6
+ * @param {string} path path
7
+ * @returns {string} string
8
8
  */
9
9
  export const includeFile = (path) => {
10
10
  let file = cache.get(path);
package/test/index.js CHANGED
@@ -22,6 +22,11 @@ const generatorExample = function* () {
22
22
  yield "</p>";
23
23
  };
24
24
 
25
+ const generatorExample2 = function* () {
26
+ yield ["", "<p>"];
27
+ yield "";
28
+ };
29
+
25
30
  const generatorPromiseExample = function* () {
26
31
  yield [
27
32
  new Promise((resolve) => {
@@ -33,6 +38,17 @@ const generatorPromiseExample = function* () {
33
38
  yield;
34
39
  };
35
40
 
41
+ const generatorPromiseExample2 = function* () {
42
+ yield [
43
+ new Promise((resolve) => {
44
+ resolve("<p>");
45
+ }),
46
+ null,
47
+ "",
48
+ ];
49
+ yield "";
50
+ };
51
+
36
52
  test("renders empty input", () => {
37
53
  assert.strictEqual(html({ raw: [""] }), "");
38
54
  });
@@ -204,6 +220,18 @@ test("htmlGenerator works with other generators (raw)", () => {
204
220
  assert.strictEqual(generator.next().done, true);
205
221
  });
206
222
 
223
+ test("htmlGenerator works with other generators (raw) /2", () => {
224
+ const generator = htmlGenerator`<div>!${generatorExample2()}</div>`;
225
+ let accumulator = "";
226
+
227
+ for (const value of generator) {
228
+ accumulator += value;
229
+ }
230
+
231
+ assert.strictEqual(accumulator, "<div><p></div>");
232
+ assert.strictEqual(generator.next().done, true);
233
+ });
234
+
207
235
  test("htmlGenerator works with other generators (escaped)", () => {
208
236
  const generator = htmlGenerator`<div>${generatorExample()}</div>`;
209
237
  let accumulator = "";
@@ -291,6 +319,17 @@ test("htmlAsyncGenerator works with other generators (raw)", async () => {
291
319
  );
292
320
  });
293
321
 
322
+ test("htmlAsyncGenerator works with other generators (raw) /2", async () => {
323
+ const generator = htmlAsyncGenerator`<div>!${generatorPromiseExample2()}</div>`;
324
+ let accumulator = "";
325
+
326
+ for await (const value of generator) {
327
+ accumulator += value;
328
+ }
329
+
330
+ assert.strictEqual(accumulator, "<div><p></div>");
331
+ });
332
+
294
333
  test("htmlAsyncGenerator works with other generators (escaped)", async () => {
295
334
  const generator = htmlAsyncGenerator`<div>${generatorExample()}</div>`;
296
335
  let accumulator = "";
package/.eslintrc.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "root": true,
3
- "extends": ["plugin:grules/all"],
4
- "rules": {
5
- "no-await-in-loop": "off",
6
- "require-unicode-regexp": "off"
7
- }
8
- }
@@ -1,6 +0,0 @@
1
- {
2
- "rules": {
3
- "require-await": "off",
4
- "n/no-missing-import": "off"
5
- }
6
- }