@stainless-api/docs 0.1.0-beta.9 → 0.1.0-beta.90
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 +748 -0
- package/eslint-suppressions.json +32 -0
- package/locals.d.ts +17 -0
- package/package.json +49 -40
- package/playground-virtual-modules.d.ts +96 -0
- package/plugin/assets/languages/cli.svg +14 -0
- package/plugin/assets/languages/csharp.svg +1 -0
- package/plugin/buildAlgoliaIndex.ts +38 -11
- package/plugin/components/MethodDescription.tsx +54 -0
- package/plugin/components/RequestBuilder/ParamEditor.tsx +55 -0
- package/plugin/components/RequestBuilder/SnippetStainlessIsland.tsx +107 -0
- package/plugin/components/RequestBuilder/index.tsx +31 -0
- package/plugin/components/RequestBuilder/props.ts +9 -0
- package/plugin/components/RequestBuilder/spec-helpers.ts +50 -0
- package/plugin/components/RequestBuilder/styles.css +67 -0
- package/plugin/components/SDKSelect.astro +20 -104
- package/plugin/components/SnippetCode.tsx +111 -66
- package/plugin/components/StainlessIslands.tsx +126 -0
- package/plugin/components/search/SearchAlgolia.astro +45 -28
- package/plugin/components/search/SearchIsland.tsx +47 -29
- package/plugin/generateAPIReferenceLink.ts +2 -2
- package/plugin/globalJs/ai-dropdown-options.ts +243 -0
- package/plugin/globalJs/code-snippets.ts +15 -8
- package/plugin/globalJs/copy.ts +94 -17
- package/plugin/globalJs/create-playground.shim.ts +3 -0
- package/plugin/globalJs/method-descriptions.ts +33 -0
- package/plugin/globalJs/navigation.ts +10 -29
- package/plugin/globalJs/playground-data.shim.ts +1 -0
- package/plugin/globalJs/playground-data.ts +14 -0
- package/plugin/helpers/generateDocsRoutes.ts +27 -0
- package/plugin/helpers/getDocsLanguages.ts +9 -0
- package/plugin/index.ts +292 -116
- package/plugin/languages.ts +7 -2
- package/plugin/loadPluginConfig.ts +155 -79
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +1 -1
- package/plugin/react/Routing.tsx +204 -132
- package/plugin/referencePlaceholderUtils.ts +18 -15
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +38 -34
- package/plugin/routes/Docs.astro +65 -117
- package/plugin/routes/DocsStatic.astro +7 -4
- package/plugin/routes/Overview.astro +20 -24
- package/plugin/routes/markdown.ts +12 -11
- package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +30 -54
- package/plugin/specs/fetchSpecSSR.ts +21 -0
- package/plugin/specs/generateSpec.ts +50 -0
- package/plugin/specs/index.ts +238 -0
- package/plugin/{cms → specs}/worker.ts +82 -5
- package/plugin/vendor/preview.worker.docs.js +20928 -17830
- package/plugin/vendor/templates/go.md +1 -1
- package/plugin/vendor/templates/python.md +1 -1
- package/resolveSrcFile.ts +10 -0
- package/scripts/vendor_deps.ts +5 -5
- package/shared/getProsePages.ts +42 -0
- package/shared/getSharedLogger.ts +15 -0
- package/shared/terminalUtils.ts +3 -0
- package/shared/virtualModule.ts +54 -1
- package/src/content.config.ts +9 -0
- package/stl-docs/components/AIDropdown.tsx +63 -0
- package/stl-docs/components/AiChatIsland.tsx +14 -0
- package/stl-docs/components/{content-panel/ContentBreadcrumbs.tsx → ContentBreadcrumbs.tsx} +2 -2
- package/stl-docs/components/Head.astro +20 -0
- package/stl-docs/components/Header.astro +6 -8
- package/stl-docs/components/PageFrame.astro +18 -0
- package/stl-docs/components/PageTitle.astro +82 -0
- package/stl-docs/components/TableOfContents.astro +34 -0
- package/stl-docs/components/ThemeProvider.astro +36 -0
- package/stl-docs/components/ThemeSelect.astro +84 -139
- package/stl-docs/components/content-panel/ContentPanel.astro +16 -46
- package/stl-docs/components/headers/SplashMobileMenuToggle.astro +17 -1
- package/stl-docs/components/headers/StackedHeader.astro +29 -24
- package/stl-docs/components/icons/chat-gpt.tsx +2 -2
- package/stl-docs/components/icons/cursor.tsx +10 -0
- package/stl-docs/components/icons/gemini.tsx +19 -0
- package/stl-docs/components/icons/markdown.tsx +1 -1
- package/stl-docs/components/index.ts +1 -0
- package/stl-docs/components/mintlify-compat/Accordion.astro +7 -5
- package/stl-docs/components/mintlify-compat/AccordionGroup.astro +7 -3
- package/stl-docs/components/mintlify-compat/Columns.astro +40 -42
- package/stl-docs/components/mintlify-compat/Frame.astro +16 -18
- package/stl-docs/components/mintlify-compat/callouts/Callout.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Check.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Danger.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Info.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Note.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Tip.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Warning.astro +1 -1
- package/stl-docs/components/mintlify-compat/card.css +33 -35
- package/stl-docs/components/mintlify-compat/index.ts +2 -4
- package/stl-docs/components/nav-tabs/NavDropdown.astro +31 -70
- package/stl-docs/components/nav-tabs/NavTabs.astro +78 -80
- package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -8
- package/stl-docs/components/nav-tabs/buildNavLinks.ts +3 -2
- package/stl-docs/components/pagination/HomeLink.astro +10 -0
- package/stl-docs/components/pagination/Pagination.astro +175 -0
- package/stl-docs/components/pagination/PaginationLinkEmphasized.astro +22 -0
- package/stl-docs/components/pagination/PaginationLinkQuiet.astro +13 -0
- package/stl-docs/components/pagination/util.ts +71 -0
- package/stl-docs/components/scripts.ts +1 -0
- package/stl-docs/components/sidebars/BaseSidebar.astro +9 -2
- package/stl-docs/components/sidebars/SidebarWithComponents.tsx +10 -0
- package/stl-docs/components/sidebars/convertAstroSidebarToStl.tsx +62 -0
- package/stl-docs/disableCalloutSyntax.ts +36 -0
- package/stl-docs/fonts.ts +186 -0
- package/stl-docs/index.ts +153 -50
- package/stl-docs/loadStlDocsConfig.ts +51 -7
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +61 -0
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +41 -0
- package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
- package/stl-docs/proseSearchIndexing.ts +606 -0
- package/stl-docs/tabsMiddleware.ts +13 -4
- package/styles/code.css +128 -136
- package/styles/links.css +11 -48
- package/styles/method-descriptions.css +36 -0
- package/styles/overrides.css +49 -57
- package/styles/page.css +100 -59
- package/styles/sdk_select.css +9 -7
- package/styles/search.css +57 -69
- package/styles/sidebar.css +26 -156
- package/styles/{variables.css → sl-variables.css} +3 -2
- package/styles/stldocs-variables.css +6 -0
- package/styles/toc.css +41 -34
- package/theme.css +11 -11
- package/tsconfig.json +2 -5
- package/virtual-module.d.ts +47 -7
- package/components/variables.css +0 -135
- package/plugin/cms/client.ts +0 -62
- package/plugin/cms/server.ts +0 -268
- package/plugin/globalJs/ai-dropdown.ts +0 -57
- package/stl-docs/components/APIReferenceAIDropdown.tsx +0 -58
- package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -55
- package/stl-docs/components/mintlify-compat/Step.astro +0 -58
- package/stl-docs/components/mintlify-compat/Steps.astro +0 -17
- package/styles/fonts.css +0 -68
- /package/{plugin/assets → assets}/fonts/geist/OFL.txt +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin.woff2 +0 -0
package/plugin/react/Routing.tsx
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { marked } from 'marked';
|
|
3
|
-
|
|
4
|
-
import {
|
|
2
|
+
import { marked, Tokens } from 'marked';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createMarkdownProcessor,
|
|
6
|
+
CreateShikiHighlighterOptions,
|
|
7
|
+
type MarkdownProcessor,
|
|
8
|
+
} from '@astrojs/markdown-remark';
|
|
5
9
|
import remarkGfmAlerts from 'remark-github-alerts';
|
|
6
10
|
|
|
7
11
|
import type { MarkdownHeading } from 'astro';
|
|
8
12
|
import type { StarlightRouteData } from '@astrojs/starlight/route-data';
|
|
9
|
-
import type * as SDKJSON from '
|
|
10
|
-
import type
|
|
13
|
+
import type * as SDKJSON from '@stainless/sdk-json';
|
|
14
|
+
import { LanguageNames, SupportedLanguageSyntaxes, type DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
11
15
|
|
|
12
16
|
import {
|
|
13
|
-
generateRouteList,
|
|
14
17
|
generateRoute,
|
|
15
18
|
parseStainlessPath,
|
|
16
19
|
walkTree,
|
|
17
|
-
SupportedLanguageSyntaxes,
|
|
18
20
|
getLanguageSnippet,
|
|
19
|
-
} from '@stainless-api/docs-ui/
|
|
21
|
+
} from '@stainless-api/docs-ui/routing';
|
|
20
22
|
|
|
21
23
|
import {
|
|
22
24
|
DocsProvider,
|
|
@@ -24,63 +26,46 @@ import {
|
|
|
24
26
|
NavigationProvider,
|
|
25
27
|
useSpec,
|
|
26
28
|
type ContentPanelLayout,
|
|
27
|
-
} from '@stainless-api/docs-ui/
|
|
29
|
+
} from '@stainless-api/docs-ui/contexts';
|
|
28
30
|
|
|
29
|
-
import { flatResources, getResourceFromSpec } from '@stainless-api/docs-ui/
|
|
31
|
+
import { flatResources, getResourceFromSpec } from '@stainless-api/docs-ui/utils';
|
|
30
32
|
|
|
31
33
|
import {
|
|
32
34
|
SDKMethod,
|
|
33
35
|
SDKResource,
|
|
34
36
|
type SDKRequestTitleProps,
|
|
35
37
|
SDKBreadcrumbs,
|
|
36
|
-
Dropdown,
|
|
37
|
-
DropdownTrigger,
|
|
38
|
-
DropdownMenu,
|
|
39
|
-
DropdownItem,
|
|
40
38
|
SDKIcon,
|
|
41
39
|
SDKOverview,
|
|
42
40
|
SDKLanguageBlock,
|
|
43
|
-
} from '@stainless-api/docs-ui/
|
|
41
|
+
} from '@stainless-api/docs-ui/components';
|
|
42
|
+
|
|
43
|
+
import { Dropdown } from '@stainless-api/docs/components';
|
|
44
|
+
|
|
44
45
|
import {
|
|
45
|
-
|
|
46
|
+
RESOLVED_API_REFERENCE_PATH,
|
|
46
47
|
EXCLUDE_LANGUAGES,
|
|
47
48
|
EXPAND_RESOURCES,
|
|
48
49
|
HIGHLIGHT_THEMES,
|
|
49
50
|
BREADCRUMB_CONFIG,
|
|
50
51
|
PROPERTY_SETTINGS,
|
|
51
|
-
|
|
52
|
+
ENABLE_CONTEXT_MENU,
|
|
53
|
+
EXPERIMENTAL_COLLAPSIBLE_METHOD_DESCRIPTIONS,
|
|
52
54
|
} from 'virtual:stl-starlight-virtual-module';
|
|
53
|
-
import style from '@stainless-api/docs-ui/
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
|
|
55
|
+
import style from '@stainless-api/docs-ui/style';
|
|
56
|
+
import { BundledTheme, createHighlighter, HighlighterGeneric, type BundledLanguage } from 'shiki';
|
|
57
|
+
import {
|
|
58
|
+
SnippetCode,
|
|
59
|
+
SnippetContainer,
|
|
60
|
+
SnippetButtons,
|
|
61
|
+
SnippetFooter,
|
|
62
|
+
SnippetResponse,
|
|
63
|
+
} from '../components/SnippetCode';
|
|
57
64
|
import type { StlStarlightMiddleware } from '../middlewareBuilder/stainlessMiddleware';
|
|
58
|
-
import { ComponentProvider } from '@stainless-api/docs-ui/
|
|
59
|
-
import {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const paths = generateRouteList({
|
|
63
|
-
spec,
|
|
64
|
-
excludeLanguages: EXCLUDE_LANGUAGES as DocsLanguage[],
|
|
65
|
-
});
|
|
66
|
-
const readmes = Object.entries(spec.readme)
|
|
67
|
-
.filter(([language]) => language !== 'http')
|
|
68
|
-
.filter(([language]) => !EXCLUDE_LANGUAGES.includes(language as DocsLanguage))
|
|
69
|
-
.map(([language]) => ({
|
|
70
|
-
slug: language,
|
|
71
|
-
stainlessPath: null,
|
|
72
|
-
language: language as DocsLanguage,
|
|
73
|
-
title: 'Readme',
|
|
74
|
-
kind: 'readme',
|
|
75
|
-
}));
|
|
76
|
-
|
|
77
|
-
return [...paths, ...readmes].map(({ slug, stainlessPath, language, title, kind }) => {
|
|
78
|
-
return {
|
|
79
|
-
params: { slug },
|
|
80
|
-
props: { stainlessPath, language, title, kind },
|
|
81
|
-
};
|
|
82
|
-
});
|
|
83
|
-
}
|
|
65
|
+
import { ComponentProvider } from '@stainless-api/docs-ui/contexts/component';
|
|
66
|
+
import { AIDropdown } from '../../stl-docs/components/AIDropdown';
|
|
67
|
+
import { ChevronsUpDownIcon } from 'lucide-react';
|
|
68
|
+
import { MethodDescription } from '../components/MethodDescription';
|
|
84
69
|
|
|
85
70
|
function isResourceNonEmpty(resource: SDKJSON.Resource) {
|
|
86
71
|
return (
|
|
@@ -121,7 +106,6 @@ export function buildSidebar(
|
|
|
121
106
|
|
|
122
107
|
const meths: SidebarEntry[] = Object.values(resource.methods ?? [])
|
|
123
108
|
.filter((method) => spec.decls?.[language]?.[method.stainlessPath])
|
|
124
|
-
.toSorted((first, second) => first.name.localeCompare(second.name))
|
|
125
109
|
.map((method) => ({
|
|
126
110
|
type: 'link',
|
|
127
111
|
isCurrent: current === method.stainlessPath,
|
|
@@ -153,19 +137,58 @@ export function buildPageNavigation(resource: SDKJSON.Resource, depth: number =
|
|
|
153
137
|
return [...output, ...subs];
|
|
154
138
|
}
|
|
155
139
|
|
|
156
|
-
function renderMarkdown(content: string) {
|
|
157
|
-
|
|
140
|
+
async function renderMarkdown(content: string) {
|
|
141
|
+
const highlighter = await astroHighlight();
|
|
142
|
+
|
|
143
|
+
const renderer = {
|
|
144
|
+
code({ text, lang }: Tokens.Code) {
|
|
145
|
+
return shikiHighlight({
|
|
146
|
+
highlighter,
|
|
147
|
+
content: text,
|
|
148
|
+
language: lang,
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
marked.use({ renderer });
|
|
154
|
+
return marked.parse(content, {
|
|
155
|
+
gfm: true,
|
|
156
|
+
}) as string;
|
|
158
157
|
}
|
|
159
158
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
function shikiHighlight({
|
|
160
|
+
highlighter,
|
|
161
|
+
content,
|
|
162
|
+
language,
|
|
163
|
+
themes,
|
|
164
|
+
}: {
|
|
165
|
+
highlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
|
|
166
|
+
content: string;
|
|
167
|
+
language?: string;
|
|
168
|
+
themes?: CreateShikiHighlighterOptions['themes'] | Record<string, 'stainless-docs-json'>;
|
|
169
|
+
}) {
|
|
170
|
+
let _themes = themes;
|
|
171
|
+
if (!themes && language === 'json') {
|
|
172
|
+
_themes = {
|
|
173
|
+
light: 'stainless-docs-json',
|
|
174
|
+
dark: 'stainless-docs-json',
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!_themes) {
|
|
179
|
+
_themes = HIGHLIGHT_THEMES;
|
|
180
|
+
}
|
|
163
181
|
return highlighter.codeToHtml(content, {
|
|
164
182
|
lang: language ?? 'javascript',
|
|
165
|
-
themes:
|
|
183
|
+
themes: _themes || {},
|
|
166
184
|
});
|
|
167
185
|
}
|
|
168
186
|
|
|
187
|
+
async function highlight(content: string, language?: string) {
|
|
188
|
+
const highlighter = await astroHighlight();
|
|
189
|
+
return shikiHighlight({ highlighter, content, language });
|
|
190
|
+
}
|
|
191
|
+
|
|
169
192
|
export function SDKSelectReactComponent({
|
|
170
193
|
selected,
|
|
171
194
|
languages,
|
|
@@ -179,30 +202,36 @@ export function SDKSelectReactComponent({
|
|
|
179
202
|
}) {
|
|
180
203
|
return (
|
|
181
204
|
<Dropdown id={id} data-current-value={selected} className={className}>
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
205
|
+
<Dropdown.Trigger>
|
|
206
|
+
<Dropdown.TriggerSelectedItem>
|
|
207
|
+
<Dropdown.Icon>
|
|
208
|
+
<SDKIcon language={getLanguageSnippet(selected)} />
|
|
209
|
+
</Dropdown.Icon>
|
|
210
|
+
<span className="stl-snippet-dropdown-button-text">{LanguageNames[selected]}</span>
|
|
211
|
+
</Dropdown.TriggerSelectedItem>
|
|
212
|
+
<Dropdown.TriggerIcon>
|
|
213
|
+
<ChevronsUpDownIcon size={16} />
|
|
214
|
+
</Dropdown.TriggerIcon>
|
|
215
|
+
</Dropdown.Trigger>
|
|
216
|
+
<Dropdown.Menu
|
|
193
217
|
className="dropdown-menu stl-sdk-select-dropdown-menu"
|
|
194
|
-
|
|
195
|
-
aria-labelledby="stldocs-snippet-title-button"
|
|
218
|
+
aria-labelledby="stl-docs-snippet-title-button"
|
|
196
219
|
>
|
|
197
220
|
{languages.map((item) => (
|
|
198
|
-
<
|
|
199
|
-
<
|
|
221
|
+
<Dropdown.MenuItem key={item} value={item} isSelected={item === selected}>
|
|
222
|
+
<Dropdown.Icon>
|
|
200
223
|
<SDKIcon language={getLanguageSnippet(item)} size={16} />
|
|
201
|
-
|
|
202
|
-
</
|
|
203
|
-
|
|
224
|
+
</Dropdown.Icon>
|
|
225
|
+
<Dropdown.MenuItemText>{LanguageNames[item]}</Dropdown.MenuItemText>
|
|
226
|
+
<Dropdown.MenuItemTemplate>
|
|
227
|
+
<Dropdown.Icon>
|
|
228
|
+
<SDKIcon language={getLanguageSnippet(item)} size={16} />
|
|
229
|
+
</Dropdown.Icon>
|
|
230
|
+
<span className="stl-snippet-dropdown-button-text">{LanguageNames[item]}</span>
|
|
231
|
+
</Dropdown.MenuItemTemplate>
|
|
232
|
+
</Dropdown.MenuItem>
|
|
204
233
|
))}
|
|
205
|
-
</
|
|
234
|
+
</Dropdown.Menu>
|
|
206
235
|
</Dropdown>
|
|
207
236
|
);
|
|
208
237
|
}
|
|
@@ -218,13 +247,13 @@ function SDKRequestTitle({ snippetLanguage }: SDKRequestTitleProps) {
|
|
|
218
247
|
selected={selected || 'http'}
|
|
219
248
|
languages={languages}
|
|
220
249
|
id="stldocs-snippet-select"
|
|
221
|
-
className="stl-sdk-select"
|
|
250
|
+
className="stl-sdk-select stl-ui-not-prose"
|
|
222
251
|
/>
|
|
223
252
|
);
|
|
224
253
|
}
|
|
225
254
|
|
|
226
255
|
export type SpecMetadata = [
|
|
227
|
-
|
|
256
|
+
DocsLanguage,
|
|
228
257
|
{
|
|
229
258
|
repo_url?: string;
|
|
230
259
|
code_url?: string;
|
|
@@ -234,15 +263,26 @@ export type SpecMetadata = [
|
|
|
234
263
|
},
|
|
235
264
|
][];
|
|
236
265
|
|
|
266
|
+
const componentOverrides = {
|
|
267
|
+
SDKRequestTitle,
|
|
268
|
+
SnippetCode,
|
|
269
|
+
SnippetContainer,
|
|
270
|
+
SnippetButtons,
|
|
271
|
+
SnippetFooter,
|
|
272
|
+
SnippetResponse,
|
|
273
|
+
...(EXPERIMENTAL_COLLAPSIBLE_METHOD_DESCRIPTIONS ? { MethodDescription } : {}),
|
|
274
|
+
} satisfies React.ComponentProps<typeof ComponentProvider>['components'];
|
|
275
|
+
|
|
237
276
|
export function RenderLibraries({ metadata }: { metadata: SpecMetadata }) {
|
|
238
277
|
return (
|
|
239
|
-
<ComponentProvider components={
|
|
278
|
+
<ComponentProvider components={componentOverrides}>
|
|
240
279
|
{metadata.map(([language, data]) => (
|
|
241
280
|
<SDKLanguageBlock
|
|
281
|
+
key={language}
|
|
242
282
|
language={language}
|
|
243
283
|
version={data.version || ''}
|
|
244
284
|
install={data.install || ''}
|
|
245
|
-
links={{ repo: data.repo_url || '#', docs: `${
|
|
285
|
+
links={{ repo: data.repo_url || '#', docs: `${RESOLVED_API_REFERENCE_PATH}/${language}` }}
|
|
246
286
|
/>
|
|
247
287
|
))}
|
|
248
288
|
</ComponentProvider>
|
|
@@ -254,15 +294,8 @@ export function RenderSpecOverview({ spec, language }: { spec: SDKJSON.Spec; lan
|
|
|
254
294
|
|
|
255
295
|
return (
|
|
256
296
|
<DocsProvider spec={spec} language={language ?? 'node'}>
|
|
257
|
-
<ComponentProvider
|
|
258
|
-
|
|
259
|
-
SDKRequestTitle,
|
|
260
|
-
SnippetCode,
|
|
261
|
-
SnippetContainer,
|
|
262
|
-
SnippetRequestContainer,
|
|
263
|
-
}}
|
|
264
|
-
>
|
|
265
|
-
<NavigationProvider basePath={BASE_PATH}>
|
|
297
|
+
<ComponentProvider components={componentOverrides}>
|
|
298
|
+
<NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH}>
|
|
266
299
|
<MarkdownProvider render={renderMarkdown} highlight={highlight}>
|
|
267
300
|
<div className={style.Overview}>
|
|
268
301
|
{resources
|
|
@@ -303,7 +336,10 @@ export function RenderSpec({
|
|
|
303
336
|
const parsed = parseStainlessPath(path);
|
|
304
337
|
const resource = getResourceFromSpec(path, spec);
|
|
305
338
|
|
|
306
|
-
if (!resource || !parsed)
|
|
339
|
+
if (!resource || !parsed) {
|
|
340
|
+
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
307
343
|
|
|
308
344
|
return (
|
|
309
345
|
<DocsProvider
|
|
@@ -314,46 +350,30 @@ export function RenderSpec({
|
|
|
314
350
|
properties: PROPERTY_SETTINGS,
|
|
315
351
|
}}
|
|
316
352
|
>
|
|
317
|
-
<ComponentProvider
|
|
318
|
-
|
|
319
|
-
SDKRequestTitle,
|
|
320
|
-
SnippetCode,
|
|
321
|
-
SnippetContainer,
|
|
322
|
-
SnippetRequestContainer,
|
|
323
|
-
}}
|
|
324
|
-
>
|
|
325
|
-
<NavigationProvider basePath={BASE_PATH} selectedPath={path}>
|
|
353
|
+
<ComponentProvider components={componentOverrides}>
|
|
354
|
+
<NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH} selectedPath={path}>
|
|
326
355
|
<MarkdownProvider render={renderMarkdown} highlight={highlight}>
|
|
327
|
-
{
|
|
356
|
+
{
|
|
328
357
|
<div className="stldocs-root stl-ui-not-prose">
|
|
329
358
|
<div className="stl-page-nav-container">
|
|
330
359
|
<SDKBreadcrumbs
|
|
331
360
|
spec={spec as SDKJSON.Spec}
|
|
332
361
|
currentPath={currentPath}
|
|
333
|
-
basePath={
|
|
362
|
+
basePath={RESOLVED_API_REFERENCE_PATH}
|
|
334
363
|
config={BREADCRUMB_CONFIG}
|
|
335
364
|
/>
|
|
336
|
-
{
|
|
365
|
+
{ENABLE_CONTEXT_MENU && <AIDropdown />}
|
|
337
366
|
</div>
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
</div>
|
|
343
|
-
) : (
|
|
344
|
-
<div className="stldocs-root stl-ui-not-prose">
|
|
345
|
-
<div className="stl-page-nav-container">
|
|
346
|
-
<SDKBreadcrumbs
|
|
347
|
-
spec={spec as SDKJSON.Spec}
|
|
348
|
-
currentPath={currentPath}
|
|
349
|
-
basePath={BASE_PATH}
|
|
350
|
-
config={BREADCRUMB_CONFIG}
|
|
367
|
+
{kind === 'http_method' ? (
|
|
368
|
+
<SDKMethod
|
|
369
|
+
method={resource.methods[parsed.method!]!}
|
|
370
|
+
transformRequestSnippet={transformRequestSnippet}
|
|
351
371
|
/>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
372
|
+
) : (
|
|
373
|
+
<SDKOverview resource={resource} />
|
|
374
|
+
)}
|
|
355
375
|
</div>
|
|
356
|
-
|
|
376
|
+
}
|
|
357
377
|
</MarkdownProvider>
|
|
358
378
|
</NavigationProvider>
|
|
359
379
|
</ComponentProvider>
|
|
@@ -367,10 +387,14 @@ export function RenderMethod({ path }: { path: string }) {
|
|
|
367
387
|
|
|
368
388
|
const parsed = parseStainlessPath(path);
|
|
369
389
|
const resource = getResourceFromSpec(path, spec);
|
|
370
|
-
if (!resource || !parsed) return null;
|
|
371
390
|
|
|
372
|
-
|
|
373
|
-
|
|
391
|
+
if (!resource || !parsed) {
|
|
392
|
+
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const method = resource.methods[parsed.method!]!;
|
|
397
|
+
return <SDKMethod method={method} />;
|
|
374
398
|
}
|
|
375
399
|
|
|
376
400
|
export async function getReadmeContent(spec: SDKJSON.Spec, language: DocsLanguage) {
|
|
@@ -390,8 +414,68 @@ export async function getReadmeContent(spec: SDKJSON.Spec, language: DocsLanguag
|
|
|
390
414
|
return spec.readme[language];
|
|
391
415
|
}
|
|
392
416
|
|
|
417
|
+
let astroShikiHighlighter:
|
|
418
|
+
| HighlighterGeneric<BundledLanguage, BundledTheme>
|
|
419
|
+
| Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>
|
|
420
|
+
| null = null;
|
|
421
|
+
|
|
422
|
+
async function astroHighlight() {
|
|
423
|
+
if (astroShikiHighlighter) {
|
|
424
|
+
return astroShikiHighlighter;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
astroShikiHighlighter = createHighlighter({
|
|
428
|
+
themes: [
|
|
429
|
+
'github-light',
|
|
430
|
+
'github-dark',
|
|
431
|
+
{
|
|
432
|
+
name: 'stainless-docs-json',
|
|
433
|
+
colors: {
|
|
434
|
+
'editor.background': 'var(--stl-color-background)',
|
|
435
|
+
'editor.foreground': 'var(--stl-color-foreground)',
|
|
436
|
+
},
|
|
437
|
+
|
|
438
|
+
tokenColors: [
|
|
439
|
+
{
|
|
440
|
+
scope: ['comment', 'punctuation.definition.comment'],
|
|
441
|
+
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
442
|
+
},
|
|
443
|
+
// numbers, booleans, null
|
|
444
|
+
{
|
|
445
|
+
scope: ['constant.numeric', 'constant.language'],
|
|
446
|
+
settings: { foreground: 'var(--stl-color-orange-foreground)' },
|
|
447
|
+
},
|
|
448
|
+
// strings
|
|
449
|
+
{
|
|
450
|
+
scope: ['string', 'string.quoted', 'string.template'],
|
|
451
|
+
settings: { foreground: 'var(--stl-color-green-foreground)' },
|
|
452
|
+
},
|
|
453
|
+
// Keys, brackets
|
|
454
|
+
{
|
|
455
|
+
scope: ['support.type', 'meta'],
|
|
456
|
+
settings: { foreground: 'var(--stl-color-foreground)' },
|
|
457
|
+
},
|
|
458
|
+
// brackets
|
|
459
|
+
{
|
|
460
|
+
scope: ['meta'],
|
|
461
|
+
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
462
|
+
},
|
|
463
|
+
// built-in types
|
|
464
|
+
{
|
|
465
|
+
scope: ['support.type.builtin'],
|
|
466
|
+
settings: { foreground: 'var(--stl-color-purple-foreground)' },
|
|
467
|
+
},
|
|
468
|
+
],
|
|
469
|
+
},
|
|
470
|
+
],
|
|
471
|
+
langs: SupportedLanguageSyntaxes,
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
return astroShikiHighlighter;
|
|
475
|
+
}
|
|
476
|
+
|
|
393
477
|
// Astro's markdown processor is a singleton
|
|
394
|
-
// Need to cache it instead of
|
|
478
|
+
// Need to cache it instead of instantiating per request
|
|
395
479
|
let astroMarkdownProcessor: MarkdownProcessor;
|
|
396
480
|
async function astroMarkdown() {
|
|
397
481
|
if (!astroMarkdownProcessor) {
|
|
@@ -407,18 +491,6 @@ async function astroMarkdown() {
|
|
|
407
491
|
return astroMarkdownProcessor;
|
|
408
492
|
}
|
|
409
493
|
|
|
410
|
-
let astroShikiHighlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
|
|
411
|
-
async function astroHighlight() {
|
|
412
|
-
if (!astroShikiHighlighter) {
|
|
413
|
-
astroShikiHighlighter = await createHighlighter({
|
|
414
|
-
themes: ['github-light', 'github-dark'],
|
|
415
|
-
langs: SupportedLanguageSyntaxes,
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return astroShikiHighlighter;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
494
|
export async function astroMarkdownRender(content: string) {
|
|
423
495
|
const md = await astroMarkdown();
|
|
424
496
|
const output = await md.render(content);
|
|
@@ -21,27 +21,30 @@ export function makePlaceholderItems(id: number) {
|
|
|
21
21
|
|
|
22
22
|
type StarlightConfig = Parameters<typeof starlight>[0];
|
|
23
23
|
|
|
24
|
-
type SidebarConfigEntry = Exclude<StarlightConfig['sidebar'], undefined>[number];
|
|
24
|
+
export type SidebarConfigEntry = Exclude<StarlightConfig['sidebar'], undefined>[number];
|
|
25
25
|
|
|
26
26
|
export function getAPIReferencePlaceholderItemFromSidebarConfig(
|
|
27
27
|
sidebar: SidebarConfigEntry[],
|
|
28
|
-
): SidebarConfigEntry
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
): SidebarConfigEntry[] {
|
|
29
|
+
const items: SidebarConfigEntry[] = [];
|
|
30
|
+
|
|
31
|
+
function recursiveGetPlaceholderItems(entries: SidebarConfigEntry[]) {
|
|
32
|
+
for (const item of entries) {
|
|
33
|
+
if (typeof item === 'string') {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if ('attrs' in item && item.attrs?.about === INTERNAL_REFERENCE_ENTRY_MARKER) {
|
|
37
|
+
items.push(item);
|
|
38
|
+
}
|
|
39
|
+
if ('items' in item) {
|
|
40
|
+
recursiveGetPlaceholderItems(item.items);
|
|
37
41
|
}
|
|
38
|
-
}
|
|
39
|
-
if ('attrs' in item && item.attrs?.about === INTERNAL_REFERENCE_ENTRY_MARKER) {
|
|
40
|
-
return item;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
recursiveGetPlaceholderItems(sidebar);
|
|
46
|
+
|
|
47
|
+
return items;
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
type SidebarEntry = StarlightRouteData['sidebar'][number];
|
|
@@ -58,7 +61,7 @@ function recursiveGetPlaceholderItems(
|
|
|
58
61
|
items: PlaceholderItemResult[],
|
|
59
62
|
): PlaceholderItemResult[] {
|
|
60
63
|
for (let i = 0; i < sidebar.length; i++) {
|
|
61
|
-
const entry = sidebar[i]
|
|
64
|
+
const entry = sidebar[i]!;
|
|
62
65
|
if ('attrs' in entry && entry.attrs?.about === INTERNAL_REFERENCE_ENTRY_MARKER) {
|
|
63
66
|
items.push({
|
|
64
67
|
index: i,
|
|
@@ -1,54 +1,58 @@
|
|
|
1
|
-
import { defineRouteMiddleware } from '@astrojs/starlight/route-data';
|
|
1
|
+
import { defineRouteMiddleware, StarlightRouteData } from '@astrojs/starlight/route-data';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { BASE_PATH } from 'virtual:stl-starlight-virtual-module';
|
|
3
|
+
import { RESOLVED_API_REFERENCE_PATH } from 'virtual:stl-starlight-virtual-module';
|
|
5
4
|
import { getAPIReferencePlaceholderItems } from './referencePlaceholderUtils';
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
5
|
+
import { parseRoute } from '@stainless-api/docs-ui/routing';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { sidebars } from 'virtual:stl-starlight-reference-sidebars';
|
|
9
8
|
|
|
10
9
|
// this fn is loaded in the plugin via addRouteMiddleware
|
|
11
10
|
|
|
11
|
+
type SidebarEntry = StarlightRouteData['sidebar'][number];
|
|
12
|
+
|
|
13
|
+
const removeTrailingSlash = (value: string) => (value.endsWith('/') ? value.slice(0, -1) : value);
|
|
14
|
+
|
|
15
|
+
function markCurrentItems(sidebar: SidebarEntry[], currentSlug: string) {
|
|
16
|
+
// IMPORTANT: we need to clone the sidebar to avoid mutating the original sidebar
|
|
17
|
+
const mutableSidebarInstance = structuredClone(sidebar);
|
|
18
|
+
const normalizedCurrentSlug = removeTrailingSlash(currentSlug);
|
|
19
|
+
|
|
20
|
+
function recursiveMarkCurrent(entries: SidebarEntry[]) {
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
if (entry.type === 'link') {
|
|
23
|
+
entry.isCurrent = removeTrailingSlash(entry.href) === normalizedCurrentSlug;
|
|
24
|
+
}
|
|
25
|
+
if (entry.type === 'group') {
|
|
26
|
+
recursiveMarkCurrent(entry.entries);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
recursiveMarkCurrent(mutableSidebarInstance);
|
|
31
|
+
|
|
32
|
+
return mutableSidebarInstance;
|
|
33
|
+
}
|
|
34
|
+
|
|
12
35
|
export const onRequest = defineRouteMiddleware(async (context) => {
|
|
13
36
|
// if using content collection schema, use: context.locals.starlightRoute.entry.data.stainlessStarlight
|
|
14
37
|
// this worked without collections but relied on hijacking starlightRoute: context.props.frontmatter.stainlessStarlight
|
|
15
|
-
|
|
16
|
-
const slug = `/${context.locals.starlightRoute.id}`; // same as .slug but not deprecated
|
|
38
|
+
const slug = path.posix.join(import.meta.env.BASE_URL ?? '', `/${context.locals.starlightRoute.id}`); // same as .slug but not deprecated
|
|
17
39
|
|
|
18
40
|
context.locals.starlightRoute._stlStarlight = {
|
|
19
|
-
basePath:
|
|
41
|
+
basePath: RESOLVED_API_REFERENCE_PATH,
|
|
20
42
|
};
|
|
21
43
|
|
|
22
44
|
const apiReferencePlaceholderItems = getAPIReferencePlaceholderItems(context.locals.starlightRoute.sidebar);
|
|
23
45
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
const { language, stainlessPath } = parseRoute(BASE_PATH, slug);
|
|
27
|
-
|
|
28
|
-
// This is probably temporary, but it fills in functionality needed for Mintlify imports
|
|
29
|
-
recursiveReplacePlaceholderItems(context.locals.starlightRoute.sidebar, (entry, { endpoint, label }) => {
|
|
30
|
-
const method = getMethodFromSDKJSON(spec, endpoint);
|
|
31
|
-
|
|
32
|
-
const route = forceGenerateRoute({
|
|
33
|
-
basePath: BASE_PATH,
|
|
34
|
-
stainlessPath: method.stainlessPath,
|
|
35
|
-
language,
|
|
36
|
-
});
|
|
37
|
-
entry.href = route;
|
|
38
|
-
entry.isCurrent = method.stainlessPath === stainlessPath;
|
|
39
|
-
if (!label) {
|
|
40
|
-
entry.label = method.summary ?? method.name;
|
|
41
|
-
}
|
|
42
|
-
entry.attrs['data-stldocs-method'] = method.httpMethod;
|
|
43
|
-
});
|
|
46
|
+
const { language } = parseRoute(RESOLVED_API_REFERENCE_PATH, slug);
|
|
44
47
|
|
|
45
48
|
for (const item of apiReferencePlaceholderItems) {
|
|
46
|
-
const entries =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
});
|
|
49
|
+
const entries = sidebars.find((sb) => sb.id === item.sidebarId && sb.language === language)?.entries;
|
|
50
|
+
if (!entries) {
|
|
51
|
+
throw new Error(`Expected sidebar entries for sidebar ID ${item.sidebarId} and language ${language}`);
|
|
52
|
+
}
|
|
51
53
|
|
|
52
54
|
item.group.splice(item.index, 1, ...entries);
|
|
53
55
|
}
|
|
56
|
+
|
|
57
|
+
context.locals.starlightRoute.sidebar = markCurrentItems(context.locals.starlightRoute.sidebar, slug);
|
|
54
58
|
});
|