radiant-docs 0.1.61 → 0.1.63
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 +38 -27
- package/template/package-lock.json +2858 -1140
- package/template/package.json +18 -13
- package/template/scripts/generate-proxy-allowed-origins.mjs +10 -179
- package/template/scripts/publish-shiki-platform-assets.mjs +1177 -0
- package/template/src/components/Header.astro +6 -1
- package/template/src/components/NavigationTabList.astro +65 -0
- package/template/src/components/NavigationTabs.astro +109 -0
- package/template/src/components/OpenApiPage.astro +17 -1
- package/template/src/components/Sidebar.astro +2 -2
- package/template/src/components/SidebarDropdown.astro +105 -44
- package/template/src/components/SidebarMenu.astro +3 -0
- package/template/src/components/SidebarSegmented.astro +87 -52
- package/template/src/components/SidebarTabs.astro +86 -0
- package/template/src/components/chat/AssistantDocsWidget.tsx +127 -2
- package/template/src/components/chat/AssistantEmbedPanel.tsx +401 -283
- package/template/src/components/endpoint/PlaygroundForm.astro +69 -55
- package/template/src/components/endpoint/ResponseDisplay.astro +2 -2
- package/template/src/components/user/Accordion.astro +1 -1
- package/template/src/components/user/Callout.astro +2 -2
- package/template/src/components/user/CodeBlock.astro +58 -7
- package/template/src/components/user/CodeGroup.astro +52 -1
- package/template/src/components/user/Column.astro +1 -1
- package/template/src/components/user/Step.astro +1 -1
- package/template/src/components/user/Tabs.astro +1 -1
- package/template/src/generated/shiki-platform-assets.json +24 -0
- package/template/src/layouts/Layout.astro +111 -8
- package/template/src/lib/assistant-panel-config.ts +4 -0
- package/template/src/lib/assistant-shiki-client.ts +522 -0
- package/template/src/lib/client-shiki-config.ts +60 -0
- package/template/src/lib/dev-playground-proxy.mjs +597 -0
- package/template/src/lib/mdx/remark-resolve-internal-links.ts +334 -17
- package/template/src/lib/proxy-allowed-origins.mjs +189 -0
- package/template/src/lib/routes.ts +66 -24
- package/template/src/styles/global.css +16 -4
- package/template/src/components/ui/demo/CodeDemo.astro +0 -15
- package/template/src/components/ui/demo/Demo.astro +0 -3
- package/template/src/components/ui/demo/UiDisplay.astro +0 -13
package/template/package.json
CHANGED
|
@@ -9,16 +9,20 @@
|
|
|
9
9
|
"build": "astro build && node scripts/remove-assistant-for-non-pro.mjs && node scripts/generate-og-metadata.mjs && node scripts/generate-og-images.mjs && node scripts/stamp-og-image-versions.mjs && node scripts/stamp-image-versions.mjs && pagefind --site dist && node scripts/stamp-pagefind-runtime-version.mjs && node scripts/generate-proxy-allowed-origins.mjs && node scripts/generate-robots-txt.mjs",
|
|
10
10
|
"preview": "astro preview",
|
|
11
11
|
"astro": "astro",
|
|
12
|
-
"search:index": "astro build && node scripts/remove-assistant-for-non-pro.mjs && node scripts/generate-og-metadata.mjs && node scripts/generate-og-images.mjs && node scripts/stamp-og-image-versions.mjs && node scripts/stamp-image-versions.mjs && pagefind --site dist && node scripts/stamp-pagefind-runtime-version.mjs && node scripts/generate-proxy-allowed-origins.mjs && node scripts/generate-robots-txt.mjs && cp -r dist/pagefind public/"
|
|
12
|
+
"search:index": "astro build && node scripts/remove-assistant-for-non-pro.mjs && node scripts/generate-og-metadata.mjs && node scripts/generate-og-images.mjs && node scripts/stamp-og-image-versions.mjs && node scripts/stamp-image-versions.mjs && pagefind --site dist && node scripts/stamp-pagefind-runtime-version.mjs && node scripts/generate-proxy-allowed-origins.mjs && node scripts/generate-robots-txt.mjs && cp -r dist/pagefind public/",
|
|
13
|
+
"shiki:assets:update": "node scripts/publish-shiki-platform-assets.mjs --prepare-only --write-current",
|
|
14
|
+
"shiki:assets:upload": "node scripts/publish-shiki-platform-assets.mjs --check-current",
|
|
15
|
+
"shiki:assets:upload:dev": "node scripts/publish-shiki-platform-assets.mjs --env-file .env --check-current"
|
|
13
16
|
},
|
|
14
17
|
"dependencies": {
|
|
15
18
|
"@alpinejs/collapse": "^3.15.2",
|
|
16
19
|
"@alpinejs/focus": "^3.15.3",
|
|
17
20
|
"@alpinejs/persist": "^3.15.2",
|
|
18
|
-
"@astrojs/alpinejs": "^0.
|
|
19
|
-
"@astrojs/
|
|
20
|
-
"@astrojs/
|
|
21
|
-
"@astrojs/
|
|
21
|
+
"@astrojs/alpinejs": "^1.0.0",
|
|
22
|
+
"@astrojs/markdown-remark": "^7.2.0",
|
|
23
|
+
"@astrojs/mdx": "^7.0.0",
|
|
24
|
+
"@astrojs/preact": "^6.0.0",
|
|
25
|
+
"@astrojs/sitemap": "^3.7.3",
|
|
22
26
|
"@aws-sdk/client-s3": "^3.964.0",
|
|
23
27
|
"@fontsource-variable/geist": "^5.2.9",
|
|
24
28
|
"@fontsource-variable/geist-mono": "^5.2.8",
|
|
@@ -34,18 +38,21 @@
|
|
|
34
38
|
"@iconify-json/lucide": "^1.2.79",
|
|
35
39
|
"@iconify-json/simple-icons": "^1.2.69",
|
|
36
40
|
"@iconify/react": "^6.0.2",
|
|
37
|
-
"@jongwooo/prism-theme-github": "^1.15.1",
|
|
38
41
|
"@paper-design/shaders": "^0.0.76",
|
|
39
42
|
"@preact/preset-vite": "^2.10.3",
|
|
40
43
|
"@readme/oas-to-snippet": "^29.3.0",
|
|
41
44
|
"@resvg/resvg-js": "^2.6.2",
|
|
45
|
+
"@shikijs/core": "4.2.0",
|
|
46
|
+
"@shikijs/engine-javascript": "4.2.0",
|
|
47
|
+
"@shikijs/langs": "4.2.0",
|
|
48
|
+
"@shikijs/themes": "4.2.0",
|
|
42
49
|
"@stoplight/spectral-core": "^1.20.0",
|
|
43
50
|
"@stoplight/spectral-rulesets": "^1.22.0",
|
|
44
51
|
"@tailwindcss/typography": "^0.5.19",
|
|
45
52
|
"@tailwindcss/vite": "^4.1.17",
|
|
46
53
|
"@xt0rted/expressive-code-file-icons": "^1.0.0",
|
|
47
54
|
"alpinejs": "^3.15.2",
|
|
48
|
-
"astro": "^
|
|
55
|
+
"astro": "^7.0.2",
|
|
49
56
|
"astro-icon": "^1.1.5",
|
|
50
57
|
"fontkit": "^2.0.4",
|
|
51
58
|
"fs-extra": "^11.3.3",
|
|
@@ -55,22 +62,20 @@
|
|
|
55
62
|
"oas": "^28.7.0",
|
|
56
63
|
"openapi-sampler": "^1.6.2",
|
|
57
64
|
"preact": "^10.29.0",
|
|
58
|
-
"
|
|
59
|
-
"prismjs": "^1.30.0",
|
|
60
|
-
"radiant-docs-validator": "^0.1.20",
|
|
65
|
+
"radiant-docs-validator": "^0.1.29",
|
|
61
66
|
"rehype-autolink-headings": "^7.1.0",
|
|
62
67
|
"rehype-slug": "^6.0.0",
|
|
63
68
|
"remark-gfm": "^4.0.1",
|
|
69
|
+
"shiki": "4.2.0",
|
|
64
70
|
"simple-git": "^3.30.0",
|
|
65
71
|
"tailwindcss": "^4.2.2",
|
|
66
72
|
"wawoff2": "^2.0.1",
|
|
67
|
-
"yaml": "^2.8.2"
|
|
68
|
-
"zod": "^3.25.76"
|
|
73
|
+
"yaml": "^2.8.2"
|
|
69
74
|
},
|
|
70
75
|
"devDependencies": {
|
|
71
76
|
"@types/fs-extra": "^11.0.4",
|
|
72
77
|
"@types/mime-types": "^3.0.1",
|
|
73
|
-
"
|
|
78
|
+
"esbuild": "^0.25.12",
|
|
74
79
|
"pagefind": "^1.4.0",
|
|
75
80
|
"tsx": "^4.21.0"
|
|
76
81
|
}
|
|
@@ -1,193 +1,24 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import
|
|
3
|
+
import { buildAllowedOrigins } from "../src/lib/proxy-allowed-origins.mjs";
|
|
4
4
|
|
|
5
5
|
const CWD = process.cwd();
|
|
6
|
-
const DOCS_DIR = path.join(CWD, "src/content/docs");
|
|
7
|
-
const DOCS_CONFIG_PATH = path.join(DOCS_DIR, "docs.json");
|
|
8
6
|
const OUTPUT_DIR = path.join(CWD, ".radiant");
|
|
9
7
|
const OUTPUT_FILE = path.join(OUTPUT_DIR, "proxy-allowed-origins.json");
|
|
10
8
|
|
|
11
|
-
function isRecord(value) {
|
|
12
|
-
return typeof value === "object" && value !== null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function isHttpUrl(value) {
|
|
16
|
-
return /^https?:\/\//i.test(String(value).trim());
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function collectOpenApiSourcesFromNavigation(navigationNode, target) {
|
|
20
|
-
if (!isRecord(navigationNode)) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const openApiConfig = navigationNode.openapi;
|
|
25
|
-
if (typeof openApiConfig === "string") {
|
|
26
|
-
const trimmed = openApiConfig.trim();
|
|
27
|
-
if (trimmed) {
|
|
28
|
-
target.add(trimmed);
|
|
29
|
-
}
|
|
30
|
-
} else if (
|
|
31
|
-
isRecord(openApiConfig) &&
|
|
32
|
-
typeof openApiConfig.source === "string"
|
|
33
|
-
) {
|
|
34
|
-
const trimmed = openApiConfig.source.trim();
|
|
35
|
-
if (trimmed) {
|
|
36
|
-
target.add(trimmed);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const menu = navigationNode.menu;
|
|
41
|
-
if (!isRecord(menu) || !Array.isArray(menu.items)) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
for (const menuItem of menu.items) {
|
|
46
|
-
if (!isRecord(menuItem) || !isRecord(menuItem.submenu)) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
collectOpenApiSourcesFromNavigation(menuItem.submenu, target);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function resolveServerTemplateUrl(rawUrl, rawVariables) {
|
|
54
|
-
let unresolved = false;
|
|
55
|
-
const variables = isRecord(rawVariables) ? rawVariables : null;
|
|
56
|
-
|
|
57
|
-
const resolved = rawUrl.replace(/\{([^}]+)\}/g, (_match, tokenName) => {
|
|
58
|
-
if (!variables) {
|
|
59
|
-
unresolved = true;
|
|
60
|
-
return "";
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const variableConfig = variables[tokenName];
|
|
64
|
-
if (
|
|
65
|
-
!isRecord(variableConfig) ||
|
|
66
|
-
typeof variableConfig.default !== "string"
|
|
67
|
-
) {
|
|
68
|
-
unresolved = true;
|
|
69
|
-
return "";
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const defaultValue = variableConfig.default.trim();
|
|
73
|
-
if (!defaultValue) {
|
|
74
|
-
unresolved = true;
|
|
75
|
-
return "";
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return defaultValue;
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
if (unresolved) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return resolved;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function normalizeAllowedOrigin(rawUrl) {
|
|
89
|
-
let parsed;
|
|
90
|
-
try {
|
|
91
|
-
parsed = new URL(rawUrl);
|
|
92
|
-
} catch {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (parsed.protocol !== "https:") {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (!parsed.hostname || parsed.username || parsed.password) {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return parsed.origin.toLowerCase();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async function loadOpenApiSpec(source) {
|
|
108
|
-
let fileContent;
|
|
109
|
-
|
|
110
|
-
if (isHttpUrl(source)) {
|
|
111
|
-
const response = await fetch(source);
|
|
112
|
-
if (!response.ok) {
|
|
113
|
-
throw new Error(
|
|
114
|
-
`Failed to fetch OpenAPI spec (${response.status} ${response.statusText})`,
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
fileContent = await response.text();
|
|
118
|
-
} else {
|
|
119
|
-
const absolutePath = path.join(DOCS_DIR, source);
|
|
120
|
-
fileContent = await fs.readFile(absolutePath, "utf8");
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const trimmed = fileContent.trim();
|
|
124
|
-
if (trimmed.startsWith("<!DOCTYPE") || trimmed.startsWith("<html")) {
|
|
125
|
-
throw new Error("OpenAPI source returned HTML instead of JSON or YAML");
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
return JSON.parse(fileContent);
|
|
130
|
-
} catch {
|
|
131
|
-
return YAML.parse(fileContent);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async function buildAllowedOrigins() {
|
|
136
|
-
const docsConfigRaw = await fs.readFile(DOCS_CONFIG_PATH, "utf8");
|
|
137
|
-
const docsConfig = JSON.parse(docsConfigRaw);
|
|
138
|
-
|
|
139
|
-
if (!isRecord(docsConfig) || !isRecord(docsConfig.navigation)) {
|
|
140
|
-
return [];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const sources = new Set();
|
|
144
|
-
collectOpenApiSourcesFromNavigation(docsConfig.navigation, sources);
|
|
145
|
-
if (sources.size === 0) {
|
|
146
|
-
return [];
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const allowedOrigins = new Set();
|
|
150
|
-
|
|
151
|
-
for (const source of sources) {
|
|
152
|
-
try {
|
|
153
|
-
const spec = await loadOpenApiSpec(source);
|
|
154
|
-
const servers =
|
|
155
|
-
isRecord(spec) && Array.isArray(spec.servers) ? spec.servers : [];
|
|
156
|
-
|
|
157
|
-
for (const server of servers) {
|
|
158
|
-
if (!isRecord(server) || typeof server.url !== "string") {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const resolvedUrl = resolveServerTemplateUrl(
|
|
163
|
-
server.url,
|
|
164
|
-
server.variables,
|
|
165
|
-
);
|
|
166
|
-
if (!resolvedUrl) {
|
|
167
|
-
continue;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const normalizedOrigin = normalizeAllowedOrigin(resolvedUrl);
|
|
171
|
-
if (normalizedOrigin) {
|
|
172
|
-
allowedOrigins.add(normalizedOrigin);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
} catch (error) {
|
|
176
|
-
console.warn(
|
|
177
|
-
`⚠️ Failed to extract OpenAPI server origins from "${source}":`,
|
|
178
|
-
error instanceof Error ? error.message : String(error),
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return Array.from(allowedOrigins).sort();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
9
|
async function run() {
|
|
187
10
|
let allowedOrigins = [];
|
|
188
11
|
|
|
189
12
|
try {
|
|
190
|
-
allowedOrigins = await buildAllowedOrigins(
|
|
13
|
+
allowedOrigins = await buildAllowedOrigins({
|
|
14
|
+
cwd: CWD,
|
|
15
|
+
onSourceError(source, error) {
|
|
16
|
+
console.warn(
|
|
17
|
+
`⚠️ Failed to extract OpenAPI server origins from "${source}":`,
|
|
18
|
+
error instanceof Error ? error.message : String(error),
|
|
19
|
+
);
|
|
20
|
+
},
|
|
21
|
+
});
|
|
191
22
|
} catch (error) {
|
|
192
23
|
console.warn(
|
|
193
24
|
"⚠️ Failed to generate proxy allowed origins. Falling back to empty allowlist.",
|