@t8/docsgen 0.1.18 → 0.1.20
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/bin.js +54 -9
- package/package.json +1 -1
- package/src/bin/getConfig.ts +23 -4
- package/src/bin/getInjectedContent.ts +28 -0
- package/src/bin/setContent.ts +9 -0
- package/src/bin/stripHTML.ts +7 -0
- package/src/bin/toFileContent.ts +1 -1
- package/src/types/ContentInjectionMap.ts +14 -0
- package/src/types/ContentInjectionTarget.ts +1 -0
- package/src/types/EntryConfig.ts +2 -0
- package/src/types/Page.ts +1 -0
package/dist/bin.js
CHANGED
|
@@ -104,6 +104,15 @@ function getLocation(ctx, path, preferredLocation) {
|
|
|
104
104
|
return path;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
// src/bin/stripHTML.ts
|
|
108
|
+
var import_jsdom = require("jsdom");
|
|
109
|
+
function stripHTML(content) {
|
|
110
|
+
try {
|
|
111
|
+
return new import_jsdom.JSDOM(content).window.document.body.textContent;
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
107
116
|
// src/bin/toRepoURL.ts
|
|
108
117
|
function toRepoURL(x) {
|
|
109
118
|
if (!x) return "";
|
|
@@ -143,6 +152,22 @@ async function addMetadata(config2) {
|
|
|
143
152
|
return config2;
|
|
144
153
|
}
|
|
145
154
|
}
|
|
155
|
+
function deriveMissingProps(config2) {
|
|
156
|
+
let { dir, root, title, htmlTitle } = config2;
|
|
157
|
+
if (htmlTitle && !title) title = stripHTML(htmlTitle);
|
|
158
|
+
if (dir && !root) root = `/${dir}/`;
|
|
159
|
+
if (!root?.endsWith("/")) root = `${root ?? ""}/`;
|
|
160
|
+
return {
|
|
161
|
+
...config2,
|
|
162
|
+
dir,
|
|
163
|
+
root,
|
|
164
|
+
title,
|
|
165
|
+
htmlTitle
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
async function reviseConfig(config2) {
|
|
169
|
+
return deriveMissingProps(await addMetadata(config2));
|
|
170
|
+
}
|
|
146
171
|
var config = null;
|
|
147
172
|
async function getConfig() {
|
|
148
173
|
if (config) return config;
|
|
@@ -165,9 +190,8 @@ async function getConfig() {
|
|
|
165
190
|
...A(args)
|
|
166
191
|
};
|
|
167
192
|
if (config.entries)
|
|
168
|
-
config.entries = await Promise.all(config.entries.map(
|
|
169
|
-
else await
|
|
170
|
-
if (!config.root?.endsWith("/")) config.root = `${config.root ?? ""}/`;
|
|
193
|
+
config.entries = await Promise.all(config.entries.map(reviseConfig));
|
|
194
|
+
else config = await reviseConfig(config);
|
|
171
195
|
return config;
|
|
172
196
|
}
|
|
173
197
|
|
|
@@ -267,8 +291,21 @@ function getIcon({ favicon, faviconType }) {
|
|
|
267
291
|
return icon;
|
|
268
292
|
}
|
|
269
293
|
|
|
294
|
+
// src/bin/getInjectedContent.ts
|
|
295
|
+
function getInjectedContent(ctx, page, target, mode = "append") {
|
|
296
|
+
let injectedContent = ctx[mode]?.[target];
|
|
297
|
+
if (!injectedContent) return "";
|
|
298
|
+
return (Array.isArray(injectedContent) ? injectedContent : [injectedContent]).reduce((s, item) => {
|
|
299
|
+
if (item === void 0) return s;
|
|
300
|
+
if (typeof item === "string") return `${s}${s ? "\n" : ""}${item}`;
|
|
301
|
+
let { content, pages } = item;
|
|
302
|
+
if (!content || pages && !pages.includes(page)) return s;
|
|
303
|
+
return `${s}${s ? "\n" : ""}${content}`;
|
|
304
|
+
}, "");
|
|
305
|
+
}
|
|
306
|
+
|
|
270
307
|
// src/bin/getNav.ts
|
|
271
|
-
var
|
|
308
|
+
var import_jsdom2 = require("jsdom");
|
|
272
309
|
|
|
273
310
|
// src/bin/getRepoLink.ts
|
|
274
311
|
function getRepoLink({ repo }, className) {
|
|
@@ -283,7 +320,7 @@ async function getNav(ctx, navItems) {
|
|
|
283
320
|
let navContent = await fetchText(nav);
|
|
284
321
|
let s = "";
|
|
285
322
|
if (navContent) {
|
|
286
|
-
let navDom = new
|
|
323
|
+
let navDom = new import_jsdom2.JSDOM(navContent).window.document.body;
|
|
287
324
|
for (let link of navDom.querySelectorAll("a")) {
|
|
288
325
|
if (link.dataset.name === name) {
|
|
289
326
|
let parent = link.parentElement;
|
|
@@ -331,7 +368,7 @@ ${navContent}
|
|
|
331
368
|
}
|
|
332
369
|
|
|
333
370
|
// src/bin/getParsedContent.ts
|
|
334
|
-
var
|
|
371
|
+
var import_jsdom3 = require("jsdom");
|
|
335
372
|
var import_markdown_it = __toESM(require("markdown-it"));
|
|
336
373
|
|
|
337
374
|
// src/bin/getSlug.ts
|
|
@@ -415,7 +452,7 @@ function getSectionPostprocess(linkMap) {
|
|
|
415
452
|
};
|
|
416
453
|
}
|
|
417
454
|
function postprocessBadges(content) {
|
|
418
|
-
let { document } = new
|
|
455
|
+
let { document } = new import_jsdom3.JSDOM(content).window;
|
|
419
456
|
for (let img of document.querySelectorAll("img")) {
|
|
420
457
|
let parent = img.parentElement;
|
|
421
458
|
if (!parent) continue;
|
|
@@ -430,7 +467,7 @@ async function getParsedContent(ctx) {
|
|
|
430
467
|
let { singlePage } = ctx;
|
|
431
468
|
let rawContent = await fetchText(getLocation(ctx, "README.md", ctx.source));
|
|
432
469
|
let content = md.render(rawContent);
|
|
433
|
-
let dom = new
|
|
470
|
+
let dom = new import_jsdom3.JSDOM(content);
|
|
434
471
|
let { nav, linkMap } = buildNav(ctx, dom);
|
|
435
472
|
let badges = [];
|
|
436
473
|
let title = "";
|
|
@@ -511,7 +548,7 @@ function getTitle(ctx, { cover, originalContent, withPackageURL } = {}) {
|
|
|
511
548
|
|
|
512
549
|
// src/bin/toFileContent.ts
|
|
513
550
|
function toFileContent(x) {
|
|
514
|
-
return `${x.trim()}
|
|
551
|
+
return `${x.replace(/\s+(<\/(head|body)>)/g, "\n$1").trim()}
|
|
515
552
|
`;
|
|
516
553
|
}
|
|
517
554
|
|
|
@@ -552,9 +589,11 @@ async function setContent(ctx) {
|
|
|
552
589
|
<meta name="viewport" content="width=device-width">
|
|
553
590
|
<meta http-equiv="refresh" content="0; URL=${escapedRedirect}">
|
|
554
591
|
${iconTag}
|
|
592
|
+
${getInjectedContent(ctx, "redirect", "head")}
|
|
555
593
|
</head>
|
|
556
594
|
<body>
|
|
557
595
|
${counterContent}
|
|
596
|
+
${getInjectedContent(ctx, "redirect", "body")}
|
|
558
597
|
<script>window.location.replace("${escapedRedirect}");</script>
|
|
559
598
|
</body>
|
|
560
599
|
</html>
|
|
@@ -592,6 +631,7 @@ ${counterContent}
|
|
|
592
631
|
${iconTag}
|
|
593
632
|
${nav[i + 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i + 1]?.id}">` : ""}
|
|
594
633
|
${nav[i - 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i - 1]?.id}">` : ""}
|
|
634
|
+
${getInjectedContent(ctx, "section", "head")}
|
|
595
635
|
</head>
|
|
596
636
|
<body>
|
|
597
637
|
<div class="layout">
|
|
@@ -626,6 +666,7 @@ ${content.includes("<pre><code ") ? `
|
|
|
626
666
|
<script>hljs.highlightAll()</script>
|
|
627
667
|
`.trim() : ""}
|
|
628
668
|
${counterContent}
|
|
669
|
+
${getInjectedContent(ctx, "section", "body")}
|
|
629
670
|
</body>
|
|
630
671
|
</html>
|
|
631
672
|
`)
|
|
@@ -646,6 +687,7 @@ ${counterContent}
|
|
|
646
687
|
${iconTag}
|
|
647
688
|
<link rel="prefetch" href="${root}start">
|
|
648
689
|
${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
|
|
690
|
+
${getInjectedContent(ctx, "index", "head")}
|
|
649
691
|
</head>
|
|
650
692
|
<body>
|
|
651
693
|
<div class="layout">
|
|
@@ -685,6 +727,7 @@ ${[description, features].some((s) => s.includes("<pre><code ")) ? `
|
|
|
685
727
|
<script>hljs.highlightAll()</script>
|
|
686
728
|
`.trim() : ""}
|
|
687
729
|
${counterContent}
|
|
730
|
+
${getInjectedContent(ctx, "index", "body")}
|
|
688
731
|
</body>
|
|
689
732
|
</html>
|
|
690
733
|
`)
|
|
@@ -702,6 +745,7 @@ ${counterContent}
|
|
|
702
745
|
<link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
|
|
703
746
|
${iconTag}
|
|
704
747
|
<script>window.location.replace("${root}${contentDir}/${nav[0]?.id}");</script>
|
|
748
|
+
${getInjectedContent(ctx, "start", "head")}
|
|
705
749
|
</head>
|
|
706
750
|
<body>
|
|
707
751
|
<div class="layout">
|
|
@@ -709,6 +753,7 @@ ${counterContent}
|
|
|
709
753
|
</div>
|
|
710
754
|
|
|
711
755
|
${counterContent}
|
|
756
|
+
${getInjectedContent(ctx, "start", "body")}
|
|
712
757
|
</body>
|
|
713
758
|
</html>
|
|
714
759
|
`)
|
package/package.json
CHANGED
package/src/bin/getConfig.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { EntryConfig } from "../types/EntryConfig";
|
|
|
4
4
|
import type { PackageMetadata } from "../types/PackageMetadata";
|
|
5
5
|
import { fetchText } from "./fetchText";
|
|
6
6
|
import { getLocation } from "./getLocation";
|
|
7
|
+
import { stripHTML } from "./stripHTML";
|
|
7
8
|
import { toConfig } from "./toConfig";
|
|
8
9
|
|
|
9
10
|
async function addMetadata(config: EntryConfig) {
|
|
@@ -20,6 +21,26 @@ async function addMetadata(config: EntryConfig) {
|
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
function deriveMissingProps(config: EntryConfig) {
|
|
25
|
+
let { dir, root, title, htmlTitle } = config;
|
|
26
|
+
|
|
27
|
+
if (htmlTitle && !title) title = stripHTML(htmlTitle);
|
|
28
|
+
if (dir && !root) root = `/${dir}/`;
|
|
29
|
+
if (!root?.endsWith("/")) root = `${root ?? ""}/`;
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
...config,
|
|
33
|
+
dir,
|
|
34
|
+
root,
|
|
35
|
+
title,
|
|
36
|
+
htmlTitle,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function reviseConfig(config: EntryConfig) {
|
|
41
|
+
return deriveMissingProps(await addMetadata(config));
|
|
42
|
+
}
|
|
43
|
+
|
|
23
44
|
let config: BinConfig | null = null;
|
|
24
45
|
|
|
25
46
|
export async function getConfig(): Promise<BinConfig> {
|
|
@@ -48,10 +69,8 @@ export async function getConfig(): Promise<BinConfig> {
|
|
|
48
69
|
};
|
|
49
70
|
|
|
50
71
|
if (config.entries)
|
|
51
|
-
config.entries = await Promise.all(config.entries.map(
|
|
52
|
-
else await
|
|
53
|
-
|
|
54
|
-
if (!config.root?.endsWith("/")) config.root = `${config.root ?? ""}/`;
|
|
72
|
+
config.entries = await Promise.all(config.entries.map(reviseConfig));
|
|
73
|
+
else config = await reviseConfig(config);
|
|
55
74
|
|
|
56
75
|
return config;
|
|
57
76
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ContentInjectionTarget } from "../types/ContentInjectionTarget";
|
|
2
|
+
import type { Context } from "../types/Context";
|
|
3
|
+
import type { Page } from "../types/Page";
|
|
4
|
+
|
|
5
|
+
export function getInjectedContent(
|
|
6
|
+
ctx: Context,
|
|
7
|
+
page: Page,
|
|
8
|
+
target: ContentInjectionTarget,
|
|
9
|
+
mode: "append" | undefined = "append",
|
|
10
|
+
) {
|
|
11
|
+
let injectedContent = ctx[mode]?.[target];
|
|
12
|
+
|
|
13
|
+
if (!injectedContent) return "";
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
Array.isArray(injectedContent) ? injectedContent : [injectedContent]
|
|
17
|
+
).reduce((s, item) => {
|
|
18
|
+
if (item === undefined) return s;
|
|
19
|
+
|
|
20
|
+
if (typeof item === "string") return `${s}${s ? "\n" : ""}${item}`;
|
|
21
|
+
|
|
22
|
+
let { content, pages } = item;
|
|
23
|
+
|
|
24
|
+
if (!content || (pages && !pages.includes(page))) return s;
|
|
25
|
+
|
|
26
|
+
return `${s}${s ? "\n" : ""}${content}`;
|
|
27
|
+
}, "");
|
|
28
|
+
}
|
package/src/bin/setContent.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { escapeHTML } from "../utils/escapeHTML";
|
|
|
8
8
|
import { escapeRegExp } from "../utils/escapeRegExp";
|
|
9
9
|
import { getCounterContent } from "./getCounterContent";
|
|
10
10
|
import { getIcon } from "./getIcon";
|
|
11
|
+
import { getInjectedContent } from "./getInjectedContent";
|
|
11
12
|
import { getNav } from "./getNav";
|
|
12
13
|
import { getParsedContent } from "./getParsedContent";
|
|
13
14
|
import { getRepoLink } from "./getRepoLink";
|
|
@@ -65,9 +66,11 @@ export async function setContent(ctx: Context) {
|
|
|
65
66
|
<meta name="viewport" content="width=device-width">
|
|
66
67
|
<meta http-equiv="refresh" content="0; URL=${escapedRedirect}">
|
|
67
68
|
${iconTag}
|
|
69
|
+
${getInjectedContent(ctx, "redirect", "head")}
|
|
68
70
|
</head>
|
|
69
71
|
<body>
|
|
70
72
|
${counterContent}
|
|
73
|
+
${getInjectedContent(ctx, "redirect", "body")}
|
|
71
74
|
<script>window.location.replace("${escapedRedirect}");</script>
|
|
72
75
|
</body>
|
|
73
76
|
</html>
|
|
@@ -112,6 +115,7 @@ ${counterContent}
|
|
|
112
115
|
${iconTag}
|
|
113
116
|
${nav[i + 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i + 1]?.id}">` : ""}
|
|
114
117
|
${nav[i - 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i - 1]?.id}">` : ""}
|
|
118
|
+
${getInjectedContent(ctx, "section", "head")}
|
|
115
119
|
</head>
|
|
116
120
|
<body>
|
|
117
121
|
<div class="layout">
|
|
@@ -150,6 +154,7 @@ ${
|
|
|
150
154
|
: ""
|
|
151
155
|
}
|
|
152
156
|
${counterContent}
|
|
157
|
+
${getInjectedContent(ctx, "section", "body")}
|
|
153
158
|
</body>
|
|
154
159
|
</html>
|
|
155
160
|
`),
|
|
@@ -170,6 +175,7 @@ ${counterContent}
|
|
|
170
175
|
${iconTag}
|
|
171
176
|
<link rel="prefetch" href="${root}start">
|
|
172
177
|
${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
|
|
178
|
+
${getInjectedContent(ctx, "index", "head")}
|
|
173
179
|
</head>
|
|
174
180
|
<body>
|
|
175
181
|
<div class="layout">
|
|
@@ -217,6 +223,7 @@ ${
|
|
|
217
223
|
: ""
|
|
218
224
|
}
|
|
219
225
|
${counterContent}
|
|
226
|
+
${getInjectedContent(ctx, "index", "body")}
|
|
220
227
|
</body>
|
|
221
228
|
</html>
|
|
222
229
|
`),
|
|
@@ -234,6 +241,7 @@ ${counterContent}
|
|
|
234
241
|
<link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
|
|
235
242
|
${iconTag}
|
|
236
243
|
<script>window.location.replace("${root}${contentDir}/${nav[0]?.id}");</script>
|
|
244
|
+
${getInjectedContent(ctx, "start", "head")}
|
|
237
245
|
</head>
|
|
238
246
|
<body>
|
|
239
247
|
<div class="layout">
|
|
@@ -241,6 +249,7 @@ ${counterContent}
|
|
|
241
249
|
</div>
|
|
242
250
|
|
|
243
251
|
${counterContent}
|
|
252
|
+
${getInjectedContent(ctx, "start", "body")}
|
|
244
253
|
</body>
|
|
245
254
|
</html>
|
|
246
255
|
`),
|
package/src/bin/toFileContent.ts
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ContentInjectionTarget } from "./ContentInjectionTarget";
|
|
2
|
+
import type { Page } from "./Page";
|
|
3
|
+
|
|
4
|
+
type InjectedContent =
|
|
5
|
+
| string
|
|
6
|
+
| undefined
|
|
7
|
+
| {
|
|
8
|
+
content?: string | undefined;
|
|
9
|
+
pages?: Page[];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type ContentInjectionMap<T extends ContentInjectionTarget> = Partial<
|
|
13
|
+
Record<T, InjectedContent | InjectedContent[]>
|
|
14
|
+
>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ContentInjectionTarget = "head" | "body";
|
package/src/types/EntryConfig.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ContentInjectionMap } from "./ContentInjectionMap";
|
|
1
2
|
import type { Theme } from "./Theme";
|
|
2
3
|
|
|
3
4
|
export type EntryConfig = {
|
|
@@ -58,4 +59,5 @@ export type EntryConfig = {
|
|
|
58
59
|
*/
|
|
59
60
|
jsorg?: boolean | string;
|
|
60
61
|
ymid?: number | string;
|
|
62
|
+
append?: ContentInjectionMap<"head" | "body">;
|
|
61
63
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Page = "index" | "start" | "section" | "redirect";
|