@t8/docsgen 0.1.4 → 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
 
@@ -303,6 +324,16 @@ function getSlug(title) {
303
324
  return slug;
304
325
  }
305
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
+
306
337
  // src/bin/getParsedContent.ts
307
338
  var md = new import_markdown_it.default({
308
339
  html: true
@@ -373,8 +404,8 @@ function getSectionPostprocess(linkMap) {
373
404
  };
374
405
  }
375
406
  async function getParsedContent(ctx) {
376
- let { source = "README.md", singlePage } = ctx;
377
- let content = md.render(await fetchText(source));
407
+ let { singlePage } = ctx;
408
+ let content = md.render(await fetchText(getSource(ctx)));
378
409
  let dom = new import_jsdom2.JSDOM(content);
379
410
  let { nav, linkMap } = buildNav(ctx, dom);
380
411
  let badges = [];
@@ -436,13 +467,12 @@ async function getParsedContent(ctx) {
436
467
 
437
468
  // src/bin/getTitle.ts
438
469
  function getTitle(ctx, { cover, originalContent, withPackageURL } = {}) {
439
- let { root, name, title: packageTitle, scope, theme } = ctx;
470
+ let { root, name, title: packageTitle, htmlTitle, scope } = ctx;
440
471
  if (originalContent && ![name, packageTitle].includes(originalContent.trim()))
441
472
  return originalContent;
473
+ if (cover && htmlTitle) return htmlTitle;
442
474
  if (packageTitle) {
443
475
  let escapedTitle = escapeHTML(packageTitle);
444
- if (cover && theme === "t8" && packageTitle.startsWith("T8 "))
445
- return `<a href="/">T8</a> <span class="name">${packageTitle.replace(/^T8 /, "")}</span>`;
446
476
  return withPackageURL ? `<a href="${root}" class="name">${escapedTitle}</a>` : `<span class="name">${escapedTitle}</span>`;
447
477
  }
448
478
  let scopeMatches = name?.match(/^(@[^/]+)\/?(.*)/);
@@ -482,18 +512,11 @@ async function setContent(ctx) {
482
512
  let packageVersion = (await exec(`npm view ${packageName} version`)).stdout.trim().split(".").slice(0, 2).join(".");
483
513
  let packageUrl = `https://unpkg.com/${packageName}@${packageVersion}`;
484
514
  let rootAttrs = "";
485
- let icon = {
486
- url: `${root}favicon.svg`,
487
- type: "image/svg+xml"
488
- };
489
515
  if (theme) rootAttrs += ` data-theme="${escapeHTML(theme)}"`;
490
516
  if (colorScheme)
491
517
  rootAttrs += ` style="--color-scheme: ${escapeHTML(colorScheme)}"`;
492
- if (theme === "t8")
493
- icon = {
494
- url: "/assets/t8.png",
495
- type: "image/png"
496
- };
518
+ let icon = getIcon(ctx);
519
+ let iconTag = icon.url ? `<link rel="icon"${icon.type ? ` type="${icon.type}"` : ""} href="${icon.url}">` : "";
497
520
  if (redirect) {
498
521
  let escapedRedirect = escapeHTML(redirect);
499
522
  await (0, import_promises4.writeFile)(
@@ -505,6 +528,7 @@ async function setContent(ctx) {
505
528
  <meta charset="utf-8">
506
529
  <meta name="viewport" content="width=device-width">
507
530
  <meta http-equiv="refresh" content="0; URL=${escapedRedirect}">
531
+ ${iconTag}
508
532
  </head>
509
533
  <body>
510
534
  ${counterContent}
@@ -536,14 +560,14 @@ ${counterContent}
536
560
  <!DOCTYPE html>
537
561
  <html lang="en"${rootAttrs}>
538
562
  <head>
539
- <meta charset="utf-8">
540
- <meta name="viewport" content="width=device-width, initial-scale=1">
541
- <title>${escapeHTML(nav[i]?.title)} | ${escapedTitle}</title>
542
- <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
543
- <link rel="stylesheet" href="${packageUrl}/dist/css/section.css">
544
- <link rel="icon" type="${icon.type}" href="${icon.url}">
545
- ${nav[i + 1]?.id ? `<link rel="prefetch" href="${root}${contentDir}/${nav[i + 1]?.id}">` : ""}
546
- ${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}">` : ""}
547
571
  </head>
548
572
  <body>
549
573
  <div class="layout">
@@ -589,14 +613,14 @@ ${counterContent}
589
613
  <!DOCTYPE html>
590
614
  <html lang="en"${rootAttrs}>
591
615
  <head>
592
- <meta charset="utf-8">
593
- <meta name="viewport" content="width=device-width, initial-scale=1">
594
- <title>${escapedTitle}${packageDescription ? ` | ${escapeHTML(packageDescription)}` : ""}</title>
595
- <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
596
- <link rel="stylesheet" href="${packageUrl}/dist/css/index.css">
597
- <link rel="icon" type="${icon.type}" href="${icon.url}">
598
- <link rel="prefetch" href="${root}start">
599
- ${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 ?? ""}">` : ""}
600
624
  </head>
601
625
  <body>
602
626
  <div class="layout">
@@ -650,7 +674,7 @@ ${counterContent}
650
674
  <meta http-equiv="refresh" content="0; URL=${root}${contentDir}/${nav[0]?.id}">
651
675
  <title>${escapedTitle}</title>
652
676
  <link rel="stylesheet" href="${packageUrl}/dist/css/base.css">
653
- <link rel="icon" type="${icon.type}" href="${icon.url}">
677
+ ${iconTag}
654
678
  <script>window.location.replace("${root}${contentDir}/${nav[0]?.id}");</script>
655
679
  </head>
656
680
  <body>
@@ -670,8 +694,8 @@ ${counterContent}
670
694
  var import_promises5 = require("node:fs/promises");
671
695
  var import_node_path4 = require("node:path");
672
696
 
673
- // src/utils/getIcon.ts
674
- function getIcon(baseColor = "gray") {
697
+ // src/utils/getIconContent.ts
698
+ function getIconContent(baseColor = "gray") {
675
699
  return `
676
700
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
677
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>
@@ -688,8 +712,11 @@ function getIcon(baseColor = "gray") {
688
712
  // src/bin/setImages.ts
689
713
  async function setImages({ dir = "", colorScheme, favicon }) {
690
714
  if (favicon) return;
691
- await (0, import_promises5.writeFile)((0, import_node_path4.join)(dir, "./favicon.svg"), `${getIcon(colorScheme)}
692
- `);
715
+ await (0, import_promises5.writeFile)(
716
+ (0, import_node_path4.join)(dir, "./favicon.svg"),
717
+ `${getIconContent(colorScheme)}
718
+ `
719
+ );
693
720
  }
694
721
 
695
722
  // src/bin/createFiles.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t8/docsgen",
3
- "version": "0.1.4",
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
+ }
@@ -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>