radiant-docs 0.1.34 → 0.1.38
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/package.json +1 -1
- package/template/astro.config.mjs +27 -0
- package/template/package-lock.json +1027 -513
- package/template/package.json +3 -2
- package/template/scripts/generate-proxy-allowed-origins.mjs +217 -0
- package/template/scripts/generate-robots-txt.mjs +19 -0
- package/template/scripts/stamp-image-versions.mjs +63 -11
- package/template/src/components/Footer.astro +1 -1
- package/template/src/components/Header.astro +9 -9
- package/template/src/components/LogoLink.astro +2 -1
- package/template/src/components/OpenApiPage.astro +18 -18
- package/template/src/components/Search.astro +18 -18
- package/template/src/components/Sidebar.astro +4 -2
- package/template/src/components/SidebarDropdown.astro +82 -79
- package/template/src/components/SidebarGroup.astro +3 -0
- package/template/src/components/SidebarMenu.astro +14 -1
- package/template/src/components/SidebarSegmented.astro +5 -5
- package/template/src/components/SidebarSubgroup.astro +35 -12
- package/template/src/components/TableOfContents.astro +24 -15
- package/template/src/components/ThemeSwitcher.astro +15 -8
- package/template/src/components/chat/AskAiWidget.tsx +10 -5
- package/template/src/components/endpoint/PlaygroundBar.astro +3 -3
- package/template/src/components/endpoint/PlaygroundButton.astro +3 -3
- package/template/src/components/endpoint/PlaygroundField.astro +53 -53
- package/template/src/components/endpoint/PlaygroundForm.astro +51 -37
- package/template/src/components/endpoint/RequestSnippets.astro +54 -21
- package/template/src/components/endpoint/ResponseDisplay.astro +24 -24
- package/template/src/components/endpoint/ResponseFieldTree.astro +12 -12
- package/template/src/components/endpoint/ResponseFields.astro +19 -19
- package/template/src/components/endpoint/ResponseSnippets.astro +66 -29
- package/template/src/components/sidebar/SidebarEndpointLink.astro +18 -15
- package/template/src/components/sidebar/SidebarOpenApiPageLink.astro +56 -0
- package/template/src/components/ui/CodeTabEdge.astro +6 -4
- package/template/src/components/ui/Field.astro +7 -7
- package/template/src/components/ui/Icon.astro +2 -1
- package/template/src/components/ui/demo/Demo.astro +1 -1
- package/template/src/components/user/Accordion.astro +3 -3
- package/template/src/components/user/Callout.astro +8 -8
- package/template/src/components/user/CodeBlock.astro +57 -22
- package/template/src/components/user/CodeGroup.astro +14 -10
- package/template/src/components/user/ComponentPreviewBlock.astro +38 -12
- package/template/src/components/user/Image.astro +6 -2
- package/template/src/components/user/Step.astro +4 -4
- package/template/src/components/user/Tab.astro +1 -1
- package/template/src/components/user/Tabs.astro +15 -20
- package/template/src/layouts/Layout.astro +9 -4
- package/template/src/lib/code/code-block.ts +150 -15
- package/template/src/lib/mdx/remark-resolve-internal-links.ts +639 -0
- package/template/src/lib/pagefind.ts +2 -1
- package/template/src/lib/routes.ts +134 -58
- package/template/src/lib/static-asset-url.ts +62 -0
- package/template/src/lib/utils.ts +48 -0
- package/template/src/lib/validation.ts +115 -27
- package/template/src/pages/404.astro +44 -0
- package/template/src/styles/global.css +28 -19
- package/template/scripts/rewrite-static-asset-host.mjs +0 -408
|
@@ -137,7 +137,9 @@ const CODE_BLOCK_LANGUAGE_ICON_FILE_BY_VALUE: Record<string, string> = {
|
|
|
137
137
|
yaml: "file_type_yaml_official.svg",
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
-
const
|
|
140
|
+
const SHIKI_LIGHT_THEME = "github-light";
|
|
141
|
+
const SHIKI_DARK_THEME = "github-dark";
|
|
142
|
+
const SHIKI_THEMES = [SHIKI_LIGHT_THEME, SHIKI_DARK_THEME] as const;
|
|
141
143
|
const BUNDLED_LANGUAGE_SET = new Set(Object.keys(bundledLanguages));
|
|
142
144
|
const LANGUAGE_RUNTIME_DEPENDENCIES: Record<string, string[]> = {
|
|
143
145
|
// MDX tokenization relies on TSX grammar injections for JSX-style tags.
|
|
@@ -228,7 +230,7 @@ function pickIconFromFileName(fileName: string): string | null {
|
|
|
228
230
|
const candidates = uniqueValues([trimmedFileName, trimmedFileName.toLowerCase()]);
|
|
229
231
|
for (const candidate of candidates) {
|
|
230
232
|
const iconFileName = getIconForFile(candidate);
|
|
231
|
-
if (iconFileName !== DEFAULT_FILE) return iconFileName;
|
|
233
|
+
if (iconFileName && iconFileName !== DEFAULT_FILE) return iconFileName;
|
|
232
234
|
}
|
|
233
235
|
|
|
234
236
|
return null;
|
|
@@ -372,7 +374,7 @@ function namespaceSvgIds(svg: string, namespace: string): string {
|
|
|
372
374
|
async function getHighlighter() {
|
|
373
375
|
if (!highlighterPromise) {
|
|
374
376
|
highlighterPromise = getSingletonHighlighter({
|
|
375
|
-
themes: [
|
|
377
|
+
themes: [...SHIKI_THEMES],
|
|
376
378
|
langs: [DEFAULT_CODE_BLOCK_LANGUAGE],
|
|
377
379
|
});
|
|
378
380
|
}
|
|
@@ -414,7 +416,7 @@ async function ensureLanguageLoaded(
|
|
|
414
416
|
}
|
|
415
417
|
|
|
416
418
|
const loadPromise = highlighter
|
|
417
|
-
.loadLanguage(language)
|
|
419
|
+
.loadLanguage(language as keyof typeof bundledLanguages)
|
|
418
420
|
.then(() => {
|
|
419
421
|
loadedLanguageSet.add(language);
|
|
420
422
|
})
|
|
@@ -493,7 +495,7 @@ export async function getCodeLineTokens({
|
|
|
493
495
|
language: string;
|
|
494
496
|
}): Promise<{
|
|
495
497
|
normalizedLanguage: string;
|
|
496
|
-
lines:
|
|
498
|
+
lines: CodeLineToken[][];
|
|
497
499
|
}> {
|
|
498
500
|
const highlighter = await getHighlighter();
|
|
499
501
|
const normalizedLanguage = normalizeCodeLanguageValue(language);
|
|
@@ -523,24 +525,157 @@ export async function getCodeLineTokens({
|
|
|
523
525
|
}
|
|
524
526
|
|
|
525
527
|
try {
|
|
526
|
-
const
|
|
527
|
-
lang: targetLanguage,
|
|
528
|
-
theme: SHIKI_THEME,
|
|
529
|
-
});
|
|
528
|
+
const themedTokenLines = getThemedTokenLines(highlighter, code, targetLanguage);
|
|
530
529
|
|
|
531
530
|
return {
|
|
532
531
|
normalizedLanguage: targetLanguage,
|
|
533
|
-
lines:
|
|
532
|
+
lines: mergeTokenLines(themedTokenLines.light, themedTokenLines.dark),
|
|
534
533
|
};
|
|
535
534
|
} catch {
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
535
|
+
const themedTokenLines = getThemedTokenLines(
|
|
536
|
+
highlighter,
|
|
537
|
+
code,
|
|
538
|
+
DEFAULT_CODE_BLOCK_LANGUAGE,
|
|
539
|
+
);
|
|
540
540
|
|
|
541
541
|
return {
|
|
542
542
|
normalizedLanguage: DEFAULT_CODE_BLOCK_LANGUAGE,
|
|
543
|
-
lines:
|
|
543
|
+
lines: mergeTokenLines(themedTokenLines.light, themedTokenLines.dark),
|
|
544
544
|
};
|
|
545
545
|
}
|
|
546
546
|
}
|
|
547
|
+
|
|
548
|
+
export type CodeLineToken = {
|
|
549
|
+
content: string;
|
|
550
|
+
color?: string;
|
|
551
|
+
darkColor?: string;
|
|
552
|
+
bgColor?: string;
|
|
553
|
+
darkBgColor?: string;
|
|
554
|
+
fontStyle?: number;
|
|
555
|
+
htmlStyle?: Record<string, string>;
|
|
556
|
+
darkHtmlStyle?: Record<string, string>;
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
function getThemedTokenLines(
|
|
560
|
+
highlighter: Awaited<ReturnType<typeof getSingletonHighlighter>>,
|
|
561
|
+
code: string,
|
|
562
|
+
lang: string,
|
|
563
|
+
): {
|
|
564
|
+
light: ThemedToken[][];
|
|
565
|
+
dark: ThemedToken[][];
|
|
566
|
+
} {
|
|
567
|
+
const shikiLanguage = lang as keyof typeof bundledLanguages;
|
|
568
|
+
const lightTokenResult = highlighter.codeToTokens(code, {
|
|
569
|
+
lang: shikiLanguage,
|
|
570
|
+
theme: SHIKI_LIGHT_THEME,
|
|
571
|
+
});
|
|
572
|
+
const darkTokenResult = highlighter.codeToTokens(code, {
|
|
573
|
+
lang: shikiLanguage,
|
|
574
|
+
theme: SHIKI_DARK_THEME,
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
return {
|
|
578
|
+
light: lightTokenResult.tokens,
|
|
579
|
+
dark: darkTokenResult.tokens,
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function buildLightOnlyTokenLine(lightLine: ThemedToken[]): CodeLineToken[] {
|
|
584
|
+
return lightLine.map((token) => ({
|
|
585
|
+
content: token.content,
|
|
586
|
+
color: token.color,
|
|
587
|
+
bgColor: token.bgColor,
|
|
588
|
+
fontStyle: token.fontStyle,
|
|
589
|
+
htmlStyle: token.htmlStyle,
|
|
590
|
+
}));
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
function mergeTokenLineByContent(
|
|
594
|
+
lightLine: ThemedToken[],
|
|
595
|
+
darkLine: ThemedToken[],
|
|
596
|
+
): CodeLineToken[] | null {
|
|
597
|
+
const lightContent = lightLine.map((token) => token.content).join("");
|
|
598
|
+
const darkContent = darkLine.map((token) => token.content).join("");
|
|
599
|
+
|
|
600
|
+
// When themes tokenize the same text with different boundaries (common for markdown),
|
|
601
|
+
// align on content segments so we can still apply dark token colors reliably.
|
|
602
|
+
if (lightContent !== darkContent) return null;
|
|
603
|
+
if (lightContent.length === 0) return [];
|
|
604
|
+
|
|
605
|
+
const mergedLine: CodeLineToken[] = [];
|
|
606
|
+
let lightTokenIndex = 0;
|
|
607
|
+
let darkTokenIndex = 0;
|
|
608
|
+
let lightTokenOffset = 0;
|
|
609
|
+
let darkTokenOffset = 0;
|
|
610
|
+
|
|
611
|
+
while (
|
|
612
|
+
lightTokenIndex < lightLine.length &&
|
|
613
|
+
darkTokenIndex < darkLine.length
|
|
614
|
+
) {
|
|
615
|
+
const lightToken = lightLine[lightTokenIndex];
|
|
616
|
+
const darkToken = darkLine[darkTokenIndex];
|
|
617
|
+
|
|
618
|
+
if (lightTokenOffset >= lightToken.content.length) {
|
|
619
|
+
lightTokenIndex += 1;
|
|
620
|
+
lightTokenOffset = 0;
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
if (darkTokenOffset >= darkToken.content.length) {
|
|
625
|
+
darkTokenIndex += 1;
|
|
626
|
+
darkTokenOffset = 0;
|
|
627
|
+
continue;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const lightRemainingLength = lightToken.content.length - lightTokenOffset;
|
|
631
|
+
const darkRemainingLength = darkToken.content.length - darkTokenOffset;
|
|
632
|
+
const segmentLength = Math.min(lightRemainingLength, darkRemainingLength);
|
|
633
|
+
if (segmentLength <= 0) break;
|
|
634
|
+
|
|
635
|
+
const lightSegment = lightToken.content.slice(
|
|
636
|
+
lightTokenOffset,
|
|
637
|
+
lightTokenOffset + segmentLength,
|
|
638
|
+
);
|
|
639
|
+
const darkSegment = darkToken.content.slice(
|
|
640
|
+
darkTokenOffset,
|
|
641
|
+
darkTokenOffset + segmentLength,
|
|
642
|
+
);
|
|
643
|
+
|
|
644
|
+
if (lightSegment !== darkSegment) return null;
|
|
645
|
+
|
|
646
|
+
mergedLine.push({
|
|
647
|
+
content: lightSegment,
|
|
648
|
+
color: lightToken.color,
|
|
649
|
+
darkColor: darkToken.color,
|
|
650
|
+
bgColor: lightToken.bgColor,
|
|
651
|
+
darkBgColor: darkToken.bgColor,
|
|
652
|
+
fontStyle: lightToken.fontStyle,
|
|
653
|
+
htmlStyle: lightToken.htmlStyle,
|
|
654
|
+
darkHtmlStyle: darkToken.htmlStyle,
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
lightTokenOffset += segmentLength;
|
|
658
|
+
darkTokenOffset += segmentLength;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const mergedContent = mergedLine.map((token) => token.content).join("");
|
|
662
|
+
return mergedContent === lightContent ? mergedLine : null;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
function mergeTokenLines(
|
|
666
|
+
lightTokenLines: ThemedToken[][],
|
|
667
|
+
darkTokenLines: ThemedToken[][],
|
|
668
|
+
): CodeLineToken[][] {
|
|
669
|
+
const lineCount = Math.max(lightTokenLines.length, darkTokenLines.length);
|
|
670
|
+
const mergedLines: CodeLineToken[][] = [];
|
|
671
|
+
|
|
672
|
+
for (let lineIndex = 0; lineIndex < lineCount; lineIndex += 1) {
|
|
673
|
+
const lightLine = lightTokenLines[lineIndex] ?? [];
|
|
674
|
+
const darkLine = darkTokenLines[lineIndex] ?? [];
|
|
675
|
+
|
|
676
|
+
const mergedLine = mergeTokenLineByContent(lightLine, darkLine);
|
|
677
|
+
mergedLines.push(mergedLine ?? buildLightOnlyTokenLine(lightLine));
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
return mergedLines;
|
|
681
|
+
}
|