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 +1 -1
- package/bench/index.js +3 -1
- package/bin/example/assets/script.js +1 -1
- package/bin/example/package.json +2 -2
- package/bin/example/routes/index.js +2 -0
- package/bin/example/server.js +4 -2
- package/bin/src/index.js +9 -7
- package/bin/src/utils.js +4 -2
- package/eslint.config.js +3 -0
- package/package.json +3 -3
- package/src/html.js +34 -48
- package/src/includeFile.js +2 -2
- package/test/index.js +39 -0
- package/.eslintrc.json +0 -8
- package/bin/example/.eslintrc.json +0 -6
package/LICENSE
CHANGED
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!");
|
package/bin/example/package.json
CHANGED
package/bin/example/server.js
CHANGED
|
@@ -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(
|
|
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
|
-
/[$()*+.?[\\\]^{|}]/
|
|
49
|
+
/[$()*+.?[\\\]^{|}]/gu,
|
|
48
50
|
String.raw`\$&`,
|
|
49
51
|
);
|
|
50
52
|
const regex = new RegExp(
|
|
51
53
|
`(?<path>${escapedPath})(\\?(?<queryString>[^#"'\`]*))?`,
|
|
52
|
-
"
|
|
54
|
+
"gu",
|
|
53
55
|
);
|
|
54
56
|
|
|
55
57
|
content = content.replace(
|
package/eslint.config.js
ADDED
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.
|
|
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.
|
|
30
|
+
"grules": "^0.25.0",
|
|
31
31
|
"tinybench": "^2.9.0",
|
|
32
|
-
"typescript": ">=5.
|
|
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
|
-
*
|
|
39
|
-
* @param {
|
|
40
|
-
* @
|
|
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
|
-
|
|
50
|
-
|
|
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
|
-
*
|
|
71
|
-
* @param {
|
|
72
|
-
* @
|
|
73
|
-
* @
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
110
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
*
|
|
167
|
-
* @param {
|
|
168
|
-
* @
|
|
169
|
-
* @
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
209
|
-
|
|
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 =
|
|
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 =
|
|
231
|
+
string = String(expression);
|
|
246
232
|
}
|
|
247
233
|
|
|
248
234
|
if (literal && literal.charCodeAt(literal.length - 1) === 33) {
|
package/src/includeFile.js
CHANGED
|
@@ -3,8 +3,8 @@ import { readFileSync } from "node:fs";
|
|
|
3
3
|
const cache = new Map();
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* @param {string} path
|
|
7
|
-
* @returns {string}
|
|
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