@stainless-api/docs 0.1.0-beta.99 → 1.0.0-beta.141
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 +401 -0
- package/ambient.d.ts +6 -0
- package/eslint-suppressions.json +22 -6
- package/{eslint.config.js → eslint.config.ts} +1 -7
- package/package.json +62 -40
- package/plugin/buildAlgoliaIndex.ts +6 -12
- package/plugin/components/SDKSelect.astro +0 -6
- package/plugin/components/SnippetCode.tsx +6 -37
- package/plugin/components/search/SearchAlgolia.astro +1 -1
- package/plugin/components/search/SearchIsland.tsx +19 -13
- package/plugin/generateAPIReferenceLink.ts +0 -40
- package/plugin/globalJs/ai-dropdown-options.ts +22 -9
- package/plugin/globalJs/code-snippets.ts +5 -5
- package/plugin/globalJs/copy.ts +20 -91
- package/plugin/globalJs/navigation.ts +13 -13
- package/plugin/globalJs/summary-selection-tweak.ts +29 -0
- package/plugin/index.ts +107 -163
- package/plugin/loadPluginConfig.ts +49 -151
- package/plugin/markdown/highlighter.ts +100 -0
- package/plugin/markdown/index.ts +39 -0
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +2 -0
- package/plugin/react/Routing.tsx +10 -244
- package/plugin/referencePlaceholderUtils.ts +1 -1
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +1 -1
- package/plugin/routes/Docs.astro +3 -1
- package/plugin/routes/Overview.astro +14 -7
- package/plugin/routes/llms.ts +186 -0
- package/plugin/routes/markdown.ts +62 -13
- package/plugin/sidebar-utils/sidebar-builder.ts +38 -12
- package/plugin/specs/defaultSpecLoader.ts +192 -0
- package/plugin/specs/fetchSpecSSR.ts +1 -1
- package/plugin/specs/utils.ts +86 -0
- package/shared/conditionalIntegration.ts +28 -0
- package/shared/getProsePages.ts +6 -7
- package/shared/virtualModule.ts +1 -26
- package/stl-docs/aiChatExamples.ts +31 -0
- package/stl-docs/chat/docs-chat-handler.ts +17 -0
- package/stl-docs/chat/hook.ts +225 -0
- package/stl-docs/chat/schemas.ts +27 -0
- package/stl-docs/chat/ui/AiChat.module.css +591 -0
- package/stl-docs/chat/ui/AiChat.tsx +175 -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 +93 -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 +106 -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/AiChatIsland.tsx +10 -12
- package/stl-docs/components/ContentPanel.astro +9 -0
- package/stl-docs/components/Footer.astro +89 -0
- package/stl-docs/components/Header.astro +0 -5
- package/stl-docs/components/PageFrame.astro +23 -8
- package/stl-docs/components/PageSidebar.astro +11 -0
- package/stl-docs/components/StainlessLogo.svg +4 -0
- package/stl-docs/components/TwoColumnContent.astro +2 -0
- package/stl-docs/components/headers/DefaultHeader.astro +6 -8
- package/stl-docs/components/headers/StackedHeader.astro +5 -53
- 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 +2 -2
- 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/nav-tabs/NavDropdown.astro +12 -7
- package/stl-docs/components/nav-tabs/NavTabs.astro +5 -3
- package/stl-docs/components/nav-tabs/buildNavLinks.ts +2 -0
- package/stl-docs/components/pagination/Pagination.astro +4 -2
- package/stl-docs/components/pagination/PaginationLinkEmphasized.astro +2 -2
- package/stl-docs/components/pagination/PaginationLinkQuiet.astro +2 -2
- package/stl-docs/components/pagination/util.ts +3 -3
- package/stl-docs/components/sidebars/BaseSidebar.astro +72 -1
- package/stl-docs/disableCalloutSyntax.ts +1 -1
- package/stl-docs/fonts.ts +5 -5
- package/stl-docs/index.ts +76 -53
- package/stl-docs/loadStlDocsConfig.ts +38 -8
- package/stl-docs/og-image/components/OpenGraphFunctionSignature.tsx +64 -0
- package/stl-docs/og-image/components/OpenGraphImage.tsx +126 -0
- package/stl-docs/og-image/config.ts +56 -0
- package/stl-docs/og-image/image-gen/generate-api-reference-og-image.tsx +188 -0
- package/stl-docs/og-image/image-gen/generate-og-image.tsx +119 -0
- package/stl-docs/og-image/image-gen/get-logo-url.ts +47 -0
- package/stl-docs/og-image/index.ts +135 -0
- package/stl-docs/og-image/routes/add-og-image.ts +45 -0
- package/stl-docs/og-image/routes/get-api-reference-og-image.ts +36 -0
- package/stl-docs/og-image/routes/get-og-image.ts +28 -0
- package/stl-docs/og-image/theme.ts +43 -0
- package/stl-docs/og-image/utils.ts +14 -0
- package/stl-docs/proseDocSync.test.ts +74 -0
- package/stl-docs/proseDocSync.ts +344 -0
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +4 -12
- package/stl-docs/schema-extension.ts +12 -0
- package/stl-docs/tabsMiddleware.ts +1 -1
- package/styles/overrides.css +2 -14
- package/styles/page.css +210 -71
- package/styles/sidebar.css +30 -17
- package/styles/sl-variables.css +3 -8
- package/styles/stldocs-variables.css +2 -2
- package/styles/toc.css +8 -0
- package/tsconfig.json +1 -1
- package/virtual-module.d.ts +35 -11
- package/playground-virtual-modules.d.ts +0 -96
- package/plugin/globalJs/create-playground.shim.ts +0 -3
- package/plugin/globalJs/playground-data.shim.ts +0 -1
- package/plugin/globalJs/playground-data.ts +0 -14
- package/plugin/specs/FileCache.ts +0 -99
- package/plugin/specs/generateSpec.ts +0 -112
- package/plugin/specs/index.ts +0 -132
- package/plugin/specs/inputResolver.ts +0 -146
- package/plugin/specs/worker.ts +0 -199
- package/plugin/vendor/preview.worker.docs.js +0 -26108
- package/plugin/vendor/templates/cli.md +0 -1
- package/plugin/vendor/templates/go.md +0 -316
- package/plugin/vendor/templates/java.md +0 -89
- package/plugin/vendor/templates/kotlin.md +0 -89
- package/plugin/vendor/templates/node.md +0 -235
- package/plugin/vendor/templates/python.md +0 -251
- package/plugin/vendor/templates/ruby.md +0 -147
- package/plugin/vendor/templates/terraform.md +0 -60
- package/plugin/vendor/templates/typescript.md +0 -319
- package/scripts/vendor_deps.ts +0 -50
- package/stl-docs/components/ClientRouterHead.astro +0 -41
- package/stl-docs/components/content-panel/ContentPanel.astro +0 -42
- package/stl-docs/components/headers/SplashMobileMenuToggle.astro +0 -65
- package/stl-docs/proseSearchIndexing.ts +0 -606
package/stl-docs/index.ts
CHANGED
|
@@ -6,7 +6,8 @@ import { disableCalloutSyntaxStarlightPlugin } from './disableCalloutSyntax';
|
|
|
6
6
|
import type { AstroIntegration } from 'astro';
|
|
7
7
|
|
|
8
8
|
import { normalizeRedirects, type NormalizedRedirectConfig } from './redirects';
|
|
9
|
-
import
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
10
11
|
import { mkdirSync, writeFileSync } from 'fs';
|
|
11
12
|
import {
|
|
12
13
|
parseStlDocsConfig,
|
|
@@ -17,13 +18,15 @@ import {
|
|
|
17
18
|
type StarlightSidebarConfig,
|
|
18
19
|
} from './loadStlDocsConfig';
|
|
19
20
|
import { buildVirtualModuleString } from '../shared/virtualModule';
|
|
20
|
-
import type * as StlDocsVirtualModule from 'virtual:stl-docs-virtual-module';
|
|
21
21
|
import { resolveSrcFile } from '../resolveSrcFile';
|
|
22
22
|
import { stainlessDocsMarkdownRenderer } from './proseMarkdown/proseMarkdownIntegration';
|
|
23
23
|
import { setSharedLogger } from '../shared/getSharedLogger';
|
|
24
|
-
import {
|
|
24
|
+
import { stainlessDocsVectorProseIndexing } from './proseDocSync';
|
|
25
25
|
import { stainlessStarlight } from '../plugin';
|
|
26
26
|
import { getFontRoles, flattenFonts } from './fonts';
|
|
27
|
+
import conditionalIntegration from '../shared/conditionalIntegration';
|
|
28
|
+
import { generateExamplesVirtualModule } from './aiChatExamples';
|
|
29
|
+
import { ogImageStarlightPlugin } from './og-image';
|
|
27
30
|
|
|
28
31
|
export * from '../plugin';
|
|
29
32
|
|
|
@@ -49,18 +52,22 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
49
52
|
|
|
50
53
|
type ComponentOverrides = StarlightConfigDefined['components'];
|
|
51
54
|
const componentOverrides: ComponentOverrides = {
|
|
55
|
+
Head: resolveSrcFile(COMPONENTS_FOLDER, './Head.astro'),
|
|
56
|
+
|
|
52
57
|
PageFrame: resolveSrcFile(COMPONENTS_FOLDER, './PageFrame.astro'),
|
|
58
|
+
TwoColumnContent: resolveSrcFile(COMPONENTS_FOLDER, './TwoColumnContent.astro'),
|
|
53
59
|
|
|
54
|
-
Head: resolveSrcFile(COMPONENTS_FOLDER, './Head.astro'),
|
|
55
60
|
Header: resolveSrcFile(COMPONENTS_FOLDER, './Header.astro'),
|
|
56
61
|
ThemeProvider: resolveSrcFile(COMPONENTS_FOLDER, './ThemeProvider.astro'),
|
|
57
62
|
ThemeSelect: resolveSrcFile(COMPONENTS_FOLDER, './ThemeSelect.astro'),
|
|
58
63
|
|
|
59
64
|
Sidebar: resolveSrcFile(COMPONENTS_FOLDER, './sidebars/BaseSidebar.astro'),
|
|
60
|
-
ContentPanel: resolveSrcFile(COMPONENTS_FOLDER, './
|
|
65
|
+
ContentPanel: resolveSrcFile(COMPONENTS_FOLDER, './ContentPanel.astro'),
|
|
66
|
+
PageTitle: resolveSrcFile(COMPONENTS_FOLDER, './PageTitle.astro'),
|
|
67
|
+
PageSidebar: resolveSrcFile(COMPONENTS_FOLDER, './PageSidebar.astro'),
|
|
61
68
|
TableOfContents: resolveSrcFile(COMPONENTS_FOLDER, './TableOfContents.astro'),
|
|
62
69
|
|
|
63
|
-
|
|
70
|
+
Footer: resolveSrcFile(COMPONENTS_FOLDER, './Footer.astro'),
|
|
64
71
|
Pagination: resolveSrcFile(COMPONENTS_FOLDER, './pagination/Pagination.astro'),
|
|
65
72
|
};
|
|
66
73
|
|
|
@@ -69,7 +76,7 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
69
76
|
disableCalloutSyntaxStarlightPlugin,
|
|
70
77
|
];
|
|
71
78
|
|
|
72
|
-
if (config.apiReference
|
|
79
|
+
if (config.apiReference) {
|
|
73
80
|
plugins.push(
|
|
74
81
|
stainlessStarlight({
|
|
75
82
|
...config.apiReference,
|
|
@@ -84,7 +91,11 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
84
91
|
componentOverrides.Search = resolveSrcFile('/plugin/components/search/Search.astro');
|
|
85
92
|
}
|
|
86
93
|
|
|
87
|
-
|
|
94
|
+
if (config.ogImage) {
|
|
95
|
+
plugins.push(ogImageStarlightPlugin(config.ogImage, config));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
plugins.push(...config.starlightCompat.plugins);
|
|
88
99
|
|
|
89
100
|
// TODO: re-add once we figure out what to do with the client router
|
|
90
101
|
// if (config.enableClientRouter) {
|
|
@@ -98,6 +109,7 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
98
109
|
|
|
99
110
|
return starlight({
|
|
100
111
|
...config.starlightPassThrough,
|
|
112
|
+
pagefind: config.starlightCompat.pagefind,
|
|
101
113
|
sidebar,
|
|
102
114
|
components: {
|
|
103
115
|
...componentOverrides,
|
|
@@ -154,8 +166,6 @@ function stainlessDocsIntegration(
|
|
|
154
166
|
config: NormalizedStainlessDocsConfig,
|
|
155
167
|
apiReferenceBasePath: string | null,
|
|
156
168
|
): AstroIntegration {
|
|
157
|
-
// The '\0' prefix tells Vite “this is a virtual module” and prevents it from being resolved again.
|
|
158
|
-
const resolveVirtualModuleId = (id: string) => `\0${id}`;
|
|
159
169
|
let redirects: NormalizedRedirectConfig | null = null;
|
|
160
170
|
|
|
161
171
|
return {
|
|
@@ -168,43 +178,64 @@ function stainlessDocsIntegration(
|
|
|
168
178
|
redirects = normalizeRedirects(astroConfig.redirects);
|
|
169
179
|
}
|
|
170
180
|
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
181
|
+
const base = astroConfig.base ?? '/';
|
|
182
|
+
const withBase = (link: string) =>
|
|
183
|
+
/^([a-z][a-z0-9+.-]*:|\/\/)/.test(link) ? link : path.posix.join(base, link);
|
|
184
|
+
|
|
185
|
+
let vmAiChatHandlerExport = 'export const AI_CHAT_HANDLER = undefined;';
|
|
186
|
+
if (config.aiChat?.handlerEntrypoint) {
|
|
187
|
+
const rawEntrypoint = config.aiChat.handlerEntrypoint;
|
|
188
|
+
const handlerEntrypoint = rawEntrypoint.startsWith('file://')
|
|
189
|
+
? fileURLToPath(rawEntrypoint)
|
|
190
|
+
: path.isAbsolute(rawEntrypoint)
|
|
191
|
+
? rawEntrypoint
|
|
192
|
+
: path.resolve(fileURLToPath(astroConfig.root), rawEntrypoint);
|
|
193
|
+
vmAiChatHandlerExport = `export { default as AI_CHAT_HANDLER } from '${handlerEntrypoint}';`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const virtualModules = new Map<string, string>([
|
|
197
|
+
[
|
|
198
|
+
'virtual:stl-docs-virtual-module',
|
|
199
|
+
buildVirtualModuleString({
|
|
200
|
+
TABS: config.tabs.map((tab) => ({ ...tab, link: withBase(tab.link) })),
|
|
175
201
|
SPLIT_TABS_ENABLED: config.splitTabsEnabled,
|
|
176
|
-
HEADER_LINKS: config.header.links,
|
|
202
|
+
HEADER_LINKS: config.header.links.map((link) => ({ ...link, link: withBase(link.link) })),
|
|
177
203
|
HEADER_LAYOUT: config.header.layout,
|
|
178
204
|
ENABLE_CLIENT_ROUTER: config.enableClientRouter,
|
|
179
205
|
API_REFERENCE_BASE_PATH: apiReferenceBasePath ?? '/api',
|
|
180
206
|
ENABLE_PROSE_MARKDOWN_RENDERING: config.enableProseMarkdownRendering,
|
|
181
|
-
ENABLE_CONTEXT_MENU: config.contextMenu, // TODO: do not duplicate this between both virtual modules
|
|
207
|
+
ENABLE_CONTEXT_MENU: !!config.contextMenu, // TODO: do not duplicate this between both virtual modules
|
|
208
|
+
CONTEXT_MENU_ENABLE_THIRD_PARTY:
|
|
209
|
+
(typeof config.contextMenu === 'object' ? config.contextMenu.thirdParty : null) ?? true,
|
|
182
210
|
RENDER_PAGE_DESCRIPTIONS: config.renderPageDescriptions,
|
|
183
211
|
FONTS: getFontRoles(config.fonts),
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
212
|
+
LINK_GROUP_TITLES_TO_OVERVIEW_PAGES: config.linkGroupTitlesToOverviewPages,
|
|
213
|
+
RENDER_CREDITS: config.credits,
|
|
214
|
+
SITE_TITLE: config.siteTitle,
|
|
215
|
+
}),
|
|
216
|
+
],
|
|
217
|
+
['virtual:stl-docs-ai-chat', vmAiChatHandlerExport],
|
|
218
|
+
]);
|
|
219
|
+
if (config.aiChat) {
|
|
220
|
+
virtualModules.set(
|
|
221
|
+
'virtual:stl-docs-ai-chat-examples',
|
|
222
|
+
generateExamplesVirtualModule(config.aiChat.examples),
|
|
223
|
+
);
|
|
192
224
|
}
|
|
193
|
-
export const STAINLESS_PROJECT = ${config.apiReference ? JSON.stringify(config.apiReference.stainlessProject) : 'undefined'};
|
|
194
|
-
`,
|
|
195
|
-
}),
|
|
196
|
-
);
|
|
197
225
|
|
|
198
226
|
updateConfig({
|
|
199
|
-
|
|
200
|
-
fonts: [...flattenFonts(config.fonts), ...(astroConfig.experimental?.fonts ?? [])],
|
|
201
|
-
},
|
|
227
|
+
fonts: [...flattenFonts(config.fonts), ...(astroConfig?.fonts ?? [])],
|
|
202
228
|
vite: {
|
|
229
|
+
define: {
|
|
230
|
+
__STLDOCS_HAS_API_REFERENCE__: !!config.apiReference,
|
|
231
|
+
__STLDOCS_ENABLE_AI_CHAT__: !!config.aiChat,
|
|
232
|
+
},
|
|
203
233
|
plugins: [
|
|
204
234
|
{
|
|
205
|
-
name: 'stl-docs-
|
|
235
|
+
name: 'stl-docs-virtual-modules',
|
|
206
236
|
resolveId(id) {
|
|
207
|
-
|
|
237
|
+
// The '\0' prefix tells Vite "this is a virtual module" and prevents it from being resolved again.
|
|
238
|
+
if (virtualModules.has(id)) return `\0${id}`;
|
|
208
239
|
},
|
|
209
240
|
load(id) {
|
|
210
241
|
const bare = id.replace(/^\0/, '');
|
|
@@ -212,18 +243,6 @@ function stainlessDocsIntegration(
|
|
|
212
243
|
},
|
|
213
244
|
},
|
|
214
245
|
],
|
|
215
|
-
optimizeDeps: {
|
|
216
|
-
include: config.aiChat
|
|
217
|
-
? [
|
|
218
|
-
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > lucide-react',
|
|
219
|
-
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > motion',
|
|
220
|
-
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > motion > framer-motion',
|
|
221
|
-
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > react-markdown',
|
|
222
|
-
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > react-syntax-highlighter',
|
|
223
|
-
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > remark-gfm',
|
|
224
|
-
]
|
|
225
|
-
: [],
|
|
226
|
-
},
|
|
227
246
|
},
|
|
228
247
|
build: {
|
|
229
248
|
...astroConfig.build,
|
|
@@ -233,9 +252,9 @@ function stainlessDocsIntegration(
|
|
|
233
252
|
},
|
|
234
253
|
'astro:build:done': ({ dir }) => {
|
|
235
254
|
if (redirects !== null) {
|
|
236
|
-
const stainlessDir = join(dir.pathname, '_stainless');
|
|
255
|
+
const stainlessDir = path.join(dir.pathname, '_stainless');
|
|
237
256
|
mkdirSync(stainlessDir, { recursive: true });
|
|
238
|
-
const outputPath = join(stainlessDir, 'redirects.json');
|
|
257
|
+
const outputPath = path.join(stainlessDir, 'redirects.json');
|
|
239
258
|
writeFileSync(outputPath, JSON.stringify(redirects, null, 2), {
|
|
240
259
|
encoding: 'utf-8',
|
|
241
260
|
});
|
|
@@ -256,7 +275,7 @@ function sharedLoggerIntegration(): AstroIntegration {
|
|
|
256
275
|
};
|
|
257
276
|
}
|
|
258
277
|
|
|
259
|
-
export function stainlessDocs(config: StainlessDocsUserConfig):
|
|
278
|
+
export function stainlessDocs(config: StainlessDocsUserConfig): AstroIntegration[] {
|
|
260
279
|
const normalizedConfigResult = parseStlDocsConfig(config);
|
|
261
280
|
if (normalizedConfigResult.result === 'error') {
|
|
262
281
|
// TODO: would be good to use the astro logger somehow
|
|
@@ -279,11 +298,15 @@ export function stainlessDocs(config: StainlessDocsUserConfig): StarlightPlugin[
|
|
|
279
298
|
react(),
|
|
280
299
|
stainlessDocsStarlightIntegration(normalizedConfig),
|
|
281
300
|
stainlessDocsIntegration(normalizedConfig, apiReferenceBasePath),
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
apiReferenceBasePath,
|
|
301
|
+
conditionalIntegration({
|
|
302
|
+
condition: !config.experimental?.disableProseMarkdownRendering,
|
|
303
|
+
integration: stainlessDocsMarkdownRenderer({ apiReferenceBasePath }),
|
|
304
|
+
reason: 'disabled by experimental config "disableProseMarkdownRendering"',
|
|
305
|
+
}),
|
|
306
|
+
conditionalIntegration({
|
|
307
|
+
condition: !config.experimental?.disableStainlessProseIndexing,
|
|
308
|
+
integration: stainlessDocsVectorProseIndexing(normalizedConfig, apiReferenceBasePath),
|
|
309
|
+
reason: 'disabled by experimental config "disableStainlessProseIndexing"',
|
|
285
310
|
}),
|
|
286
|
-
stainlessDocsAlgoliaProseIndexing({ apiReferenceBasePath }),
|
|
287
|
-
stainlessDocsVectorProseIndexing(normalizedConfig, apiReferenceBasePath),
|
|
288
311
|
];
|
|
289
312
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { StainlessStarlightUserConfig } from '../plugin/loadPluginConfig';
|
|
2
|
-
import type {
|
|
2
|
+
import type { StarlightUserConfig } from '@astrojs/starlight/types';
|
|
3
3
|
import type { ButtonVariant } from '@stainless-api/ui-primitives';
|
|
4
4
|
import type { AnchorHTMLAttributes } from 'react';
|
|
5
5
|
import type starlight from '@astrojs/starlight';
|
|
6
6
|
import { normalizeFonts, type StlDocsFontConfig } from './fonts';
|
|
7
|
+
import type { ExamplePromptResponse } from './aiChatExamples';
|
|
8
|
+
import type { OGImageConfig } from './og-image/config';
|
|
7
9
|
|
|
8
10
|
type StarlightConfig = Parameters<typeof starlight>[0];
|
|
9
11
|
|
|
@@ -38,7 +40,7 @@ type PassThroughStarlightConfigOptions = Pick<
|
|
|
38
40
|
|
|
39
41
|
type ExperimentalStarlightCompatibilityConfig = Pick<
|
|
40
42
|
StarlightConfigDefined,
|
|
41
|
-
'components' | 'routeMiddleware' | 'plugins' | 'prerender'
|
|
43
|
+
'components' | 'routeMiddleware' | 'plugins' | 'prerender' | 'pagefind'
|
|
42
44
|
>;
|
|
43
45
|
|
|
44
46
|
export type Tabs = {
|
|
@@ -67,6 +69,7 @@ export type StainlessDocsUserConfig = {
|
|
|
67
69
|
layout?: HeaderLayout;
|
|
68
70
|
links?: HeaderLink[];
|
|
69
71
|
};
|
|
72
|
+
disableCredits?: boolean;
|
|
70
73
|
fonts?: StlDocsFontConfig;
|
|
71
74
|
experimental?: {
|
|
72
75
|
starlightCompat?: ExperimentalStarlightCompatibilityConfig;
|
|
@@ -77,14 +80,21 @@ export type StainlessDocsUserConfig = {
|
|
|
77
80
|
* @default false
|
|
78
81
|
*/
|
|
79
82
|
disableProseMarkdownRendering?: boolean;
|
|
80
|
-
|
|
83
|
+
disableStainlessProseIndexing?: boolean;
|
|
84
|
+
aiChat?: { handlerEntrypoint: string; examples?: ExamplePromptResponse };
|
|
85
|
+
/**
|
|
86
|
+
* Whether to link group titles to overview pages. Note: overview pages must already be present in the sidebar for this to work.
|
|
87
|
+
*
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
linkGroupTitlesToOverviewPages?: boolean;
|
|
81
91
|
};
|
|
82
92
|
/**
|
|
83
93
|
* Whether to show the context menu with options like "Copy as Markdown" and "Open in ChatGPT".
|
|
84
94
|
*
|
|
85
95
|
* @default true
|
|
86
96
|
*/
|
|
87
|
-
contextMenu?: boolean;
|
|
97
|
+
contextMenu?: boolean | { thirdParty?: boolean };
|
|
88
98
|
|
|
89
99
|
/**
|
|
90
100
|
* Whether to render page descriptions in prose page headers
|
|
@@ -93,10 +103,11 @@ export type StainlessDocsUserConfig = {
|
|
|
93
103
|
*/
|
|
94
104
|
renderPageDescriptions?: boolean;
|
|
95
105
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
106
|
+
* Enable and configure Open Graph image generation.
|
|
107
|
+
*
|
|
108
|
+
* Requires `takumi-js` to be installed as a dependency.
|
|
98
109
|
*/
|
|
99
|
-
|
|
110
|
+
ogImage?: OGImageConfig;
|
|
100
111
|
} & PassThroughStarlightConfigOptions;
|
|
101
112
|
|
|
102
113
|
type HeaderLayout = 'default' | 'stacked';
|
|
@@ -128,6 +139,19 @@ function normalizeRouteMiddleware(userConfig: StainlessDocsUserConfig) {
|
|
|
128
139
|
return entry;
|
|
129
140
|
}
|
|
130
141
|
|
|
142
|
+
function normalizeSiteTitle(userConfig: StainlessDocsUserConfig) {
|
|
143
|
+
if (typeof userConfig.title === 'string') {
|
|
144
|
+
return userConfig.title;
|
|
145
|
+
}
|
|
146
|
+
if (typeof userConfig.title === 'object') {
|
|
147
|
+
const firstValue = Object.values(userConfig.title)[0];
|
|
148
|
+
if (typeof firstValue === 'string') {
|
|
149
|
+
return firstValue;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
throw new Error('Site title provided in config is not valid.');
|
|
153
|
+
}
|
|
154
|
+
|
|
131
155
|
function normalizeConfig(userConfig: StainlessDocsUserConfig) {
|
|
132
156
|
const splitTabsEnabled = areSplitTabsEnabled(userConfig);
|
|
133
157
|
|
|
@@ -160,18 +184,24 @@ function normalizeConfig(userConfig: StainlessDocsUserConfig) {
|
|
|
160
184
|
starlightCompat: {
|
|
161
185
|
components: userConfig.experimental?.starlightCompat?.components ?? {},
|
|
162
186
|
plugins: userConfig.experimental?.starlightCompat?.plugins ?? [],
|
|
187
|
+
pagefind: userConfig.experimental?.starlightCompat?.pagefind ?? true,
|
|
163
188
|
routeMiddleware: normalizeRouteMiddleware(userConfig),
|
|
164
189
|
},
|
|
165
190
|
enableClientRouter: userConfig.experimental?.enableClientRouter ?? false,
|
|
166
191
|
apiReference: userConfig.apiReference ?? null,
|
|
167
192
|
sidebar: userConfig.sidebar,
|
|
193
|
+
enableStainlessProseIndexing:
|
|
194
|
+
userConfig.experimental?.disableStainlessProseIndexing === true ? false : true,
|
|
168
195
|
enableProseMarkdownRendering:
|
|
169
196
|
userConfig.experimental?.disableProseMarkdownRendering === true ? false : true,
|
|
170
197
|
contextMenu: userConfig.contextMenu ?? true,
|
|
171
198
|
expressiveCode: userConfig.expressiveCode,
|
|
172
199
|
renderPageDescriptions: userConfig.renderPageDescriptions ?? true,
|
|
173
|
-
plugins: userConfig.plugins ?? [],
|
|
174
200
|
aiChat: userConfig.experimental?.aiChat,
|
|
201
|
+
linkGroupTitlesToOverviewPages: userConfig.experimental?.linkGroupTitlesToOverviewPages ?? false,
|
|
202
|
+
credits: !userConfig.disableCredits,
|
|
203
|
+
siteTitle: normalizeSiteTitle(userConfig),
|
|
204
|
+
ogImage: userConfig.ogImage ?? null,
|
|
175
205
|
};
|
|
176
206
|
|
|
177
207
|
return configWithDefaults;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { darkThemeVars, lightThemeVars } from '../theme';
|
|
2
|
+
|
|
3
|
+
export default function OpenGraphFunctionSignature({
|
|
4
|
+
params,
|
|
5
|
+
fullyQualifiedName,
|
|
6
|
+
theme,
|
|
7
|
+
}: {
|
|
8
|
+
params: { ident: string; optional?: boolean }[] | undefined;
|
|
9
|
+
fullyQualifiedName: string | undefined;
|
|
10
|
+
theme?: 'light' | 'dark';
|
|
11
|
+
}) {
|
|
12
|
+
if (!params || !fullyQualifiedName) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const colors = theme === 'dark' ? darkThemeVars : lightThemeVars;
|
|
16
|
+
|
|
17
|
+
const joinedParams = params
|
|
18
|
+
.map((param) => {
|
|
19
|
+
if (param.optional) {
|
|
20
|
+
return `${param.ident}?`;
|
|
21
|
+
}
|
|
22
|
+
return param.ident;
|
|
23
|
+
})
|
|
24
|
+
.filter((p): p is string => p !== null)
|
|
25
|
+
.join(', ');
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<p
|
|
29
|
+
style={{
|
|
30
|
+
lineClamp: 1,
|
|
31
|
+
textOverflow: 'ellipsis',
|
|
32
|
+
fontSize: '33px',
|
|
33
|
+
lineHeight: '150%',
|
|
34
|
+
overflow: 'hidden',
|
|
35
|
+
width: '100%',
|
|
36
|
+
color: colors.foreground,
|
|
37
|
+
marginBottom: 0,
|
|
38
|
+
marginTop: 0,
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<span
|
|
42
|
+
style={{
|
|
43
|
+
color: colors.foregroundReduced,
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{fullyQualifiedName.split('.').slice(0, -1).join('.')}.
|
|
47
|
+
</span>
|
|
48
|
+
<span
|
|
49
|
+
style={{
|
|
50
|
+
fontWeight: 600,
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
{fullyQualifiedName.split('.').slice(-1)}
|
|
54
|
+
</span>
|
|
55
|
+
<span
|
|
56
|
+
style={{
|
|
57
|
+
fontWeight: 600,
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
({joinedParams})
|
|
61
|
+
</span>
|
|
62
|
+
</p>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { darkThemeVars, lightThemeVars, typography } from '../theme';
|
|
2
|
+
import { resolveLocalImageFile } from '../image-gen/get-logo-url';
|
|
3
|
+
import { OG_IMAGE_OPTIONS } from 'virtual:stainless-docs/docs-og-image';
|
|
4
|
+
|
|
5
|
+
/* The default open graph image template. It is expected to be used with takumi-js */
|
|
6
|
+
export default function OpenGraphImage({
|
|
7
|
+
title,
|
|
8
|
+
description,
|
|
9
|
+
logo,
|
|
10
|
+
children,
|
|
11
|
+
theme,
|
|
12
|
+
breadcrumbs,
|
|
13
|
+
}: {
|
|
14
|
+
title: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
logo?: string;
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
theme?: 'light' | 'dark';
|
|
19
|
+
breadcrumbs?: string[];
|
|
20
|
+
}) {
|
|
21
|
+
const colors = theme === 'dark' ? darkThemeVars : lightThemeVars;
|
|
22
|
+
|
|
23
|
+
const testLogo = OG_IMAGE_OPTIONS?.backgroundImage
|
|
24
|
+
? resolveLocalImageFile(OG_IMAGE_OPTIONS.backgroundImage.src)
|
|
25
|
+
: undefined;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
style={{
|
|
30
|
+
backgroundColor: colors.background,
|
|
31
|
+
width: '100%',
|
|
32
|
+
height: '100%',
|
|
33
|
+
display: 'flex',
|
|
34
|
+
alignItems: 'flex-start',
|
|
35
|
+
justifyContent: 'space-between',
|
|
36
|
+
flexDirection: 'column',
|
|
37
|
+
padding: '72px',
|
|
38
|
+
position: 'relative',
|
|
39
|
+
fontFeatureSettings: "'ss01' on, 'ss03' on, 'ss04' on, 'ss06' on",
|
|
40
|
+
lineHeight: `${typography.baseLineHeight}`,
|
|
41
|
+
fontSize: `${typography.baseFontSize}`,
|
|
42
|
+
letterSpacing: `${typography.baseLetterSpacing}`,
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{testLogo && (
|
|
46
|
+
<img
|
|
47
|
+
src={testLogo}
|
|
48
|
+
alt="Background"
|
|
49
|
+
style={{
|
|
50
|
+
position: 'absolute',
|
|
51
|
+
top: 0,
|
|
52
|
+
right: 0,
|
|
53
|
+
zIndex: -1,
|
|
54
|
+
...OG_IMAGE_OPTIONS?.backgroundImage?.style,
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
{logo && <img src={logo} alt="Logo" style={{ height: '80px', marginBottom: '24px' }} />}
|
|
59
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '100%' }}>
|
|
60
|
+
{breadcrumbs && breadcrumbs.length > 0 && (
|
|
61
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', color: colors.foregroundMuted }}>
|
|
62
|
+
{breadcrumbs.map((crumb, index) => (
|
|
63
|
+
<div key={index} style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
64
|
+
{index > 0 && (
|
|
65
|
+
<svg
|
|
66
|
+
width="32"
|
|
67
|
+
height="32"
|
|
68
|
+
viewBox="0 0 32 32"
|
|
69
|
+
fill="none"
|
|
70
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
71
|
+
>
|
|
72
|
+
<g opacity="0.6">
|
|
73
|
+
<path
|
|
74
|
+
d="M11.0573 7.05727C11.578 6.53657 12.422 6.53657 12.9427 7.05727L20.9427 15.0573C21.4634 15.578 21.4634 16.422 20.9427 16.9427L12.9427 24.9427C12.422 25.4634 11.578 25.4634 11.0573 24.9427C10.5366 24.422 10.5366 23.578 11.0573 23.0573L18.1146 16L11.0573 8.94269C10.5366 8.42199 10.5366 7.57797 11.0573 7.05727Z"
|
|
75
|
+
fill={colors.foreground}
|
|
76
|
+
/>
|
|
77
|
+
</g>
|
|
78
|
+
</svg>
|
|
79
|
+
)}
|
|
80
|
+
<span
|
|
81
|
+
style={{
|
|
82
|
+
fontSize: `${typography.breadcrumbFontSize}`,
|
|
83
|
+
lineHeight: `${typography.breadcrumbLineHeight}`,
|
|
84
|
+
letterSpacing: `${typography.breadcrumbLetterSpacing}`,
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
{crumb}
|
|
88
|
+
</span>
|
|
89
|
+
</div>
|
|
90
|
+
))}
|
|
91
|
+
</div>
|
|
92
|
+
)}
|
|
93
|
+
<h1
|
|
94
|
+
style={{
|
|
95
|
+
marginBottom: '0',
|
|
96
|
+
marginTop: '0',
|
|
97
|
+
fontWeight: 600,
|
|
98
|
+
color: colors.foreground,
|
|
99
|
+
letterSpacing: `${typography.headerLetterSpacing}`,
|
|
100
|
+
lineClamp: 2,
|
|
101
|
+
textOverflow: 'ellipsis',
|
|
102
|
+
lineHeight: `${typography.headerLineHeight}`,
|
|
103
|
+
fontSize: `${typography.headerFontSize}`,
|
|
104
|
+
textWrap: 'balance',
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
{title}
|
|
108
|
+
</h1>
|
|
109
|
+
{description && (
|
|
110
|
+
<p
|
|
111
|
+
style={{
|
|
112
|
+
color: colors.foregroundMuted,
|
|
113
|
+
marginBottom: 0,
|
|
114
|
+
marginTop: 0,
|
|
115
|
+
lineClamp: 2,
|
|
116
|
+
textOverflow: 'ellipsis',
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
119
|
+
{description}
|
|
120
|
+
</p>
|
|
121
|
+
)}
|
|
122
|
+
{children}
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Exported utilites for @stainless-api/docs consumers
|
|
2
|
+
|
|
3
|
+
import type { ImageResponseOptions } from 'takumi-js/response';
|
|
4
|
+
import type { CSSProperties } from 'react';
|
|
5
|
+
|
|
6
|
+
export type OGImageConfig = {
|
|
7
|
+
/**
|
|
8
|
+
* Path to source file for logo to include in generated OG images
|
|
9
|
+
*
|
|
10
|
+
* example: './src/assets/og-logo.png'
|
|
11
|
+
*/
|
|
12
|
+
logo?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Takumi ImageResponseOptions for OG image generation
|
|
15
|
+
*/
|
|
16
|
+
renderOptions?: Omit<ImageResponseOptions, 'fonts'>;
|
|
17
|
+
/**
|
|
18
|
+
* A background image for the OG images. A tailwind `tw` string can be provided to style the image.
|
|
19
|
+
*
|
|
20
|
+
* example: './src/assets/og-background-logo.png'
|
|
21
|
+
*/
|
|
22
|
+
backgroundImage?: {
|
|
23
|
+
/**
|
|
24
|
+
* Path to source file for background image
|
|
25
|
+
*
|
|
26
|
+
* example: './src/assets/og-background-logo.png'
|
|
27
|
+
*/
|
|
28
|
+
src: string;
|
|
29
|
+
/**
|
|
30
|
+
* Style applied to the background image using React CSSProperties
|
|
31
|
+
*
|
|
32
|
+
* example: { right: -20px }
|
|
33
|
+
*/
|
|
34
|
+
style?: CSSProperties;
|
|
35
|
+
};
|
|
36
|
+
/** Preferred theme for the OG images
|
|
37
|
+
*/
|
|
38
|
+
theme?: 'light' | 'dark';
|
|
39
|
+
/** The base path for the docs site. To be used when setting `base` within your astro config is not sufficient depending on hosting strategy.
|
|
40
|
+
* If your docs site is hosted at a subpath (e.g. example.com/docs), set the basePath to '/docs'.
|
|
41
|
+
*
|
|
42
|
+
* example: '/docs'
|
|
43
|
+
*/
|
|
44
|
+
basePath?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Override the default OG image components with custom implementations.
|
|
47
|
+
* Each value should be a file path to a component that exports a default React component.
|
|
48
|
+
*
|
|
49
|
+
* You can import the default components from `@stainless-api/docs/og-image/components/OpenGraphImage`
|
|
50
|
+
* and `@stainless-api/docs/og-image/components/OpenGraphFunctionSignature` to compose with them.
|
|
51
|
+
*/
|
|
52
|
+
components?: {
|
|
53
|
+
OpenGraphImage?: string;
|
|
54
|
+
OpenGraphFunctionSignature?: string;
|
|
55
|
+
};
|
|
56
|
+
};
|