tkeron 5.1.1 → 5.2.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/changelog.md +19 -0
- package/package.json +1 -1
- package/src/build.ts +3 -0
- package/src/processCom.ts +12 -0
- package/src/processComTs.ts +12 -0
- package/src/processPost.ts +80 -0
- package/tkeron.d.ts +1 -0
package/changelog.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# v5.2.0
|
|
2
|
+
|
|
3
|
+
## Feature: `.post.ts` post-processing support
|
|
4
|
+
|
|
5
|
+
- New file type `.post.ts`: runs after the build to post-process the corresponding `.html` file
|
|
6
|
+
- The `.post.ts` script receives a `document` object (parsed from the HTML) and writes the result back to the HTML file after execution
|
|
7
|
+
- Executes with `bun run` in the project root context
|
|
8
|
+
- Useful for final DOM manipulation, injecting metadata, or any transformation after components are resolved
|
|
9
|
+
- `processPost` returns `false` when no `.post.ts` files are found (no-op)
|
|
10
|
+
|
|
11
|
+
## Feature: `data-tk-id` attribute on component `<style>` elements
|
|
12
|
+
|
|
13
|
+
- Root-level `<style>` elements in component output now receive a `data-tk-id="component-name"` attribute
|
|
14
|
+
- Nested `<style>` elements (inside wrappers) also receive `data-tk-id`
|
|
15
|
+
- Applies to both `.com.html` and `.com.ts` components
|
|
16
|
+
- Enables per-component style scoping and identification in the final HTML
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
1
20
|
# v5.1.0
|
|
2
21
|
|
|
3
22
|
## Feature: .com.html template injection into .com.ts components
|
package/package.json
CHANGED
package/src/build.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { processPre } from "./processPre";
|
|
|
4
4
|
import { processCom } from "./processCom";
|
|
5
5
|
import { processComTs } from "./processComTs";
|
|
6
6
|
import { processComMd } from "./processComMd";
|
|
7
|
+
import { processPost } from "./processPost";
|
|
7
8
|
import { rm, exists, mkdir, cp } from "fs/promises";
|
|
8
9
|
import type { Logger } from "@tkeron/tools";
|
|
9
10
|
import { silentLogger } from "@tkeron/tools";
|
|
@@ -56,6 +57,8 @@ export const build = async (options: BuildOptions) => {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
await processPost(tempDir, { logger: log, projectRoot: sourceParent });
|
|
61
|
+
|
|
59
62
|
if (await exists(target)) {
|
|
60
63
|
await rm(target, { recursive: true, force: true });
|
|
61
64
|
}
|
package/src/processCom.ts
CHANGED
|
@@ -189,6 +189,18 @@ const processComponents = async (
|
|
|
189
189
|
(tempContainer as any).childNodes || [],
|
|
190
190
|
).map((node: any) => (node?.cloneNode ? node.cloneNode(true) : node));
|
|
191
191
|
|
|
192
|
+
for (const node of nodesToInsert) {
|
|
193
|
+
if ((node as any).nodeType === 1) {
|
|
194
|
+
if ((node as any).tagName?.toLowerCase() === "style") {
|
|
195
|
+
(node as any).setAttribute("data-tk-id", tagName);
|
|
196
|
+
}
|
|
197
|
+
const nested = (node as any).querySelectorAll?.("style") || [];
|
|
198
|
+
for (const styleEl of nested) {
|
|
199
|
+
(styleEl as any).setAttribute("data-tk-id", tagName);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
192
204
|
const parent = (child as any).parentNode;
|
|
193
205
|
|
|
194
206
|
if (parent) {
|
package/src/processComTs.ts
CHANGED
|
@@ -335,6 +335,18 @@ ${codeWithoutImports}
|
|
|
335
335
|
(node: any) => (node?.cloneNode ? node.cloneNode(true) : node),
|
|
336
336
|
);
|
|
337
337
|
|
|
338
|
+
for (const node of nodesToInsert) {
|
|
339
|
+
if ((node as any).nodeType === 1) {
|
|
340
|
+
if ((node as any).tagName?.toLowerCase() === "style") {
|
|
341
|
+
(node as any).setAttribute("data-tk-id", tagName);
|
|
342
|
+
}
|
|
343
|
+
const nested = (node as any).querySelectorAll?.("style") || [];
|
|
344
|
+
for (const styleEl of nested) {
|
|
345
|
+
(styleEl as any).setAttribute("data-tk-id", tagName);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
338
350
|
const parent = (child as any).parentNode;
|
|
339
351
|
|
|
340
352
|
if (parent) {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { join, dirname } from "path";
|
|
2
|
+
import { getFilePaths } from "@tkeron/tools";
|
|
3
|
+
import type { Logger } from "@tkeron/tools";
|
|
4
|
+
import { silentLogger } from "@tkeron/tools";
|
|
5
|
+
|
|
6
|
+
const HTML_PARSER_PATH = import.meta.resolve("@tkeron/html-parser");
|
|
7
|
+
|
|
8
|
+
export interface ProcessPostOptions {
|
|
9
|
+
logger?: Logger;
|
|
10
|
+
projectRoot?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const processPost = async (
|
|
14
|
+
tempDir: string,
|
|
15
|
+
options: ProcessPostOptions = {},
|
|
16
|
+
): Promise<boolean> => {
|
|
17
|
+
const log = options.logger || silentLogger;
|
|
18
|
+
|
|
19
|
+
if (!tempDir || typeof tempDir !== "string") {
|
|
20
|
+
log.error(`\n❌ Error: Invalid tempDir provided for processPost.`);
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const postFiles = getFilePaths(tempDir, "**/*.post.ts", true);
|
|
25
|
+
|
|
26
|
+
if (postFiles.length === 0) return false;
|
|
27
|
+
|
|
28
|
+
for (const postFile of postFiles) {
|
|
29
|
+
const htmlFile = postFile.replace(/\.post\.ts$/, ".html");
|
|
30
|
+
|
|
31
|
+
const originalCode = await Bun.file(postFile).text();
|
|
32
|
+
|
|
33
|
+
const htmlContent = await Bun.file(htmlFile).text();
|
|
34
|
+
|
|
35
|
+
const modifiedCode = `
|
|
36
|
+
import { parseHTML } from ${JSON.stringify(HTML_PARSER_PATH)};
|
|
37
|
+
|
|
38
|
+
const htmlPath = ${JSON.stringify(htmlFile)};
|
|
39
|
+
const htmlContent = ${JSON.stringify(htmlContent)};
|
|
40
|
+
const document = parseHTML(htmlContent);
|
|
41
|
+
|
|
42
|
+
${originalCode}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
const doctype = '<!DOCTYPE html>\\n';
|
|
46
|
+
const htmlOutput = doctype + document.documentElement.outerHTML;
|
|
47
|
+
await Bun.write(htmlPath, htmlOutput);
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
await Bun.write(postFile, modifiedCode);
|
|
51
|
+
|
|
52
|
+
const proc = Bun.spawn(["bun", "run", postFile], {
|
|
53
|
+
cwd: options.projectRoot || dirname(postFile),
|
|
54
|
+
stdout: "pipe",
|
|
55
|
+
stderr: "pipe",
|
|
56
|
+
env: { ...process.env },
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
await proc.exited;
|
|
60
|
+
|
|
61
|
+
if (proc.exitCode !== 0) {
|
|
62
|
+
const stderr = await new Response(proc.stderr).text();
|
|
63
|
+
const stdout = await new Response(proc.stdout).text();
|
|
64
|
+
log.error(
|
|
65
|
+
`\n❌ Error: Post-processing failed for ${postFile.split("/").pop()}`,
|
|
66
|
+
);
|
|
67
|
+
log.error(`\n💡 File: ${postFile}`);
|
|
68
|
+
if (stderr) {
|
|
69
|
+
log.error(`\nError details:\n${stderr}`);
|
|
70
|
+
}
|
|
71
|
+
if (stdout) {
|
|
72
|
+
log.error(`\nOutput:\n${stdout}`);
|
|
73
|
+
}
|
|
74
|
+
log.error("");
|
|
75
|
+
throw new Error(`Post-processing failed for ${postFile}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return true;
|
|
80
|
+
};
|
package/tkeron.d.ts
CHANGED