@stainless-api/docs 0.1.0-beta.60 → 0.1.0-beta.62
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/CHANGELOG.md +22 -0
- package/locals.d.ts +1 -0
- package/package.json +6 -6
- package/plugin/index.ts +0 -1
- package/stl-docs/components/AiChatIsland.tsx +2 -4
- package/stl-docs/components/ThemeProvider.astro +36 -0
- package/stl-docs/components/ThemeSelect.astro +0 -37
- package/stl-docs/index.ts +24 -7
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +38 -16
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +6 -1
- package/virtual-module.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @stainless-api/docs
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.62
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3c4a030: increase minimum starlight depdendency version
|
|
8
|
+
- cd86726: Fix a crash when stl-starlight plugin isn’t being loaded
|
|
9
|
+
- aa9d333: fixes for markdown rendering when astro integrations override the starlight html entrypoint
|
|
10
|
+
- 07a2c87: Should override ThemeProvider for setting theme within the html head
|
|
11
|
+
- @stainless-api/docs-search@0.1.0-beta.3
|
|
12
|
+
- @stainless-api/docs-ui@0.1.0-beta.51
|
|
13
|
+
- @stainless-api/ui-primitives@0.1.0-beta.38
|
|
14
|
+
|
|
15
|
+
## 0.1.0-beta.61
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 88a9894: patch vite optimizeDeps for docs-ai-chat
|
|
20
|
+
- Updated dependencies [2a79bae]
|
|
21
|
+
- @stainless-api/ui-primitives@0.1.0-beta.38
|
|
22
|
+
- @stainless-api/docs-ui@0.1.0-beta.51
|
|
23
|
+
- @stainless-api/docs-search@0.1.0-beta.3
|
|
24
|
+
|
|
3
25
|
## 0.1.0-beta.60
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/locals.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stainless-api/docs",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.62",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"node": ">=18.17.1"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@astrojs/starlight": ">=0.
|
|
28
|
+
"@astrojs/starlight": ">=0.37.0",
|
|
29
29
|
"astro": ">=5.15.3",
|
|
30
30
|
"react": ">=19.0.0",
|
|
31
31
|
"react-dom": ">=19.0.0",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"vite-plugin-prebundle-workers": "^0.2.0",
|
|
53
53
|
"web-worker": "^1.5.0",
|
|
54
54
|
"yaml": "^2.8.2",
|
|
55
|
-
"@stainless-api/docs-ui": "0.1.0-beta.
|
|
56
|
-
"@stainless-api/docs-search": "0.1.0-beta.
|
|
57
|
-
"@stainless-api/ui-primitives": "0.1.0-beta.
|
|
55
|
+
"@stainless-api/docs-ui": "0.1.0-beta.51",
|
|
56
|
+
"@stainless-api/docs-search": "0.1.0-beta.3",
|
|
57
|
+
"@stainless-api/ui-primitives": "0.1.0-beta.38"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@astrojs/check": "^0.9.6",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"typescript": "5.9.3",
|
|
69
69
|
"vite": "^6.4.1",
|
|
70
70
|
"zod": "^4.1.13",
|
|
71
|
-
"@stainless/eslint-config": "0.1.0-beta.
|
|
71
|
+
"@stainless/eslint-config": "0.1.0-beta.1",
|
|
72
72
|
"@stainless/sdk-json": "^0.1.0-beta.2"
|
|
73
73
|
},
|
|
74
74
|
"scripts": {
|
package/plugin/index.ts
CHANGED
|
@@ -301,7 +301,6 @@ async function stlStarlightAstroIntegration(
|
|
|
301
301
|
PROPERTY_SETTINGS: pluginConfig.propertySettings,
|
|
302
302
|
ENABLE_CONTEXT_MENU: pluginConfig.contextMenu,
|
|
303
303
|
EXPERIMENTAL_PLAYGROUNDS: !!pluginConfig.experimentalPlaygrounds,
|
|
304
|
-
STAINLESS_PROJECT: version.stainlessProject,
|
|
305
304
|
} satisfies Omit<typeof StlStarlightVirtualModule, 'MIDDLEWARE'>),
|
|
306
305
|
vmMiddlewareExport,
|
|
307
306
|
].join('\n');
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
2
|
-
import AiChat from 'virtual:stl-docs/components/AiChat.tsx';
|
|
3
|
-
// right now loading AiChat without API reference plugin is unsupported
|
|
4
|
-
// because the AiChat is for talking about the SDKs
|
|
5
|
-
import { STAINLESS_PROJECT } from 'virtual:stl-starlight-virtual-module';
|
|
2
|
+
import AiChat, { STAINLESS_PROJECT } from 'virtual:stl-docs/components/AiChat.tsx';
|
|
6
3
|
|
|
7
4
|
export default function AiChatIsland({ currentLanguage }: { currentLanguage: DocsLanguage | undefined }) {
|
|
8
5
|
if (!AiChat) throw new Error('AiChatIsland was rendered but could not load AiChat component');
|
|
6
|
+
if (!STAINLESS_PROJECT) return null;
|
|
9
7
|
return <AiChat projectId={STAINLESS_PROJECT} language={currentLanguage} />;
|
|
10
8
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{/* Inlined to avoid FOUC. All theme selects are initialized here */}
|
|
2
|
+
<script is:inline>
|
|
3
|
+
window.didInitThemePickers = window.didInitThemePickers ?? false;
|
|
4
|
+
|
|
5
|
+
// Only run once.
|
|
6
|
+
if (!window.didInitThemePickers) {
|
|
7
|
+
window.didInitThemePickers = true;
|
|
8
|
+
|
|
9
|
+
// The stored theme will be either 'auto', 'light', 'dark' or null.
|
|
10
|
+
const storedTheme = typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
|
|
11
|
+
|
|
12
|
+
// This theme is either 'light' or 'dark'. It's used for setting the data-theme attribute.
|
|
13
|
+
const theme =
|
|
14
|
+
!storedTheme || storedTheme === 'auto'
|
|
15
|
+
? window.matchMedia('(prefers-color-scheme: light)').matches
|
|
16
|
+
? 'light'
|
|
17
|
+
: 'dark'
|
|
18
|
+
: storedTheme;
|
|
19
|
+
|
|
20
|
+
document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark';
|
|
21
|
+
|
|
22
|
+
const themeSelects = document.querySelectorAll('[data-theme-select]');
|
|
23
|
+
const selectedThemeValue = storedTheme || 'auto';
|
|
24
|
+
|
|
25
|
+
themeSelects.forEach((select) => {
|
|
26
|
+
const tmpl = select.querySelector(`[data-value="${selectedThemeValue}"] template`);
|
|
27
|
+
const selectedSlot = select.querySelector('[data-part="trigger-selected"]');
|
|
28
|
+
|
|
29
|
+
selectedSlot.innerHTML = '';
|
|
30
|
+
if (tmpl) {
|
|
31
|
+
selectedSlot.appendChild(tmpl.content.cloneNode(true));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
@@ -88,43 +88,6 @@ const options = [
|
|
|
88
88
|
</Dropdown.Menu>
|
|
89
89
|
</Dropdown>
|
|
90
90
|
|
|
91
|
-
{/* Inlined to avoid FOUC. All theme selects are initialized here */}
|
|
92
|
-
<script is:inline>
|
|
93
|
-
window.didInitThemePickers = window.didInitThemePickers ?? false;
|
|
94
|
-
|
|
95
|
-
// Only run once.
|
|
96
|
-
if (!window.didInitThemePickers) {
|
|
97
|
-
window.didInitThemePickers = true;
|
|
98
|
-
|
|
99
|
-
// The stored theme will be either 'auto', 'light', 'dark' or null.
|
|
100
|
-
const storedTheme = typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
|
|
101
|
-
|
|
102
|
-
// This theme is either 'light' or 'dark'. It's used for setting the data-theme attribute.
|
|
103
|
-
const theme =
|
|
104
|
-
!storedTheme || storedTheme === 'auto'
|
|
105
|
-
? window.matchMedia('(prefers-color-scheme: light)').matches
|
|
106
|
-
? 'light'
|
|
107
|
-
: 'dark'
|
|
108
|
-
: storedTheme;
|
|
109
|
-
|
|
110
|
-
document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark';
|
|
111
|
-
|
|
112
|
-
const themeSelects = document.querySelectorAll('[data-theme-select]');
|
|
113
|
-
const selectedThemeValue = storedTheme || 'auto';
|
|
114
|
-
|
|
115
|
-
themeSelects.forEach((select) => {
|
|
116
|
-
const tmpl = select.querySelector(`[data-value="${selectedThemeValue}"] template`);
|
|
117
|
-
const selectedSlot = select.querySelector('[data-part="trigger-selected"]');
|
|
118
|
-
|
|
119
|
-
selectedSlot.innerHTML = '';
|
|
120
|
-
if (tmpl) {
|
|
121
|
-
selectedSlot.appendChild(tmpl.content.cloneNode(true));
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
</script>
|
|
127
|
-
|
|
128
91
|
<script>
|
|
129
92
|
import { getPageLoadEvent } from '../../plugin/helpers/getPageLoadEvent';
|
|
130
93
|
import { initDropdown } from '@stainless-api/docs/components/scripts';
|
package/stl-docs/index.ts
CHANGED
|
@@ -52,6 +52,7 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
52
52
|
|
|
53
53
|
Head: resolveSrcFile(COMPONENTS_FOLDER, './Head.astro'),
|
|
54
54
|
Header: resolveSrcFile(COMPONENTS_FOLDER, './Header.astro'),
|
|
55
|
+
ThemeProvider: resolveSrcFile(COMPONENTS_FOLDER, './ThemeProvider.astro'),
|
|
55
56
|
ThemeSelect: resolveSrcFile(COMPONENTS_FOLDER, './ThemeSelect.astro'),
|
|
56
57
|
|
|
57
58
|
Sidebar: resolveSrcFile(COMPONENTS_FOLDER, './sidebars/BaseSidebar.astro'),
|
|
@@ -158,15 +159,19 @@ function stainlessDocsIntegration(
|
|
|
158
159
|
ENABLE_CLIENT_ROUTER: config.enableClientRouter,
|
|
159
160
|
API_REFERENCE_BASE_PATH: apiReferenceBasePath,
|
|
160
161
|
ENABLE_PROSE_MARKDOWN_RENDERING: config.enableProseMarkdownRendering,
|
|
161
|
-
// TODO: do not duplicate this between both virtual modules
|
|
162
|
-
ENABLE_CONTEXT_MENU: config.contextMenu,
|
|
162
|
+
ENABLE_CONTEXT_MENU: config.contextMenu, // TODO: do not duplicate this between both virtual modules
|
|
163
163
|
RENDER_PAGE_DESCRIPTIONS: config.renderPageDescriptions,
|
|
164
164
|
} satisfies typeof StlDocsVirtualModule),
|
|
165
165
|
|
|
166
|
-
'virtual:stl-docs/components/AiChat.tsx':
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
'virtual:stl-docs/components/AiChat.tsx': `
|
|
167
|
+
${
|
|
168
|
+
config.aiChat
|
|
169
|
+
? `export { default } from ${JSON.stringify(config.aiChat.chatComponentPath)};`
|
|
170
|
+
: // export null when no AI chat component is provided
|
|
171
|
+
`export default null;`
|
|
172
|
+
}
|
|
173
|
+
export const STAINLESS_PROJECT = ${config.apiReference ? JSON.stringify(config.apiReference.stainlessProject) : 'undefined'};
|
|
174
|
+
`,
|
|
170
175
|
}),
|
|
171
176
|
);
|
|
172
177
|
|
|
@@ -198,6 +203,15 @@ function stainlessDocsIntegration(
|
|
|
198
203
|
},
|
|
199
204
|
},
|
|
200
205
|
],
|
|
206
|
+
optimizeDeps: {
|
|
207
|
+
include: config.aiChat
|
|
208
|
+
? [
|
|
209
|
+
'@stainless-api/docs-ai-chat > motion',
|
|
210
|
+
'@stainless-api/docs-ai-chat > react-markdown',
|
|
211
|
+
'@stainless-api/docs-ai-chat > react-syntax-highlighter',
|
|
212
|
+
]
|
|
213
|
+
: [],
|
|
214
|
+
},
|
|
201
215
|
},
|
|
202
216
|
build: {
|
|
203
217
|
...astroConfig.build,
|
|
@@ -253,7 +267,10 @@ export function stainlessDocs(config: StainlessDocsUserConfig) {
|
|
|
253
267
|
react(),
|
|
254
268
|
stainlessDocsStarlightIntegration(normalizedConfig),
|
|
255
269
|
stainlessDocsIntegration(normalizedConfig, apiReferenceBasePath),
|
|
256
|
-
stainlessDocsMarkdownRenderer({
|
|
270
|
+
stainlessDocsMarkdownRenderer({
|
|
271
|
+
enabled: normalizedConfig.enableProseMarkdownRendering,
|
|
272
|
+
apiReferenceBasePath,
|
|
273
|
+
}),
|
|
257
274
|
stainlessDocsProseIndexing(),
|
|
258
275
|
];
|
|
259
276
|
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import type { AstroIntegration } from 'astro';
|
|
2
|
-
import { readFile, writeFile } from 'fs/promises';
|
|
2
|
+
import { readdir, readFile, writeFile } from 'fs/promises';
|
|
3
3
|
import { toMarkdown } from './toMarkdown';
|
|
4
4
|
import { resolveSrcFile } from '../../resolveSrcFile';
|
|
5
5
|
import { getSharedLogger } from '../../shared/getSharedLogger';
|
|
6
|
+
import { join, relative } from 'path';
|
|
6
7
|
import { bold } from '../../shared/terminalUtils';
|
|
7
8
|
|
|
8
|
-
export function stainlessDocsMarkdownRenderer({
|
|
9
|
+
export function stainlessDocsMarkdownRenderer({
|
|
10
|
+
enabled,
|
|
11
|
+
apiReferenceBasePath,
|
|
12
|
+
}: {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
apiReferenceBasePath: string | null;
|
|
15
|
+
}): AstroIntegration {
|
|
9
16
|
return {
|
|
10
17
|
name: 'stl-docs-md',
|
|
11
18
|
hooks: {
|
|
@@ -17,29 +24,44 @@ export function stainlessDocsMarkdownRenderer({ enabled }: { enabled: boolean })
|
|
|
17
24
|
});
|
|
18
25
|
}
|
|
19
26
|
},
|
|
20
|
-
'astro:build:done': async ({
|
|
27
|
+
'astro:build:done': async ({ logger: localLogger, dir }) => {
|
|
21
28
|
const logger = getSharedLogger({ fallback: localLogger });
|
|
22
29
|
if (!enabled) {
|
|
23
30
|
logger.info('Stainless Docs prose Markdown rendering is disabled, skipping...');
|
|
24
31
|
return;
|
|
25
32
|
}
|
|
26
|
-
const
|
|
27
|
-
const pagesToRender = Array.from(assets.entries())
|
|
28
|
-
.filter(([k]) => {
|
|
29
|
-
if (starlightPagePatterns.includes(k)) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
return false;
|
|
33
|
-
})
|
|
34
|
-
.map(([, v]) => v)
|
|
35
|
-
.flat()
|
|
36
|
-
.map((v) => v.pathname);
|
|
33
|
+
const outputBasePath = dir.pathname;
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
// Read all HTML files from output directory, and not from assets.
|
|
36
|
+
// We cannot use the `assets` map here because it is not guaranteed to
|
|
37
|
+
// contain all files, especially if they were generated by other integrations.
|
|
38
|
+
// Other astro integrations may hijack the "[...slug]" entrypoint, and any files
|
|
39
|
+
// previously in the [...slug] asset map entry would be lost (this is where starlight stores
|
|
40
|
+
// its prose HTML files).
|
|
41
|
+
const allFiles = await readdir(outputBasePath, {
|
|
42
|
+
recursive: true,
|
|
43
|
+
withFileTypes: true,
|
|
44
|
+
});
|
|
39
45
|
|
|
40
|
-
const
|
|
46
|
+
const htmlFiles = allFiles
|
|
47
|
+
.filter((file) => file.isFile() && file.name.endsWith('.html'))
|
|
48
|
+
.map((file) => join(file.parentPath, file.name));
|
|
49
|
+
|
|
50
|
+
// Filter out API reference pages
|
|
51
|
+
const pagesToRender = htmlFiles.filter((absPath) => {
|
|
52
|
+
if (!apiReferenceBasePath) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
const relPath = relative(outputBasePath, absPath);
|
|
56
|
+
// Normalize by removing leading/trailing slashes from apiReferenceBasePath
|
|
57
|
+
const normalizedApiPath = apiReferenceBasePath.replace(/^\/+|\/+$/g, '');
|
|
58
|
+
return !relPath.startsWith(normalizedApiPath);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
logger.info(bold(`Building ${pagesToRender.length} Markdown pages for prose content`));
|
|
41
62
|
|
|
42
63
|
let completedCount = 0;
|
|
64
|
+
|
|
43
65
|
for (const absHtmlPath of pagesToRender) {
|
|
44
66
|
const txt = await readFile(absHtmlPath, 'utf-8');
|
|
45
67
|
const md = await toMarkdown(txt);
|
|
@@ -18,7 +18,12 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|
|
18
18
|
return next();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const pathname = context.url.pathname.replace('index.md', '');
|
|
22
|
+
|
|
23
|
+
// We must trim the trailing slash to support astro configs with `trailingSlash: 'never'`
|
|
24
|
+
const cleanPathname = pathname !== '/' ? pathname.replace(/\/$/, '') : pathname;
|
|
25
|
+
const htmlUrl = new URL(cleanPathname, context.url);
|
|
26
|
+
|
|
22
27
|
const resp = await fetch(htmlUrl);
|
|
23
28
|
if (!resp.ok) {
|
|
24
29
|
return new Response('Failed to fetch HTML', { status: 400 });
|
package/virtual-module.d.ts
CHANGED
|
@@ -23,7 +23,6 @@ declare module 'virtual:stl-starlight-virtual-module' {
|
|
|
23
23
|
export const PROPERTY_SETTINGS: PropertySettingsType;
|
|
24
24
|
export const MIDDLEWARE: StlStarlightMiddleware;
|
|
25
25
|
export const ENABLE_CONTEXT_MENU: boolean;
|
|
26
|
-
export const STAINLESS_PROJECT: string;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
declare module 'virtual:stl-docs-virtual-module' {
|
|
@@ -60,4 +59,5 @@ declare module 'virtual:stl-docs/components/AiChat.tsx' {
|
|
|
60
59
|
}>
|
|
61
60
|
| null;
|
|
62
61
|
export default AiChatComponent;
|
|
62
|
+
export const STAINLESS_PROJECT: string | undefined;
|
|
63
63
|
}
|