@stainless-api/docs 0.1.0-beta.12 → 0.1.0-beta.121
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 +1012 -0
- package/eslint-suppressions.json +95 -0
- package/{eslint.config.js → eslint.config.ts} +0 -2
- package/locals.d.ts +17 -0
- package/package.json +57 -43
- 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/assets/languages/php.svg +4 -0
- package/plugin/buildAlgoliaIndex.ts +40 -39
- 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 +40 -0
- package/plugin/components/RequestBuilder/props.ts +9 -0
- package/plugin/components/RequestBuilder/spec-helpers.ts +47 -0
- package/plugin/components/RequestBuilder/styles.css +67 -0
- package/plugin/components/SDKSelect.astro +18 -111
- package/plugin/components/SnippetCode.tsx +112 -70
- package/plugin/components/StainlessIslands.tsx +126 -0
- package/plugin/components/search/SearchAlgolia.astro +46 -29
- package/plugin/components/search/SearchIsland.tsx +61 -37
- package/plugin/generateAPIReferenceLink.ts +2 -2
- package/plugin/globalJs/ai-dropdown-options.ts +248 -0
- package/plugin/globalJs/code-snippets.ts +45 -16
- package/plugin/globalJs/copy.ts +115 -27
- package/plugin/globalJs/create-playground.shim.ts +3 -0
- package/plugin/globalJs/method-descriptions.ts +33 -0
- package/plugin/globalJs/navigation.ts +15 -33
- package/plugin/globalJs/playground-data.shim.ts +1 -0
- package/plugin/globalJs/playground-data.ts +14 -0
- package/plugin/globalJs/summary-selection-tweak.ts +29 -0
- package/plugin/helpers/generateDocsRoutes.ts +59 -0
- package/plugin/helpers/multiSpec.ts +8 -0
- package/plugin/index.ts +306 -142
- package/plugin/languages.ts +8 -2
- package/plugin/loadPluginConfig.ts +251 -107
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +3 -1
- package/plugin/react/Routing.tsx +214 -143
- package/plugin/referencePlaceholderUtils.ts +18 -15
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +39 -35
- package/plugin/routes/Docs.astro +71 -111
- package/plugin/routes/DocsStatic.astro +6 -5
- package/plugin/routes/Overview.astro +46 -22
- package/plugin/routes/markdown.ts +13 -12
- package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +83 -63
- package/plugin/specs/FileCache.ts +99 -0
- package/plugin/specs/fetchSpecSSR.ts +27 -0
- package/plugin/specs/generateSpec.ts +112 -0
- package/plugin/specs/index.ts +137 -0
- package/plugin/specs/inputResolver.ts +148 -0
- package/plugin/{cms → specs}/worker.ts +82 -5
- package/plugin/vendor/preview.worker.docs.js +27234 -17991
- package/plugin/vendor/templates/cli.md +1 -0
- package/plugin/vendor/templates/go.md +4 -2
- package/plugin/vendor/templates/java.md +5 -1
- package/plugin/vendor/templates/kotlin.md +5 -1
- package/plugin/vendor/templates/node.md +4 -2
- package/plugin/vendor/templates/python.md +4 -2
- package/plugin/vendor/templates/ruby.md +4 -2
- package/plugin/vendor/templates/terraform.md +1 -1
- package/plugin/vendor/templates/typescript.md +3 -1
- package/resolveSrcFile.ts +10 -0
- package/scripts/vendor_deps.ts +5 -5
- package/shared/conditionalIntegration.ts +28 -0
- package/shared/getProsePages.ts +41 -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/ContentPanel.astro +9 -0
- package/stl-docs/components/Footer.astro +89 -0
- package/stl-docs/components/Head.astro +20 -0
- package/stl-docs/components/Header.astro +3 -10
- package/stl-docs/components/PageFrame.astro +34 -0
- package/stl-docs/components/PageSidebar.astro +11 -0
- package/stl-docs/components/PageTitle.astro +82 -0
- package/stl-docs/components/StainlessLogo.svg +4 -0
- package/stl-docs/components/TableOfContents.astro +34 -0
- package/stl-docs/components/ThemeProvider.astro +36 -0
- package/stl-docs/components/ThemeSelect.astro +84 -146
- package/stl-docs/components/TwoColumnContent.astro +2 -0
- package/stl-docs/components/headers/DefaultHeader.astro +4 -6
- package/stl-docs/components/headers/StackedHeader.astro +8 -51
- 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/Frame.astro +4 -4
- package/stl-docs/components/mintlify-compat/card.css +4 -4
- package/stl-docs/components/mintlify-compat/index.ts +2 -4
- package/stl-docs/components/nav-tabs/NavDropdown.astro +31 -75
- package/stl-docs/components/nav-tabs/NavTabs.astro +79 -81
- package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -7
- 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 +177 -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 +80 -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 +178 -54
- package/stl-docs/loadStlDocsConfig.ts +64 -8
- package/stl-docs/proseDocSync.ts +314 -0
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +53 -0
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +41 -0
- package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
- package/stl-docs/proseSearchIndexing.ts +222 -0
- package/stl-docs/tabsMiddleware.ts +14 -5
- package/styles/code.css +53 -49
- package/styles/links.css +2 -37
- package/styles/method-descriptions.css +36 -0
- package/styles/overrides.css +28 -46
- package/styles/page.css +230 -52
- package/styles/sdk_select.css +9 -6
- package/styles/search.css +11 -21
- package/styles/sidebar.css +28 -211
- package/styles/{variables.css → sl-variables.css} +4 -8
- package/styles/stldocs-variables.css +6 -0
- package/styles/toc.css +19 -8
- package/theme.css +11 -9
- package/tsconfig.json +1 -4
- package/virtual-module.d.ts +65 -8
- package/components/variables.css +0 -112
- 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/ContentPanel.astro +0 -69
- package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -55
- package/stl-docs/components/headers/SplashMobileMenuToggle.astro +0 -49
- package/stl-docs/components/mintlify-compat/Step.astro +0 -56
- package/stl-docs/components/mintlify-compat/Steps.astro +0 -15
- 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,25 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { marked } from 'marked';
|
|
3
|
-
import
|
|
4
|
-
|
|
2
|
+
import { marked, Tokens } from 'marked';
|
|
3
|
+
import { getDocsLanguages } from '../helpers/multiSpec';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
createMarkdownProcessor,
|
|
7
|
+
CreateShikiHighlighterOptions,
|
|
8
|
+
type MarkdownProcessor,
|
|
9
|
+
} from '@astrojs/markdown-remark';
|
|
5
10
|
import remarkGfmAlerts from 'remark-github-alerts';
|
|
6
11
|
|
|
7
12
|
import type { MarkdownHeading } from 'astro';
|
|
8
13
|
import type { StarlightRouteData } from '@astrojs/starlight/route-data';
|
|
9
|
-
import type * as SDKJSON from '
|
|
10
|
-
import type
|
|
14
|
+
import type * as SDKJSON from '@stainless/sdk-json';
|
|
15
|
+
import { LanguageNames, SupportedLanguageSyntaxes, type DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
11
16
|
|
|
12
17
|
import {
|
|
13
|
-
generateRouteList,
|
|
14
18
|
generateRoute,
|
|
15
19
|
parseStainlessPath,
|
|
16
20
|
walkTree,
|
|
17
|
-
SupportedLanguageSyntaxes,
|
|
18
21
|
getLanguageSnippet,
|
|
19
|
-
} from '@stainless-api/docs-ui/
|
|
22
|
+
} from '@stainless-api/docs-ui/routing';
|
|
20
23
|
|
|
21
24
|
import {
|
|
22
25
|
DocsProvider,
|
|
@@ -24,63 +27,46 @@ import {
|
|
|
24
27
|
NavigationProvider,
|
|
25
28
|
useSpec,
|
|
26
29
|
type ContentPanelLayout,
|
|
27
|
-
} from '@stainless-api/docs-ui/
|
|
30
|
+
} from '@stainless-api/docs-ui/contexts';
|
|
28
31
|
|
|
29
|
-
import { flatResources, getResourceFromSpec } from '@stainless-api/docs-ui/
|
|
32
|
+
import { flatResources, getResourceFromSpec } from '@stainless-api/docs-ui/utils';
|
|
30
33
|
|
|
31
34
|
import {
|
|
32
35
|
SDKMethod,
|
|
33
36
|
SDKResource,
|
|
34
37
|
type SDKRequestTitleProps,
|
|
35
38
|
SDKBreadcrumbs,
|
|
36
|
-
Dropdown,
|
|
37
|
-
DropdownTrigger,
|
|
38
|
-
DropdownMenu,
|
|
39
|
-
DropdownItem,
|
|
40
39
|
SDKIcon,
|
|
41
40
|
SDKOverview,
|
|
42
41
|
SDKLanguageBlock,
|
|
43
|
-
} from '@stainless-api/docs-ui/
|
|
42
|
+
} from '@stainless-api/docs-ui/components';
|
|
43
|
+
|
|
44
|
+
import { Dropdown } from '@stainless-api/docs/components';
|
|
45
|
+
|
|
44
46
|
import {
|
|
45
|
-
|
|
46
|
-
EXCLUDE_LANGUAGES,
|
|
47
|
+
RESOLVED_API_REFERENCE_PATH,
|
|
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,
|
|
54
|
+
MIDDLEWARE,
|
|
52
55
|
} from 'virtual:stl-starlight-virtual-module';
|
|
53
|
-
import style from '@stainless-api/docs-ui/
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
|
|
56
|
+
import style from '@stainless-api/docs-ui/style';
|
|
57
|
+
import { BundledTheme, createHighlighter, HighlighterGeneric, type BundledLanguage } from 'shiki';
|
|
58
|
+
import {
|
|
59
|
+
SnippetCode,
|
|
60
|
+
SnippetContainer,
|
|
61
|
+
SnippetButtons,
|
|
62
|
+
SnippetFooter,
|
|
63
|
+
SnippetResponse,
|
|
64
|
+
} from '../components/SnippetCode';
|
|
57
65
|
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
|
-
}
|
|
66
|
+
import { ComponentProvider } from '@stainless-api/docs-ui/contexts/component';
|
|
67
|
+
import { AIDropdown } from '../../stl-docs/components/AIDropdown';
|
|
68
|
+
import { ChevronsUpDownIcon } from 'lucide-react';
|
|
69
|
+
import { MethodDescription } from '../components/MethodDescription';
|
|
84
70
|
|
|
85
71
|
function isResourceNonEmpty(resource: SDKJSON.Resource) {
|
|
86
72
|
return (
|
|
@@ -121,7 +107,6 @@ export function buildSidebar(
|
|
|
121
107
|
|
|
122
108
|
const meths: SidebarEntry[] = Object.values(resource.methods ?? [])
|
|
123
109
|
.filter((method) => spec.decls?.[language]?.[method.stainlessPath])
|
|
124
|
-
.toSorted((first, second) => first.name.localeCompare(second.name))
|
|
125
110
|
.map((method) => ({
|
|
126
111
|
type: 'link',
|
|
127
112
|
isCurrent: current === method.stainlessPath,
|
|
@@ -153,78 +138,120 @@ export function buildPageNavigation(resource: SDKJSON.Resource, depth: number =
|
|
|
153
138
|
return [...output, ...subs];
|
|
154
139
|
}
|
|
155
140
|
|
|
156
|
-
function renderMarkdown(content: string) {
|
|
157
|
-
|
|
141
|
+
async function renderMarkdown(content: string) {
|
|
142
|
+
const highlighter = await astroHighlight();
|
|
143
|
+
|
|
144
|
+
const renderer = {
|
|
145
|
+
code({ text, lang }: Tokens.Code) {
|
|
146
|
+
return shikiHighlight({
|
|
147
|
+
highlighter,
|
|
148
|
+
content: text,
|
|
149
|
+
language: lang,
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
marked.use({ renderer });
|
|
155
|
+
return marked.parse(content, {
|
|
156
|
+
gfm: true,
|
|
157
|
+
}) as string;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
function shikiHighlight({
|
|
161
|
+
highlighter,
|
|
162
|
+
content,
|
|
163
|
+
language,
|
|
164
|
+
themes,
|
|
165
|
+
}: {
|
|
166
|
+
highlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
|
|
167
|
+
content: string;
|
|
168
|
+
language?: string;
|
|
169
|
+
themes?: CreateShikiHighlighterOptions['themes'] | Record<string, 'stainless-docs-json'>;
|
|
170
|
+
}) {
|
|
171
|
+
let _themes = themes;
|
|
172
|
+
if (!themes && language === 'json') {
|
|
173
|
+
_themes = {
|
|
174
|
+
light: 'stainless-docs-json',
|
|
175
|
+
dark: 'stainless-docs-json',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!_themes) {
|
|
180
|
+
_themes = HIGHLIGHT_THEMES;
|
|
181
|
+
}
|
|
163
182
|
return highlighter.codeToHtml(content, {
|
|
164
183
|
lang: language ?? 'javascript',
|
|
165
|
-
themes:
|
|
184
|
+
themes: _themes || {},
|
|
166
185
|
});
|
|
167
186
|
}
|
|
168
187
|
|
|
188
|
+
async function highlight(content: string, language?: string) {
|
|
189
|
+
const highlighter = await astroHighlight();
|
|
190
|
+
return shikiHighlight({ highlighter, content, language });
|
|
191
|
+
}
|
|
192
|
+
|
|
169
193
|
export function SDKSelectReactComponent({
|
|
170
194
|
selected,
|
|
171
195
|
languages,
|
|
172
|
-
id,
|
|
173
196
|
className,
|
|
197
|
+
...rest
|
|
174
198
|
}: {
|
|
175
199
|
selected: DocsLanguage;
|
|
176
200
|
languages: DocsLanguage[];
|
|
177
|
-
id: string;
|
|
178
201
|
className?: string;
|
|
179
|
-
}) {
|
|
202
|
+
} & Omit<React.ComponentProps<'div'>, 'children'>) {
|
|
180
203
|
return (
|
|
181
|
-
<Dropdown
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
204
|
+
<Dropdown data-current-value={selected} className={className} {...rest}>
|
|
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
|
}
|
|
209
238
|
|
|
210
239
|
function SDKRequestTitle({ snippetLanguage }: SDKRequestTitleProps) {
|
|
211
|
-
const spec = useSpec();
|
|
212
|
-
|
|
213
240
|
const selected = snippetLanguage.split('.').at(0) as DocsLanguage;
|
|
214
|
-
const languages = (
|
|
241
|
+
const languages = getDocsLanguages();
|
|
215
242
|
|
|
216
243
|
return (
|
|
217
244
|
<SDKSelectReactComponent
|
|
218
245
|
selected={selected || 'http'}
|
|
219
246
|
languages={languages}
|
|
220
|
-
|
|
221
|
-
className="stl-sdk-select"
|
|
247
|
+
data-stldocs-snippet-select
|
|
248
|
+
className="stl-sdk-select stl-ui-not-prose"
|
|
222
249
|
/>
|
|
223
250
|
);
|
|
224
251
|
}
|
|
225
252
|
|
|
226
253
|
export type SpecMetadata = [
|
|
227
|
-
|
|
254
|
+
DocsLanguage,
|
|
228
255
|
{
|
|
229
256
|
repo_url?: string;
|
|
230
257
|
code_url?: string;
|
|
@@ -234,15 +261,27 @@ export type SpecMetadata = [
|
|
|
234
261
|
},
|
|
235
262
|
][];
|
|
236
263
|
|
|
264
|
+
const componentOverrides = {
|
|
265
|
+
SDKRequestTitle,
|
|
266
|
+
SnippetCode,
|
|
267
|
+
SnippetContainer,
|
|
268
|
+
SnippetButtons,
|
|
269
|
+
SnippetFooter,
|
|
270
|
+
SnippetResponse,
|
|
271
|
+
...(EXPERIMENTAL_COLLAPSIBLE_METHOD_DESCRIPTIONS ? { MethodDescription } : {}),
|
|
272
|
+
...MIDDLEWARE.componentOverrides,
|
|
273
|
+
} satisfies React.ComponentProps<typeof ComponentProvider>['components'];
|
|
274
|
+
|
|
237
275
|
export function RenderLibraries({ metadata }: { metadata: SpecMetadata }) {
|
|
238
276
|
return (
|
|
239
|
-
<ComponentProvider components={
|
|
277
|
+
<ComponentProvider components={componentOverrides}>
|
|
240
278
|
{metadata.map(([language, data]) => (
|
|
241
279
|
<SDKLanguageBlock
|
|
280
|
+
key={language}
|
|
242
281
|
language={language}
|
|
243
282
|
version={data.version || ''}
|
|
244
283
|
install={data.install || ''}
|
|
245
|
-
links={{ repo: data.repo_url || '#', docs: `${
|
|
284
|
+
links={{ repo: data.repo_url || '#', docs: `${RESOLVED_API_REFERENCE_PATH}/${language}` }}
|
|
246
285
|
/>
|
|
247
286
|
))}
|
|
248
287
|
</ComponentProvider>
|
|
@@ -254,15 +293,8 @@ export function RenderSpecOverview({ spec, language }: { spec: SDKJSON.Spec; lan
|
|
|
254
293
|
|
|
255
294
|
return (
|
|
256
295
|
<DocsProvider spec={spec} language={language ?? 'node'}>
|
|
257
|
-
<ComponentProvider
|
|
258
|
-
|
|
259
|
-
SDKRequestTitle,
|
|
260
|
-
SnippetCode,
|
|
261
|
-
SnippetContainer,
|
|
262
|
-
SnippetRequestContainer,
|
|
263
|
-
}}
|
|
264
|
-
>
|
|
265
|
-
<NavigationProvider basePath={BASE_PATH}>
|
|
296
|
+
<ComponentProvider components={componentOverrides}>
|
|
297
|
+
<NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH}>
|
|
266
298
|
<MarkdownProvider render={renderMarkdown} highlight={highlight}>
|
|
267
299
|
<div className={style.Overview}>
|
|
268
300
|
{resources
|
|
@@ -303,57 +335,44 @@ export function RenderSpec({
|
|
|
303
335
|
const parsed = parseStainlessPath(path);
|
|
304
336
|
const resource = getResourceFromSpec(path, spec);
|
|
305
337
|
|
|
306
|
-
if (!resource || !parsed)
|
|
338
|
+
if (!resource || !parsed) {
|
|
339
|
+
console.warn(`Could not find resource or parsed path for '${path}'`); // eslint-disable-line @eslint-react/purity
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
307
342
|
|
|
308
343
|
return (
|
|
309
344
|
<DocsProvider
|
|
310
|
-
spec={spec
|
|
345
|
+
spec={spec}
|
|
311
346
|
language={language ?? 'node'}
|
|
312
347
|
settings={{
|
|
313
348
|
contentPanelLayout,
|
|
314
349
|
properties: PROPERTY_SETTINGS,
|
|
315
350
|
}}
|
|
316
351
|
>
|
|
317
|
-
<ComponentProvider
|
|
318
|
-
|
|
319
|
-
SDKRequestTitle,
|
|
320
|
-
SnippetCode,
|
|
321
|
-
SnippetContainer,
|
|
322
|
-
SnippetRequestContainer,
|
|
323
|
-
}}
|
|
324
|
-
>
|
|
325
|
-
<NavigationProvider basePath={BASE_PATH} selectedPath={path}>
|
|
352
|
+
<ComponentProvider components={componentOverrides}>
|
|
353
|
+
<NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH} selectedPath={path}>
|
|
326
354
|
<MarkdownProvider render={renderMarkdown} highlight={highlight}>
|
|
327
|
-
{
|
|
355
|
+
{
|
|
328
356
|
<div className="stldocs-root stl-ui-not-prose">
|
|
329
357
|
<div className="stl-page-nav-container">
|
|
330
358
|
<SDKBreadcrumbs
|
|
331
|
-
spec={spec
|
|
359
|
+
spec={spec}
|
|
332
360
|
currentPath={currentPath}
|
|
333
|
-
basePath={
|
|
361
|
+
basePath={RESOLVED_API_REFERENCE_PATH}
|
|
334
362
|
config={BREADCRUMB_CONFIG}
|
|
335
363
|
/>
|
|
336
|
-
{
|
|
364
|
+
{ENABLE_CONTEXT_MENU && <AIDropdown />}
|
|
337
365
|
</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}
|
|
366
|
+
{kind === 'http_method' ? (
|
|
367
|
+
<SDKMethod
|
|
368
|
+
method={resource.methods[parsed.method!]!}
|
|
369
|
+
transformRequestSnippet={transformRequestSnippet}
|
|
351
370
|
/>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
371
|
+
) : (
|
|
372
|
+
<SDKOverview resource={resource} />
|
|
373
|
+
)}
|
|
355
374
|
</div>
|
|
356
|
-
|
|
375
|
+
}
|
|
357
376
|
</MarkdownProvider>
|
|
358
377
|
</NavigationProvider>
|
|
359
378
|
</ComponentProvider>
|
|
@@ -367,10 +386,14 @@ export function RenderMethod({ path }: { path: string }) {
|
|
|
367
386
|
|
|
368
387
|
const parsed = parseStainlessPath(path);
|
|
369
388
|
const resource = getResourceFromSpec(path, spec);
|
|
370
|
-
if (!resource || !parsed) return null;
|
|
371
389
|
|
|
372
|
-
|
|
373
|
-
|
|
390
|
+
if (!resource || !parsed) {
|
|
391
|
+
console.warn(`Could not find resource or parsed path for '${path}'`); // eslint-disable-line @eslint-react/purity
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const method = resource.methods[parsed.method!]!;
|
|
396
|
+
return <SDKMethod method={method} />;
|
|
374
397
|
}
|
|
375
398
|
|
|
376
399
|
export async function getReadmeContent(spec: SDKJSON.Spec, language: DocsLanguage) {
|
|
@@ -390,8 +413,68 @@ export async function getReadmeContent(spec: SDKJSON.Spec, language: DocsLanguag
|
|
|
390
413
|
return spec.readme[language];
|
|
391
414
|
}
|
|
392
415
|
|
|
416
|
+
let astroShikiHighlighter:
|
|
417
|
+
| HighlighterGeneric<BundledLanguage, BundledTheme>
|
|
418
|
+
| Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>
|
|
419
|
+
| null = null;
|
|
420
|
+
|
|
421
|
+
async function astroHighlight() {
|
|
422
|
+
if (astroShikiHighlighter) {
|
|
423
|
+
return astroShikiHighlighter;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
astroShikiHighlighter = createHighlighter({
|
|
427
|
+
themes: [
|
|
428
|
+
'github-light',
|
|
429
|
+
'github-dark',
|
|
430
|
+
{
|
|
431
|
+
name: 'stainless-docs-json',
|
|
432
|
+
colors: {
|
|
433
|
+
'editor.background': 'var(--stl-color-background)',
|
|
434
|
+
'editor.foreground': 'var(--stl-color-foreground)',
|
|
435
|
+
},
|
|
436
|
+
|
|
437
|
+
tokenColors: [
|
|
438
|
+
{
|
|
439
|
+
scope: ['comment', 'punctuation.definition.comment'],
|
|
440
|
+
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
441
|
+
},
|
|
442
|
+
// numbers, booleans, null
|
|
443
|
+
{
|
|
444
|
+
scope: ['constant.numeric', 'constant.language'],
|
|
445
|
+
settings: { foreground: 'var(--stl-color-orange-foreground)' },
|
|
446
|
+
},
|
|
447
|
+
// strings
|
|
448
|
+
{
|
|
449
|
+
scope: ['string', 'string.quoted', 'string.template'],
|
|
450
|
+
settings: { foreground: 'var(--stl-color-green-foreground)' },
|
|
451
|
+
},
|
|
452
|
+
// Keys, brackets
|
|
453
|
+
{
|
|
454
|
+
scope: ['support.type', 'meta'],
|
|
455
|
+
settings: { foreground: 'var(--stl-color-foreground)' },
|
|
456
|
+
},
|
|
457
|
+
// brackets
|
|
458
|
+
{
|
|
459
|
+
scope: ['meta'],
|
|
460
|
+
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
461
|
+
},
|
|
462
|
+
// built-in types
|
|
463
|
+
{
|
|
464
|
+
scope: ['support.type.builtin'],
|
|
465
|
+
settings: { foreground: 'var(--stl-color-purple-foreground)' },
|
|
466
|
+
},
|
|
467
|
+
],
|
|
468
|
+
},
|
|
469
|
+
],
|
|
470
|
+
langs: SupportedLanguageSyntaxes,
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
return astroShikiHighlighter;
|
|
474
|
+
}
|
|
475
|
+
|
|
393
476
|
// Astro's markdown processor is a singleton
|
|
394
|
-
// Need to cache it instead of
|
|
477
|
+
// Need to cache it instead of instantiating per request
|
|
395
478
|
let astroMarkdownProcessor: MarkdownProcessor;
|
|
396
479
|
async function astroMarkdown() {
|
|
397
480
|
if (!astroMarkdownProcessor) {
|
|
@@ -407,18 +490,6 @@ async function astroMarkdown() {
|
|
|
407
490
|
return astroMarkdownProcessor;
|
|
408
491
|
}
|
|
409
492
|
|
|
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
493
|
export async function astroMarkdownRender(content: string) {
|
|
423
494
|
const md = await astroMarkdown();
|
|
424
495
|
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
|
|
|
12
|
-
|
|
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
|
+
|
|
35
|
+
export const onRequest = defineRouteMiddleware((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
|
});
|