@t8/docsgen 0.1.3 → 0.1.5

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 CHANGED
@@ -225,6 +225,27 @@ ym(${ymid}, "init", {clickmap: true, trackLinks: true, accurateTrackBounce: true
225
225
  `.trim();
226
226
  }
227
227
 
228
+ // src/bin/getIcon.ts
229
+ var iconTypeMap = {
230
+ ico: "image/x-icon",
231
+ svg: "image/svg+xml",
232
+ png: "image/png",
233
+ gif: "image/gif",
234
+ jpg: "image/jpeg",
235
+ jpeg: "image/jpeg"
236
+ };
237
+ function getIcon({ favicon, faviconType }) {
238
+ let icon = {
239
+ url: favicon,
240
+ type: faviconType
241
+ };
242
+ if (icon.url && !icon.type) {
243
+ let ext = icon.url.split("/").at(-1)?.split(".").at(-1)?.toLowerCase();
244
+ if (ext) icon.type = iconTypeMap[ext];
245
+ }
246
+ return icon;
247
+ }
248
+
228
249
  // src/bin/getNav.ts
229
250
  var import_jsdom = require("jsdom");
230
251
 
@@ -269,19 +290,22 @@ async function getNav(ctx, navItems) {
269
290
  }
270
291
  }
271
292
  if (!s && !navContent) return "";
272
- let repoLink = getRepoLink(ctx);
273
293
  s = s.trim() ? `<section><ul>${s}
274
294
  </ul></section>` : "";
275
- s = `${s}
295
+ let repoLink = getRepoLink(ctx);
296
+ let refContent = "";
297
+ if (repoLink || backstory)
298
+ refContent = `
276
299
  <section class="ref">
277
300
  <ul>
278
- <li>${repoLink}</li>
301
+ ${repoLink ? `<li>${repoLink}</li>` : ""}
279
302
  ${backstory ? `<li><a href="${backstory}">Backstory</a></li>` : ""}
280
303
  </ul>
281
304
  </section>
282
- ${navContent}`;
305
+ `;
283
306
  return `<nav>
284
- ${s}
307
+ ${s}${refContent}
308
+ ${navContent}
285
309
  </nav>`;
286
310
  }
287
311
 
@@ -300,6 +324,16 @@ function getSlug(title) {
300
324
  return slug;
301
325
  }
302
326
 
327
+ // src/bin/getSource.ts
328
+ function getSource(ctx) {
329
+ let { source, repo, mainBranch = "main" } = ctx;
330
+ if (source) return source;
331
+ let ghId = repo?.startsWith("https://github.com/") ? repo.replace("https://github.com/", "").split("/").slice(0, 2).join("/") : "";
332
+ if (ghId)
333
+ return `https://raw.githubusercontent.com/${ghId}/refs/heads/${mainBranch}/README.md`;
334
+ return "README.md";
335
+ }
336
+
303
337
  // src/bin/getParsedContent.ts
304
338
  var md = new import_markdown_it.default({
305
339
  html: true
@@ -370,8 +404,8 @@ function getSectionPostprocess(linkMap) {
370
404
  };
371
405
  }
372
406
  async function getParsedContent(ctx) {
373
- let { source = "README.md", singlePage } = ctx;
374
- let content = md.render(await fetchText(source));
407
+ let { singlePage } = ctx;
408
+ let content = md.render(await fetchText(getSource(ctx)));
375
409
  let dom = new import_jsdom2.JSDOM(content);
376
410
  let { nav, linkMap } = buildNav(ctx, dom);
377
411
  let badges = [];
@@ -433,13 +467,12 @@ async function getParsedContent(ctx) {
433
467
 
434
468
  // src/bin/getTitle.ts
435
469
  function getTitle(ctx, { cover, originalContent, withPackageURL } = {}) {
436
- let { root, name, title: packageTitle, scope, theme } = ctx;
470
+ let { root, name, title: packageTitle, htmlTitle, scope } = ctx;
437
471
  if (originalContent && ![name, packageTitle].includes(originalContent.trim()))
438
472
  return originalContent;
473
+ if (cover && htmlTitle) return htmlTitle;
439
474
  if (packageTitle) {
440
475
  let escapedTitle = escapeHTML(packageTitle);
441
- if (cover && theme === "t8" && packageTitle.startsWith("T8 "))
442
- return `<a href="/">T8</a> <span class="name">${packageTitle.replace(/^T8 /, "")}</span>`;
443
476
  return withPackageURL ? `<a href="${root}" class="name">${escapedTitle}</a>` : `<span class="name">${escapedTitle}</span>`;
444
477
  }
445
478
  let scopeMatches = name?.match(/^(@[^/]+)\/?(.*)/);
@@ -479,18 +512,11 @@ async function setContent(ctx) {
479
512
  let packageVersion = (await exec(`npm view ${packageName} version`)).stdout.trim().split(".").slice(0, 2).join(".");
480
513
  let packageUrl = `https://unpkg.com/${packageName}@${packageVersion}`;
481
514
  let rootAttrs = "";
482
- let icon = {
483
- url: `${root}favicon.svg`,
484
- type: "image/svg+xml"
485
- };
486
515
  if (theme) rootAttrs += ` data-theme="${escapeHTML(theme)}"`;
487
516
  if (colorScheme)
488
517
  rootAttrs += ` style="--color-scheme: ${escapeHTML(colorScheme)}"`;
489
- if (theme === "t8")
490
- icon = {
491
- url: "/assets/t8.png",
492
- type: "image/png"
493
- };
518
+ let icon = getIcon(ctx);
519
+ let iconTag = icon.url ? `<link rel="icon"${icon.type ? ` type="${icon.type}"` : ""} href="${icon.url}">` : "";
494
520
  if (redirect) {
495
521
  let escapedRedirect = escapeHTML(redirect);
496
522
  await (0, import_promises4.writeFile)(
@@ -502,6 +528,7 @@ async function setContent(ctx) {
502
528
  <meta charset="utf-8">
503
529
  <meta name="viewport" content="width=device-width">
504
530
  <meta http-equiv="refresh" content="0; URL=${escapedRedirect}">
531
+ ${iconTag}
505
532
  </head>
506
533
  <body>
507
534
  ${counterContent}
@@ -533,14 +560,14 @@ ${counterContent}
533
560
  <!DOCTYPE html>
534
561
  <html lang="en"${rootAttrs}>
535
562
  <head>
536
- <meta charset="utf-8">
537
- <meta name="viewport" content="width=device-width, initial-scale=1">
538
- <title>${escapeHTML(nav[i]?.title)} | ${escapedTitle}</title>
539
- <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
540
- <link rel="stylesheet" href="${packageUrl}/dist/css/section.css">
541
- <link rel="icon" type="${icon.type}" href="${icon.url}">
542
- ${nav[i + 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i + 1]?.id}">` : ""}
543
- ${nav[i - 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i - 1]?.id}">` : ""}
563
+ <meta charset="utf-8">
564
+ <meta name="viewport" content="width=device-width, initial-scale=1">
565
+ <title>${escapeHTML(nav[i]?.title)} | ${escapedTitle}</title>
566
+ <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
567
+ <link rel="stylesheet" href="${packageUrl}/dist/css/section.css">
568
+ ${iconTag}
569
+ ${nav[i + 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i + 1]?.id}">` : ""}
570
+ ${nav[i - 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i - 1]?.id}">` : ""}
544
571
  </head>
545
572
  <body>
546
573
  <div class="layout">
@@ -586,14 +613,14 @@ ${counterContent}
586
613
  <!DOCTYPE html>
587
614
  <html lang="en"${rootAttrs}>
588
615
  <head>
589
- <meta charset="utf-8">
590
- <meta name="viewport" content="width=device-width, initial-scale=1">
591
- <title>${escapedTitle}${packageDescription ? ` | ${escapeHTML(packageDescription)}` : ""}</title>
592
- <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
593
- <link rel="stylesheet" href="${packageUrl}/dist/css/index.css">
594
- <link rel="icon" type="${icon.type}" href="${icon.url}">
595
- <link rel="prefetch" href="${root}start">
596
- ${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
616
+ <meta charset="utf-8">
617
+ <meta name="viewport" content="width=device-width, initial-scale=1">
618
+ <title>${escapedTitle}${packageDescription ? ` | ${escapeHTML(packageDescription)}` : ""}</title>
619
+ <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
620
+ <link rel="stylesheet" href="${packageUrl}/dist/css/index.css">
621
+ ${iconTag}
622
+ <link rel="prefetch" href="${root}start">
623
+ ${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
597
624
  </head>
598
625
  <body>
599
626
  <div class="layout">
@@ -647,7 +674,7 @@ ${counterContent}
647
674
  <meta http-equiv="refresh" content="0; URL=${root}${contentDir}/${nav[0]?.id}">
648
675
  <title>${escapedTitle}</title>
649
676
  <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
650
- <link rel="icon" type="${icon.type}" href="${icon.url}">
677
+ ${iconTag}
651
678
  <script>window.location.replace("${root}${contentDir}/${nav[0]?.id}");</script>
652
679
  </head>
653
680
  <body>
@@ -667,8 +694,8 @@ ${counterContent}
667
694
  var import_promises5 = require("node:fs/promises");
668
695
  var import_node_path4 = require("node:path");
669
696
 
670
- // src/utils/getIcon.ts
671
- function getIcon(baseColor = "gray") {
697
+ // src/utils/getIconContent.ts
698
+ function getIconContent(baseColor = "gray") {
672
699
  return `
673
700
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
674
701
  <style>.b{fill:${baseColor};}.c0{fill:oklch(from ${baseColor} calc(100*(.78 - l)) 0 0 / .5);}.c1{fill:oklch(from ${baseColor} calc(100*(.78 - l)) 0 0 / .3);}.c2{fill:none;}</style>
@@ -685,8 +712,11 @@ function getIcon(baseColor = "gray") {
685
712
  // src/bin/setImages.ts
686
713
  async function setImages({ dir = "", colorScheme, favicon }) {
687
714
  if (favicon) return;
688
- await (0, import_promises5.writeFile)((0, import_node_path4.join)(dir, "./favicon.svg"), `${getIcon(colorScheme)}
689
- `);
715
+ await (0, import_promises5.writeFile)(
716
+ (0, import_node_path4.join)(dir, "./favicon.svg"),
717
+ `${getIconContent(colorScheme)}
718
+ `
719
+ );
690
720
  }
691
721
 
692
722
  // src/bin/createFiles.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t8/docsgen",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "",
5
5
  "main": "dist/bin.js",
6
6
  "bin": {
@@ -0,0 +1,30 @@
1
+ import type { Context } from "../types/Context";
2
+
3
+ const iconTypeMap: Record<string, string> = {
4
+ ico: "image/x-icon",
5
+ svg: "image/svg+xml",
6
+ png: "image/png",
7
+ gif: "image/gif",
8
+ jpg: "image/jpeg",
9
+ jpeg: "image/jpeg",
10
+ };
11
+
12
+ type Icon = {
13
+ url?: string | undefined;
14
+ type?: string | undefined;
15
+ };
16
+
17
+ export function getIcon({ favicon, faviconType }: Context) {
18
+ let icon: Icon = {
19
+ url: favicon,
20
+ type: faviconType,
21
+ };
22
+
23
+ if (icon.url && !icon.type) {
24
+ let ext = icon.url.split("/").at(-1)?.split(".").at(-1)?.toLowerCase();
25
+
26
+ if (ext) icon.type = iconTypeMap[ext];
27
+ }
28
+
29
+ return icon;
30
+ }
package/src/bin/getNav.ts CHANGED
@@ -48,17 +48,20 @@ export async function getNav(ctx: Context, navItems: NavItem[]) {
48
48
 
49
49
  if (!s && !navContent) return "";
50
50
 
51
+ s = s.trim() ? `<section><ul>${s}\n</ul></section>` : "";
52
+
51
53
  let repoLink = getRepoLink(ctx);
54
+ let refContent = "";
52
55
 
53
- s = s.trim() ? `<section><ul>${s}\n</ul></section>` : "";
54
- s = `${s}
56
+ if (repoLink || backstory)
57
+ refContent = `
55
58
  <section class="ref">
56
59
  <ul>
57
- <li>${repoLink}</li>
60
+ ${repoLink ? `<li>${repoLink}</li>` : ""}
58
61
  ${backstory ? `<li><a href="${backstory}">Backstory</a></li>` : ""}
59
62
  </ul>
60
63
  </section>
61
- ${navContent}`;
64
+ `;
62
65
 
63
- return `<nav>\n${s}\n</nav>`;
66
+ return `<nav>\n${s}${refContent}\n${navContent}\n</nav>`;
64
67
  }
@@ -4,6 +4,7 @@ import type { Context } from "../types/Context";
4
4
  import type { NavItem } from "../types/NavItem";
5
5
  import { fetchText } from "./fetchText";
6
6
  import { getSlug } from "./getSlug";
7
+ import { getSource } from "./getSource";
7
8
 
8
9
  const md = new Markdown({
9
10
  html: true,
@@ -103,8 +104,8 @@ function getSectionPostprocess(linkMap: Record<string, string>) {
103
104
  }
104
105
 
105
106
  export async function getParsedContent(ctx: Context) {
106
- let { source = "README.md", singlePage } = ctx;
107
- let content = md.render(await fetchText(source));
107
+ let { singlePage } = ctx;
108
+ let content = md.render(await fetchText(getSource(ctx)));
108
109
  let dom = new JSDOM(content);
109
110
 
110
111
  let { nav, linkMap } = buildNav(ctx, dom);
@@ -0,0 +1,16 @@
1
+ import type { Context } from "../types/Context";
2
+
3
+ export function getSource(ctx: Context) {
4
+ let { source, repo, mainBranch = "main" } = ctx;
5
+
6
+ if (source) return source;
7
+
8
+ let ghId = repo?.startsWith("https://github.com/")
9
+ ? repo.replace("https://github.com/", "").split("/").slice(0, 2).join("/")
10
+ : "";
11
+
12
+ if (ghId)
13
+ return `https://raw.githubusercontent.com/${ghId}/refs/heads/${mainBranch}/README.md`;
14
+
15
+ return "README.md";
16
+ }
@@ -11,17 +11,16 @@ export function getTitle(
11
11
  ctx: Context,
12
12
  { cover, originalContent, withPackageURL }: GetTitleParams = {},
13
13
  ) {
14
- let { root, name, title: packageTitle, scope, theme } = ctx;
14
+ let { root, name, title: packageTitle, htmlTitle, scope } = ctx;
15
15
 
16
16
  if (originalContent && ![name, packageTitle].includes(originalContent.trim()))
17
17
  return originalContent;
18
18
 
19
+ if (cover && htmlTitle) return htmlTitle;
20
+
19
21
  if (packageTitle) {
20
22
  let escapedTitle = escapeHTML(packageTitle);
21
23
 
22
- if (cover && theme === "t8" && packageTitle.startsWith("T8 "))
23
- return `<a href="/">T8</a> <span class="name">${packageTitle.replace(/^T8 /, "")}</span>`;
24
-
25
24
  return withPackageURL
26
25
  ? `<a href="${root}" class="name">${escapedTitle}</a>`
27
26
  : `<span class="name">${escapedTitle}</span>`;
@@ -7,6 +7,7 @@ import type { Context } from "../types/Context";
7
7
  import { escapeHTML } from "../utils/escapeHTML";
8
8
  import { escapeRegExp } from "../utils/escapeRegExp";
9
9
  import { getCounterContent } from "./getCounterContent";
10
+ import { getIcon } from "./getIcon";
10
11
  import { getNav } from "./getNav";
11
12
  import { getParsedContent } from "./getParsedContent";
12
13
  import { getRepoLink } from "./getRepoLink";
@@ -42,21 +43,15 @@ export async function setContent(ctx: Context) {
42
43
  let packageUrl = `https://unpkg.com/${packageName}@${packageVersion}`;
43
44
  let rootAttrs = "";
44
45
 
45
- let icon = {
46
- url: `${root}favicon.svg`,
47
- type: "image/svg+xml",
48
- };
49
-
50
46
  if (theme) rootAttrs += ` data-theme="${escapeHTML(theme)}"`;
51
47
 
52
48
  if (colorScheme)
53
49
  rootAttrs += ` style="--color-scheme: ${escapeHTML(colorScheme)}"`;
54
50
 
55
- if (theme === "t8")
56
- icon = {
57
- url: "/assets/t8.png",
58
- type: "image/png",
59
- };
51
+ let icon = getIcon(ctx);
52
+ let iconTag = icon.url
53
+ ? `<link rel="icon"${icon.type ? ` type="${icon.type}"` : ""} href="${icon.url}">`
54
+ : "";
60
55
 
61
56
  if (redirect) {
62
57
  let escapedRedirect = escapeHTML(redirect);
@@ -70,6 +65,7 @@ export async function setContent(ctx: Context) {
70
65
  <meta charset="utf-8">
71
66
  <meta name="viewport" content="width=device-width">
72
67
  <meta http-equiv="refresh" content="0; URL=${escapedRedirect}">
68
+ ${iconTag}
73
69
  </head>
74
70
  <body>
75
71
  ${counterContent}
@@ -108,14 +104,14 @@ ${counterContent}
108
104
  <!DOCTYPE html>
109
105
  <html lang="en"${rootAttrs}>
110
106
  <head>
111
- <meta charset="utf-8">
112
- <meta name="viewport" content="width=device-width, initial-scale=1">
113
- <title>${escapeHTML(nav[i]?.title)} | ${escapedTitle}</title>
114
- <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
115
- <link rel="stylesheet" href="${packageUrl}/dist/css/section.css">
116
- <link rel="icon" type="${icon.type}" href="${icon.url}">
117
- ${nav[i + 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i + 1]?.id}">` : ""}
118
- ${nav[i - 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i - 1]?.id}">` : ""}
107
+ <meta charset="utf-8">
108
+ <meta name="viewport" content="width=device-width, initial-scale=1">
109
+ <title>${escapeHTML(nav[i]?.title)} | ${escapedTitle}</title>
110
+ <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
111
+ <link rel="stylesheet" href="${packageUrl}/dist/css/section.css">
112
+ ${iconTag}
113
+ ${nav[i + 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i + 1]?.id}">` : ""}
114
+ ${nav[i - 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i - 1]?.id}">` : ""}
119
115
  </head>
120
116
  <body>
121
117
  <div class="layout">
@@ -165,14 +161,14 @@ ${counterContent}
165
161
  <!DOCTYPE html>
166
162
  <html lang="en"${rootAttrs}>
167
163
  <head>
168
- <meta charset="utf-8">
169
- <meta name="viewport" content="width=device-width, initial-scale=1">
170
- <title>${escapedTitle}${packageDescription ? ` | ${escapeHTML(packageDescription)}` : ""}</title>
171
- <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
172
- <link rel="stylesheet" href="${packageUrl}/dist/css/index.css">
173
- <link rel="icon" type="${icon.type}" href="${icon.url}">
174
- <link rel="prefetch" href="${root}start">
175
- ${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
164
+ <meta charset="utf-8">
165
+ <meta name="viewport" content="width=device-width, initial-scale=1">
166
+ <title>${escapedTitle}${packageDescription ? ` | ${escapeHTML(packageDescription)}` : ""}</title>
167
+ <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
168
+ <link rel="stylesheet" href="${packageUrl}/dist/css/index.css">
169
+ ${iconTag}
170
+ <link rel="prefetch" href="${root}start">
171
+ ${nav[0] ? `<link rel="prefetch" href="${root}${contentDir}/${nav[0]?.id ?? ""}">` : ""}
176
172
  </head>
177
173
  <body>
178
174
  <div class="layout">
@@ -234,7 +230,7 @@ ${counterContent}
234
230
  <meta http-equiv="refresh" content="0; URL=${root}${contentDir}/${nav[0]?.id}">
235
231
  <title>${escapedTitle}</title>
236
232
  <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
237
- <link rel="icon" type="${icon.type}" href="${icon.url}">
233
+ ${iconTag}
238
234
  <script>window.location.replace("${root}${contentDir}/${nav[0]?.id}");</script>
239
235
  </head>
240
236
  <body>
@@ -1,10 +1,13 @@
1
1
  import { writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import type { Context } from "../types/Context";
4
- import { getIcon } from "../utils/getIcon";
4
+ import { getIconContent } from "../utils/getIconContent";
5
5
 
6
6
  export async function setImages({ dir = "", colorScheme, favicon }: Context) {
7
7
  if (favicon) return;
8
8
 
9
- await writeFile(join(dir, "./favicon.svg"), `${getIcon(colorScheme)}\n`);
9
+ await writeFile(
10
+ join(dir, "./favicon.svg"),
11
+ `${getIconContent(colorScheme)}\n`,
12
+ );
10
13
  }
@@ -8,6 +8,7 @@ export type EntryConfig = {
8
8
  theme?: Theme;
9
9
  name?: string;
10
10
  title?: string;
11
+ htmlTitle?: string;
11
12
  description?: string;
12
13
  version?: string;
13
14
  repo?: string;
@@ -39,6 +40,7 @@ export type EntryConfig = {
39
40
  nav?: string;
40
41
  /** Favicon URL. */
41
42
  favicon?: string;
43
+ faviconType?: string;
42
44
  /** Scope URL. */
43
45
  scope?: string;
44
46
  /** Redirection URL. */
@@ -1,4 +1,4 @@
1
- export function getIcon(baseColor = "gray") {
1
+ export function getIconContent(baseColor = "gray") {
2
2
  return `
3
3
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
4
4
  <style>.b{fill:${baseColor};}.c0{fill:oklch(from ${baseColor} calc(100*(.78 - l)) 0 0 / .5);}.c1{fill:oklch(from ${baseColor} calc(100*(.78 - l)) 0 0 / .3);}.c2{fill:none;}</style>