@stainless-api/docs 0.1.0-beta.13 → 0.1.0-beta.131
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 +1110 -0
- package/ambient.d.ts +6 -0
- package/eslint-suppressions.json +90 -0
- package/{eslint.config.js → eslint.config.ts} +0 -2
- package/locals.d.ts +17 -0
- package/package.json +62 -44
- 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 +0 -40
- 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 +24 -44
- 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 +317 -141
- package/plugin/languages.ts +8 -2
- package/plugin/loadPluginConfig.ts +284 -109
- package/plugin/markdown/highlighter.ts +100 -0
- package/plugin/markdown/index.ts +39 -0
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +3 -1
- package/plugin/react/Routing.tsx +98 -263
- package/plugin/referencePlaceholderUtils.ts +17 -14
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +39 -35
- package/plugin/routes/Docs.astro +72 -111
- package/plugin/routes/DocsStatic.astro +6 -5
- package/plugin/routes/Overview.astro +46 -22
- package/plugin/routes/llms.ts +186 -0
- package/plugin/routes/markdown.ts +13 -12
- package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +84 -69
- 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 +132 -0
- package/plugin/specs/inputResolver.ts +148 -0
- package/plugin/{cms → specs}/worker.ts +82 -5
- package/plugin/vendor/preview.worker.docs.js +27121 -16890
- 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 +46 -1
- package/src/content.config.ts +9 -0
- package/stl-docs/aiChatExamples.ts +95 -0
- package/stl-docs/chat/docs-chat-handler.ts +18 -0
- package/stl-docs/chat/hook.ts +215 -0
- package/stl-docs/chat/schemas.ts +70 -0
- package/stl-docs/chat/stainless-handler/index.ts +126 -0
- package/stl-docs/chat/stream-util.ts +16 -0
- package/stl-docs/chat/ui/AiChat.module.css +591 -0
- package/stl-docs/chat/ui/AiChat.tsx +188 -0
- package/stl-docs/chat/ui/Trigger.tsx +154 -0
- package/stl-docs/chat/ui/components/ChatControls.tsx +51 -0
- package/stl-docs/chat/ui/components/ChatEmpty.tsx +42 -0
- package/stl-docs/chat/ui/components/ChatLog.tsx +96 -0
- package/stl-docs/chat/ui/components/ChatMessage.tsx +47 -0
- package/stl-docs/chat/ui/components/CodeBlock.tsx +33 -0
- package/stl-docs/chat/ui/components/MessageFeedback.tsx +109 -0
- package/stl-docs/chat/ui/components/Table.tsx +15 -0
- package/stl-docs/chat/ui/components/ToolCall.tsx +34 -0
- package/stl-docs/chat/ui/components/hljs-github.css +81 -0
- package/stl-docs/chat/ui/scroll-manager.ts +86 -0
- package/stl-docs/chat/ui/types.ts +45 -0
- package/stl-docs/components/AIDropdown.tsx +63 -0
- package/stl-docs/components/AiChatIsland.tsx +16 -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 -9
- package/stl-docs/components/PageFrame.astro +37 -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/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 +6 -8
- package/stl-docs/components/headers/StackedHeader.astro +10 -53
- 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 +2 -2
- package/stl-docs/components/mintlify-compat/AccordionGroup.astro +0 -4
- package/stl-docs/components/mintlify-compat/Columns.astro +2 -2
- package/stl-docs/components/mintlify-compat/Frame.astro +6 -6
- package/stl-docs/components/mintlify-compat/Tab.astro +2 -2
- package/stl-docs/components/mintlify-compat/callouts/Callout.astro +2 -2
- package/stl-docs/components/mintlify-compat/callouts/Check.astro +0 -4
- package/stl-docs/components/mintlify-compat/callouts/Danger.astro +0 -4
- package/stl-docs/components/mintlify-compat/callouts/Info.astro +0 -4
- package/stl-docs/components/mintlify-compat/callouts/Note.astro +0 -4
- package/stl-docs/components/mintlify-compat/callouts/Tip.astro +0 -4
- package/stl-docs/components/mintlify-compat/callouts/Warning.astro +0 -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 +38 -77
- package/stl-docs/components/nav-tabs/NavTabs.astro +81 -81
- package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +1 -2
- package/stl-docs/components/nav-tabs/buildNavLinks.ts +5 -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 +176 -58
- package/stl-docs/loadStlDocsConfig.ts +73 -8
- package/stl-docs/proseDocSync.test.ts +74 -0
- package/stl-docs/proseDocSync.ts +344 -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 +218 -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 +228 -38
- package/styles/sdk_select.css +9 -6
- package/styles/search.css +11 -21
- package/styles/sidebar.css +28 -215
- 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 +66 -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/ClientRouterHead.astro +0 -41
- 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/routes/Docs.astro
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
1
|
---
|
|
2
|
-
import StarlightPage from
|
|
3
|
-
import {
|
|
2
|
+
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
|
|
3
|
+
import { getReadmeContent, buildPageNavigation, RenderSpec } from '../react/Routing';
|
|
4
|
+
import { astroMarkdownRender } from '../markdown';
|
|
5
|
+
import { getResourceFromSpec } from '@stainless-api/docs-ui/utils';
|
|
6
|
+
import { parseRoute, parseStainlessPath } from '@stainless-api/docs-ui/routing';
|
|
4
7
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
CONTENT_PANEL_LAYOUT,
|
|
9
|
+
MIDDLEWARE,
|
|
10
|
+
EXPERIMENTAL_REQUEST_BUILDER,
|
|
11
|
+
RESOLVED_API_REFERENCE_PATH,
|
|
12
|
+
} from 'virtual:stl-starlight-virtual-module';
|
|
13
|
+
import { generateDocsRoutes } from '../helpers/generateDocsRoutes';
|
|
14
|
+
import { StainlessIslands } from '../components/StainlessIslands';
|
|
15
|
+
import { getSDKJSONInSSR } from '../specs/fetchSpecSSR';
|
|
13
16
|
|
|
17
|
+
const language = parseRoute(RESOLVED_API_REFERENCE_PATH, Astro.url.pathname)?.language;
|
|
14
18
|
|
|
15
|
-
const spec = await
|
|
16
|
-
const routes = generateDocsRoutes(spec);
|
|
19
|
+
const spec = await getSDKJSONInSSR(language);
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
export type Props = Awaited<ReturnType<typeof generateDocsRoutes>>[number]['props'] | Record<string, never>;
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
const props =
|
|
24
|
+
'language' in Astro.props
|
|
25
|
+
? // In prod, we pass the props down to this page
|
|
26
|
+
Astro.props
|
|
27
|
+
: // In the dev server, we skip the DocsStatic wrapper so we need to find the props ourselves
|
|
28
|
+
generateDocsRoutes(spec).find((r) => r.params.slug === Astro.params.slug)?.props;
|
|
29
|
+
if (!props) throw new Error(`Could not find a route for slug '${Astro.params.slug}'`);
|
|
30
|
+
|
|
31
|
+
// PageTitle override will skip rendering the default Starlight title
|
|
32
|
+
Astro.locals._stlStarlightPage = {
|
|
33
|
+
skipRenderingStarlightTitle: props.kind === 'readme' ? false : true,
|
|
34
|
+
};
|
|
23
35
|
|
|
24
|
-
const readmeContent = await getReadmeContent(spec,
|
|
25
|
-
const readme =
|
|
26
|
-
route.props.kind === "readme"
|
|
27
|
-
? await astroMarkdownRender(readmeContent ?? "")
|
|
28
|
-
: null;
|
|
36
|
+
const readmeContent = await getReadmeContent(spec, props.language);
|
|
37
|
+
const readme = props.kind === 'readme' ? await astroMarkdownRender(readmeContent ?? '') : null;
|
|
29
38
|
|
|
30
|
-
const resource =
|
|
31
|
-
? getResourceFromSpec(route.props.stainlessPath, spec)
|
|
32
|
-
: null;
|
|
39
|
+
const resource = props.stainlessPath ? getResourceFromSpec(props.stainlessPath, spec) : null;
|
|
33
40
|
|
|
34
41
|
const pageNav =
|
|
35
|
-
|
|
42
|
+
props.kind === 'resource' && resource
|
|
36
43
|
? buildPageNavigation(resource)
|
|
37
|
-
:
|
|
44
|
+
: props.kind === 'readme' && readme?.metadata
|
|
38
45
|
? readme?.metadata.headings
|
|
39
46
|
: [];
|
|
40
47
|
|
|
41
|
-
|
|
48
|
+
Astro.locals.language = props.language;
|
|
42
49
|
|
|
50
|
+
// Use first heading in README as page title
|
|
43
51
|
if (readme) {
|
|
44
52
|
const repo = spec.metadata?.[props.language]?.code_url;
|
|
45
|
-
readme.code = readme.code.replace(
|
|
46
|
-
|
|
47
|
-
`<a href="${repo}/$1"`);
|
|
48
|
-
props.title = readme.metadata.headings[0].text ?? "Overview";
|
|
53
|
+
readme.code = readme.code.replace(/<a href="(?!(?:https?:\/\/|\/\/))([^"]+)"/g, `<a href="${repo}/$1"`);
|
|
54
|
+
props.title = readme.metadata.headings[0]!.text ?? 'Overview';
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
// use summary for the page title of method pages
|
|
58
|
+
if (props.kind === 'http_method' && props.stainlessPath) {
|
|
59
|
+
const parsed = parseStainlessPath(props.stainlessPath);
|
|
60
|
+
const resource = getResourceFromSpec(props.stainlessPath, spec);
|
|
61
|
+
if (parsed?.method && resource?.methods[parsed.method]) {
|
|
62
|
+
const method = resource.methods[parsed.method];
|
|
63
|
+
props.title = method?.summary ?? method?.title ?? props.title;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
51
66
|
---
|
|
52
67
|
|
|
53
|
-
|
|
54
68
|
<StarlightPage
|
|
55
69
|
headings={pageNav}
|
|
56
70
|
frontmatter={{
|
|
57
|
-
title: props
|
|
58
|
-
head: [
|
|
59
|
-
{
|
|
60
|
-
tag: "link",
|
|
61
|
-
attrs: {
|
|
62
|
-
rel: "alternate",
|
|
63
|
-
type: "text/markdown",
|
|
64
|
-
href: `${BASE_PATH}/${Astro.params.slug}.md`
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
],
|
|
71
|
+
title: props.title,
|
|
68
72
|
pagefind: false,
|
|
69
|
-
tableOfContents:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
stainlessStarlight: {
|
|
74
|
-
basePath: BASE_PATH,
|
|
75
|
-
...props,
|
|
76
|
-
},
|
|
73
|
+
tableOfContents:
|
|
74
|
+
props.kind === 'readme' || (props.kind === 'resource' && props.language !== 'terraform')
|
|
75
|
+
? { maxHeadingLevel: 6 }
|
|
76
|
+
: false,
|
|
77
77
|
}}
|
|
78
78
|
>
|
|
79
79
|
{
|
|
@@ -88,76 +88,37 @@ if (readme) {
|
|
|
88
88
|
contentPanelLayout={CONTENT_PANEL_LAYOUT}
|
|
89
89
|
transformRequestSnippet={MIDDLEWARE.transformRequestSnippet}
|
|
90
90
|
/>
|
|
91
|
-
|
|
92
|
-
<style is:inline>
|
|
93
|
-
#stldocs-snippet-title {
|
|
94
|
-
display: flex;
|
|
95
|
-
gap: 5px;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.stldocs-snippet-code:not(.stldocs-snippet-response .stldocs-snippet-code) {
|
|
99
|
-
padding: 0 !important;
|
|
100
|
-
|
|
101
|
-
.astro-code {
|
|
102
|
-
padding: 1rem;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
[data-has-sidebar]:not([data-has-toc]) .sl-container {
|
|
108
|
-
max-width: 1428px;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.content-panel:nth-of-type(1) {
|
|
112
|
-
display: none;
|
|
113
|
-
}
|
|
114
|
-
.content-panel:nth-of-type(2) .stl-page-nav-container {
|
|
115
|
-
display: none;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.content-panel:nth-of-type(2) .stldocs-root .stl-page-nav-container {
|
|
119
|
-
display: flex;
|
|
120
|
-
}
|
|
121
|
-
</style>
|
|
122
91
|
</div>
|
|
123
92
|
) : (
|
|
124
93
|
<>
|
|
125
94
|
<Fragment set:html={readme?.code} />
|
|
126
|
-
<style
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
background-color: currentColor;
|
|
144
|
-
color: inherit;
|
|
145
|
-
display: inline-block;
|
|
146
|
-
vertical-align: text-bottom;
|
|
147
|
-
width: 1em;
|
|
148
|
-
height: 1em;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.sl-markdown-content code {
|
|
152
|
-
white-space: pre-wrap;
|
|
153
|
-
}
|
|
154
|
-
</style>
|
|
95
|
+
<style
|
|
96
|
+
is:inline
|
|
97
|
+
set:text={`
|
|
98
|
+
.sl-markdown-content h1:first-of-type {
|
|
99
|
+
display: none;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.sl-markdown-content img {
|
|
103
|
+
display: inline-block;
|
|
104
|
+
vertical-align: text-bottom;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.sl-markdown-content code {
|
|
108
|
+
white-space: pre-wrap;
|
|
109
|
+
}
|
|
110
|
+
`}
|
|
111
|
+
/>
|
|
155
112
|
</>
|
|
156
113
|
)
|
|
157
114
|
}
|
|
158
115
|
</StarlightPage>
|
|
159
116
|
|
|
117
|
+
{EXPERIMENTAL_REQUEST_BUILDER && <StainlessIslands client:load />}
|
|
118
|
+
|
|
160
119
|
<script src="../globalJs/navigation.ts"></script>
|
|
161
120
|
<script src="../globalJs/copy.ts"></script>
|
|
162
121
|
<script src="../globalJs/tooltip.ts"></script>
|
|
163
122
|
<script src="../globalJs/code-snippets.ts"></script>
|
|
123
|
+
<script src="../globalJs/method-descriptions.ts"></script>
|
|
124
|
+
<script src="../globalJs/summary-selection-tweak.ts"></script>
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { GetStaticPaths } from 'astro';
|
|
3
3
|
import Docs from './Docs.astro';
|
|
4
|
-
import {
|
|
5
|
-
import { generateDocsRoutes } from '../react/Routing';
|
|
4
|
+
import { generateAllDocsRoutes } from '../helpers/generateDocsRoutes';
|
|
6
5
|
|
|
7
6
|
export const getStaticPaths = (async () => {
|
|
8
|
-
const
|
|
9
|
-
const routes = generateDocsRoutes(spec);
|
|
7
|
+
const routes = await generateAllDocsRoutes();
|
|
10
8
|
return routes;
|
|
11
9
|
}) satisfies GetStaticPaths;
|
|
10
|
+
|
|
11
|
+
export type Props = Awaited<ReturnType<typeof getStaticPaths>>[number]['props'];
|
|
12
|
+
const props = Astro.props;
|
|
12
13
|
---
|
|
13
14
|
|
|
14
|
-
<Docs />
|
|
15
|
+
<Docs {...props} />
|
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
---
|
|
2
2
|
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
|
|
3
|
-
import {
|
|
4
|
-
import { cmsClient } from '../cms/client';
|
|
5
|
-
import type { DocsLanguage } from '@stainless-api/docs-ui/src/routing';
|
|
3
|
+
import { EXCLUDE_LANGUAGES } from 'virtual:stl-starlight-virtual-module';
|
|
6
4
|
import { RenderLibraries, RenderSpecOverview, type SpecMetadata } from '../react/Routing';
|
|
5
|
+
import { getSDKJSONInSSR } from '../specs/fetchSpecSSR';
|
|
6
|
+
import { api } from 'virtual:stainless-apis-manifest';
|
|
7
7
|
|
|
8
|
-
const spec = await
|
|
8
|
+
const spec = await getSDKJSONInSSR('http');
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
.filter((
|
|
13
|
-
.filter((
|
|
14
|
-
|
|
10
|
+
const langTargets = api.languages
|
|
11
|
+
.map((l) => l.language)
|
|
12
|
+
.filter((l) => !EXCLUDE_LANGUAGES.includes(l))
|
|
13
|
+
.filter((l) => l !== 'http');
|
|
14
|
+
|
|
15
|
+
const langsWithSpecs = await Promise.all(
|
|
16
|
+
langTargets.map(async (language) => {
|
|
17
|
+
const spec = await getSDKJSONInSSR(language);
|
|
18
|
+
return {
|
|
19
|
+
language,
|
|
20
|
+
spec,
|
|
21
|
+
};
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const metadata: SpecMetadata = langsWithSpecs.map(({ language, spec }) => [
|
|
26
|
+
language,
|
|
27
|
+
spec.metadata[language]!,
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
// PageTitle override will skip rendering the default Starlight title
|
|
31
|
+
Astro.locals._stlStarlightPage = {
|
|
32
|
+
hasMarkdownRoute: false,
|
|
33
|
+
};
|
|
15
34
|
---
|
|
16
35
|
|
|
17
36
|
<StarlightPage
|
|
@@ -19,22 +38,26 @@ const metadata = languages
|
|
|
19
38
|
title: 'API Reference',
|
|
20
39
|
pagefind: false,
|
|
21
40
|
tableOfContents: false,
|
|
22
|
-
stainlessStarlight: {
|
|
23
|
-
basePath: BASE_PATH,
|
|
24
|
-
language: 'http',
|
|
25
|
-
},
|
|
26
41
|
}}
|
|
27
42
|
>
|
|
28
|
-
<
|
|
43
|
+
<div class="stl-overview">
|
|
44
|
+
{
|
|
45
|
+
metadata.length > 0 && (
|
|
46
|
+
<>
|
|
47
|
+
<h3>Libraries</h3>
|
|
29
48
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
49
|
+
<div class="stldocs-root language-blocks stl-ui-not-prose not-content">
|
|
50
|
+
<RenderLibraries metadata={metadata} />
|
|
51
|
+
</div>
|
|
52
|
+
</>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
33
55
|
|
|
34
|
-
|
|
56
|
+
<h3>API Overview</h3>
|
|
35
57
|
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
<div class="stldocs-root api-overview stl-ui-not-prose">
|
|
59
|
+
<RenderSpecOverview spec={spec} language="http" />
|
|
60
|
+
</div>
|
|
38
61
|
</div>
|
|
39
62
|
</StarlightPage>
|
|
40
63
|
|
|
@@ -45,8 +68,9 @@ const metadata = languages
|
|
|
45
68
|
gap: 1rem;
|
|
46
69
|
margin-top: 2rem;
|
|
47
70
|
|
|
48
|
-
|
|
49
|
-
width:
|
|
71
|
+
> * {
|
|
72
|
+
width: 0;
|
|
73
|
+
flex: 1 1 350px;
|
|
50
74
|
}
|
|
51
75
|
}
|
|
52
76
|
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import type { APIRoute } from 'astro';
|
|
2
|
+
import { getCollection } from 'astro:content';
|
|
3
|
+
import { base as ASTRO_BASE } from 'astro:config/server';
|
|
4
|
+
import { SITE_TITLE, API_REFERENCE_BASE_PATH } from 'virtual:stl-docs-virtual-module';
|
|
5
|
+
import { LLMS_TXT_DESCRIPTION, LLMS_TXT_DETAIL_THRESHOLD } from 'virtual:stl-starlight-virtual-module';
|
|
6
|
+
import { getSDKJSONInSSR } from '../specs/fetchSpecSSR';
|
|
7
|
+
import Markdoc from '@markdoc/markdoc';
|
|
8
|
+
import type { Node } from '@markdoc/markdoc';
|
|
9
|
+
import * as md from '@stainless-api/docs-ui/markdown/md';
|
|
10
|
+
import type * as SDKJSON from '@stainless/sdk-json';
|
|
11
|
+
import { generateRoute, walkTree } from '@stainless-api/docs-ui/routing';
|
|
12
|
+
|
|
13
|
+
export const prerender = true;
|
|
14
|
+
|
|
15
|
+
function joinUrlParts(...parts: (string | boolean | null | undefined)[]) {
|
|
16
|
+
return (
|
|
17
|
+
'/' +
|
|
18
|
+
parts
|
|
19
|
+
.map((p) => {
|
|
20
|
+
if (typeof p === 'string') {
|
|
21
|
+
return p.split('/');
|
|
22
|
+
}
|
|
23
|
+
return p;
|
|
24
|
+
})
|
|
25
|
+
.flat()
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.join('/')
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type ProsePageEntry = {
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
function isResourceEmpty(resource: SDKJSON.Resource) {
|
|
38
|
+
return Object.values(resource.methods).length < 1 && Object.values(resource.subresources ?? {}).length < 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function trimPath(path: string) {
|
|
42
|
+
return path.endsWith('/') ? path.slice(0, -1) : path;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function apiHref(basePath: string, language: string, stainlessPath: string) {
|
|
46
|
+
const href = generateRoute(basePath, language, stainlessPath);
|
|
47
|
+
if (!href) return null;
|
|
48
|
+
return joinUrlParts(ASTRO_BASE, href, 'index.md');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function linkListItem(title: string, url: string, description?: string): Node {
|
|
52
|
+
const children = [md.link(url, title)];
|
|
53
|
+
if (description) children.push(md.text(`: ${description}`));
|
|
54
|
+
return md.item(md.inline(...children));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function generateProseIndex(routes: ProsePageEntry[], detailed: boolean) {
|
|
58
|
+
const pageEntryLink = (page: ProsePageEntry) =>
|
|
59
|
+
linkListItem(
|
|
60
|
+
page.title,
|
|
61
|
+
joinUrlParts(ASTRO_BASE, page.id === 'index' ? null : page.id, 'index.md'),
|
|
62
|
+
detailed ? page.description : undefined,
|
|
63
|
+
);
|
|
64
|
+
return [md.heading(2, 'Docs'), md.list(...routes.map(pageEntryLink))];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function renderMethods(basePath: string, language: string, methods: Record<string, SDKJSON.Method>) {
|
|
68
|
+
const output: Node[] = [];
|
|
69
|
+
|
|
70
|
+
for (const method of Object.values(methods)) {
|
|
71
|
+
const href = apiHref(basePath, language, method.stainlessPath);
|
|
72
|
+
if (href) output.push(linkListItem(method.title, href, method.summary));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return md.list(...output);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function renderResource(
|
|
79
|
+
basePath: string,
|
|
80
|
+
language: string,
|
|
81
|
+
detailed: boolean,
|
|
82
|
+
resource: SDKJSON.Resource,
|
|
83
|
+
): Node {
|
|
84
|
+
const href = apiHref(basePath, language, resource.stainlessPath);
|
|
85
|
+
const output = [md.paragraph(href ? md.link(href, resource.title) : md.text(resource.title))];
|
|
86
|
+
if (resource.methods && detailed) output.push(renderMethods(basePath, language, resource.methods));
|
|
87
|
+
if (resource.subresources) output.push(renderSubs(basePath, language, detailed, resource.subresources));
|
|
88
|
+
return md.item(...output);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function renderSubs(
|
|
92
|
+
basePath: string,
|
|
93
|
+
language: string,
|
|
94
|
+
detailed: boolean,
|
|
95
|
+
resources: Record<string, SDKJSON.Resource>,
|
|
96
|
+
): Node {
|
|
97
|
+
return md.list(
|
|
98
|
+
...Object.values(resources)
|
|
99
|
+
.filter((res) => !isResourceEmpty(res))
|
|
100
|
+
.map((sub) => renderResource(basePath, language, detailed, sub)),
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function renderLanguageNote(basePath: string, languages: string[]) {
|
|
105
|
+
return [
|
|
106
|
+
md.paragraph(
|
|
107
|
+
md.text('Links below point to language-neutral HTTP documentation. '),
|
|
108
|
+
md.text(
|
|
109
|
+
'SDK-specific docs follow the same URL structure with the language inserted after the base path: ',
|
|
110
|
+
),
|
|
111
|
+
md.code(`${trimPath(basePath)}/{language}/resources/...`),
|
|
112
|
+
md.text('.'),
|
|
113
|
+
),
|
|
114
|
+
md.paragraph(md.text(`Available languages: ${languages.join(', ')}`)),
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function generateRefIndex(
|
|
119
|
+
basePath: string,
|
|
120
|
+
languages: string[],
|
|
121
|
+
language: string,
|
|
122
|
+
detailed: boolean,
|
|
123
|
+
spec: SDKJSON.Spec,
|
|
124
|
+
) {
|
|
125
|
+
const output = [md.heading(2, 'API Reference'), ...renderLanguageNote(basePath, languages)];
|
|
126
|
+
|
|
127
|
+
for (const resource of Object.values(spec.resources)) {
|
|
128
|
+
if (isResourceEmpty(resource)) continue;
|
|
129
|
+
const href = apiHref(basePath, language, resource.stainlessPath);
|
|
130
|
+
output.push(md.heading(3, [href ? md.link(href, resource.title) : md.text(resource.title)]));
|
|
131
|
+
if (resource.methods && detailed) output.push(renderMethods(basePath, language, resource.methods));
|
|
132
|
+
if (resource.subresources) output.push(renderSubs(basePath, language, detailed, resource.subresources));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return output;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function generateMarkdownIndex({
|
|
139
|
+
siteTitle,
|
|
140
|
+
description,
|
|
141
|
+
basePath,
|
|
142
|
+
languages,
|
|
143
|
+
spec,
|
|
144
|
+
detailed,
|
|
145
|
+
proseRoutes,
|
|
146
|
+
}: {
|
|
147
|
+
siteTitle: string;
|
|
148
|
+
description: string | null;
|
|
149
|
+
basePath: string;
|
|
150
|
+
languages: string[];
|
|
151
|
+
spec: SDKJSON.Spec;
|
|
152
|
+
detailed: boolean;
|
|
153
|
+
proseRoutes: ProsePageEntry[];
|
|
154
|
+
}) {
|
|
155
|
+
const output: Node[] = [md.heading(1, siteTitle)];
|
|
156
|
+
if (description) output.push(md.paragraph(md.text(description)));
|
|
157
|
+
if (proseRoutes.length > 0) output.push(...generateProseIndex(proseRoutes, detailed));
|
|
158
|
+
if (languages.length > 0) output.push(...generateRefIndex(basePath, languages, 'http', detailed, spec));
|
|
159
|
+
|
|
160
|
+
const doc = new Markdoc.Ast.Node('document', {}, output);
|
|
161
|
+
return Markdoc.format(doc);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const GET: APIRoute = async () => {
|
|
165
|
+
const [docsCollection, spec] = await Promise.all([getCollection('docs'), getSDKJSONInSSR('http')]);
|
|
166
|
+
const apiEntries = [...walkTree(spec)].filter((n) => n.data.kind !== 'model');
|
|
167
|
+
const proseRoutes = docsCollection.map((entry) => ({
|
|
168
|
+
id: entry.id,
|
|
169
|
+
title: entry.data.title,
|
|
170
|
+
description: entry.data.description,
|
|
171
|
+
}));
|
|
172
|
+
|
|
173
|
+
const content = generateMarkdownIndex({
|
|
174
|
+
siteTitle: SITE_TITLE,
|
|
175
|
+
description: LLMS_TXT_DESCRIPTION,
|
|
176
|
+
basePath: API_REFERENCE_BASE_PATH,
|
|
177
|
+
languages: spec.docs?.languages ?? [],
|
|
178
|
+
detailed: apiEntries.length + proseRoutes.length < LLMS_TXT_DETAIL_THRESHOLD,
|
|
179
|
+
spec,
|
|
180
|
+
proseRoutes,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return new Response(content, {
|
|
184
|
+
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
|
|
185
|
+
});
|
|
186
|
+
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { APIRoute, GetStaticPaths } from 'astro';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { getResourceFromSpec } from '@stainless-api/docs-ui/src/utils';
|
|
2
|
+
import { getReadmeContent } from '../react/Routing';
|
|
3
|
+
import { getResourceFromSpec } from '@stainless-api/docs-ui/utils';
|
|
5
4
|
|
|
6
|
-
import { renderMarkdown } from '@stainless-api/docs-ui/
|
|
5
|
+
import { renderMarkdown } from '@stainless-api/docs-ui/markdown';
|
|
7
6
|
|
|
8
|
-
import { parseStainlessPath, type DocsLanguage } from '@stainless-api/docs-ui/
|
|
9
|
-
import type { EnvironmentType } from '@stainless-api/docs-ui/
|
|
7
|
+
import { parseStainlessPath, type DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
8
|
+
import type { EnvironmentType } from '@stainless-api/docs-ui/markdown/utils';
|
|
10
9
|
import { PROPERTY_SETTINGS, MIDDLEWARE } from 'virtual:stl-starlight-virtual-module';
|
|
10
|
+
import { generateAllDocsRoutes } from '../helpers/generateDocsRoutes';
|
|
11
|
+
import { getSDKJSONInSSR } from '../specs/fetchSpecSSR';
|
|
11
12
|
|
|
12
13
|
type RouteProps = {
|
|
13
14
|
stainlessPath: string;
|
|
@@ -16,17 +17,17 @@ type RouteProps = {
|
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
export const getStaticPaths = (async () => {
|
|
19
|
-
const
|
|
20
|
-
return
|
|
20
|
+
const paths = await generateAllDocsRoutes();
|
|
21
|
+
return paths;
|
|
21
22
|
}) satisfies GetStaticPaths;
|
|
22
23
|
|
|
23
24
|
export const GET: APIRoute<RouteProps> = async ({ props }) => {
|
|
24
|
-
const spec = await
|
|
25
|
+
const spec = await getSDKJSONInSSR(props.language);
|
|
25
26
|
|
|
26
27
|
if (props.kind === 'readme') {
|
|
27
28
|
const readmeContent = await getReadmeContent(spec, props.language);
|
|
28
29
|
return new Response(readmeContent, {
|
|
29
|
-
headers: { 'Content-Type': 'text/
|
|
30
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
30
31
|
});
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -47,11 +48,11 @@ export const GET: APIRoute<RouteProps> = async ({ props }) => {
|
|
|
47
48
|
},
|
|
48
49
|
};
|
|
49
50
|
|
|
50
|
-
const target = props.kind === 'http_method' && parsed?.method ? resource.methods[parsed.method] : resource;
|
|
51
|
+
const target = props.kind === 'http_method' && parsed?.method ? resource.methods[parsed.method]! : resource;
|
|
51
52
|
const output = renderMarkdown(env, target);
|
|
52
53
|
|
|
53
54
|
return new Response(output, {
|
|
54
|
-
headers: { 'Content-Type': 'text/
|
|
55
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
55
56
|
});
|
|
56
57
|
};
|
|
57
58
|
|