@stainless-api/docs 0.1.0-beta.13 → 0.1.0-beta.130
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 +1102 -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
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import type { AstroIntegration } from 'astro';
|
|
2
|
+
import { readFile } from 'fs/promises';
|
|
3
|
+
import { getProsePages } from '../shared/getProsePages';
|
|
4
|
+
import { getSharedLogger } from '../shared/getSharedLogger';
|
|
5
|
+
import { bold } from '../shared/terminalUtils';
|
|
6
|
+
import * as cheerio from 'cheerio';
|
|
7
|
+
import { buildProseIndex } from '@stainless-api/docs-search/providers/algolia';
|
|
8
|
+
|
|
9
|
+
class SectionContext {
|
|
10
|
+
headers: { level: number; text: string }[] = [];
|
|
11
|
+
headerId: string | undefined;
|
|
12
|
+
headerTag: string | undefined;
|
|
13
|
+
headerText: string | undefined;
|
|
14
|
+
hasContent = false;
|
|
15
|
+
|
|
16
|
+
get(): string | undefined {
|
|
17
|
+
if (this.headers.length === 0) return;
|
|
18
|
+
return this.headers.map((h) => h.text).join(' > ');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
header({ id, tag, text }: { id: string; tag: string; text: string }) {
|
|
22
|
+
const level = getHeaderLevel(tag);
|
|
23
|
+
if (level > 0) {
|
|
24
|
+
while (this.headers.length > 0 && this.headers[this.headers.length - 1]!.level >= level) {
|
|
25
|
+
this.headers.pop();
|
|
26
|
+
}
|
|
27
|
+
this.headers.push({ level, text });
|
|
28
|
+
}
|
|
29
|
+
this.headerId = id;
|
|
30
|
+
this.headerTag = tag;
|
|
31
|
+
this.headerText = text;
|
|
32
|
+
this.hasContent = false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function slugify(text: string): string {
|
|
37
|
+
return text
|
|
38
|
+
.toLowerCase()
|
|
39
|
+
.replace(/`/g, '')
|
|
40
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
41
|
+
.replace(/^-|-$/g, '');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getHeaderLevel(tag: string): number {
|
|
45
|
+
const match = tag.match(/^h(\d)$/);
|
|
46
|
+
return match ? parseInt(match[1]!, 10) : 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Chunking configuration
|
|
50
|
+
// We target 64-256 tokens per chunk, using ~1.3 tokens/word for English text
|
|
51
|
+
const TOKENS_PER_WORD = 1.3;
|
|
52
|
+
const MIN_TOKENS = 64;
|
|
53
|
+
const MAX_TOKENS = 256;
|
|
54
|
+
const MIN_WORDS = Math.floor(MIN_TOKENS / TOKENS_PER_WORD); // ~49 words
|
|
55
|
+
const MAX_WORDS = Math.floor(MAX_TOKENS / TOKENS_PER_WORD); // ~197 words
|
|
56
|
+
const SENTENCE_BREAK_WORDS = Math.floor((MAX_TOKENS * 0.875) / TOKENS_PER_WORD); // ~172 words
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Chunks text content into segments of 64-256 tokens using word-based boundaries.
|
|
60
|
+
* Prefers breaking at sentence endings for natural chunk boundaries.
|
|
61
|
+
*/
|
|
62
|
+
function chunkTextByWords(text: string): string[] {
|
|
63
|
+
const words = text.split(/\s+/).filter((w) => w.length > 0);
|
|
64
|
+
|
|
65
|
+
if (words.length <= MAX_WORDS) {
|
|
66
|
+
return words.length > 0 ? [words.join(' ')] : [];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const chunks: string[] = [];
|
|
70
|
+
let currentChunk: string[] = [];
|
|
71
|
+
|
|
72
|
+
for (const word of words) {
|
|
73
|
+
currentChunk.push(word);
|
|
74
|
+
|
|
75
|
+
// Force break at max words
|
|
76
|
+
if (currentChunk.length >= MAX_WORDS) {
|
|
77
|
+
chunks.push(currentChunk.join(' '));
|
|
78
|
+
currentChunk = [];
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Prefer breaking at sentence boundaries after threshold
|
|
83
|
+
if (currentChunk.length >= SENTENCE_BREAK_WORDS && /[.!?]["']?$/.test(word)) {
|
|
84
|
+
chunks.push(currentChunk.join(' '));
|
|
85
|
+
currentChunk = [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (currentChunk.length > 0) {
|
|
90
|
+
if (currentChunk.length < MIN_WORDS && chunks.length > 0) {
|
|
91
|
+
const lastChunk = chunks[chunks.length - 1]!;
|
|
92
|
+
const mergedWords = lastChunk.split(/\s+/).length + currentChunk.length;
|
|
93
|
+
if (mergedWords <= MAX_WORDS) {
|
|
94
|
+
chunks[chunks.length - 1] = lastChunk + ' ' + currentChunk.join(' ');
|
|
95
|
+
} else {
|
|
96
|
+
chunks.push(currentChunk.join(' '));
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
chunks.push(currentChunk.join(' '));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return chunks;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type IndexEntry = {
|
|
107
|
+
chunk: { id: string; index: number; total: number };
|
|
108
|
+
id: string;
|
|
109
|
+
tag: string;
|
|
110
|
+
content: string;
|
|
111
|
+
language?: string;
|
|
112
|
+
sectionContext?: string;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const DEFAULT_ROOT = 'main';
|
|
116
|
+
const DEFAULT_PATTERN = 'h1, h2, h3, h4, h5, h6, p, li, pre code';
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Indexes HTML content for search, with section context and code language extraction.
|
|
120
|
+
*
|
|
121
|
+
* Features:
|
|
122
|
+
* - Tracks header hierarchy to prepend section context (e.g., "Guide > Setup: ...")
|
|
123
|
+
* - Extracts language metadata from code blocks (class="language-js")
|
|
124
|
+
* - Uses word-based chunking with sentence boundary detection
|
|
125
|
+
*/
|
|
126
|
+
function* indexHTML(content: string, root = DEFAULT_ROOT, pattern = DEFAULT_PATTERN): Generator<IndexEntry> {
|
|
127
|
+
const $ = cheerio.load(content);
|
|
128
|
+
const matches = $(root).find(pattern);
|
|
129
|
+
|
|
130
|
+
const ctx = new SectionContext();
|
|
131
|
+
|
|
132
|
+
for (const match of matches) {
|
|
133
|
+
const tagName = match.tagName.toLowerCase();
|
|
134
|
+
const rawText = $(match).text().trim();
|
|
135
|
+
|
|
136
|
+
if (getHeaderLevel(tagName) > 0) {
|
|
137
|
+
ctx.header({ id: $(match).attr('id') ?? slugify(rawText), tag: tagName, text: rawText });
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Check if this is a code block and extract language
|
|
142
|
+
const isCode = tagName === 'code' && $(match).parent().is('pre');
|
|
143
|
+
let language: string | undefined;
|
|
144
|
+
if (isCode) {
|
|
145
|
+
const classes = $(match).attr('class') || '';
|
|
146
|
+
const langMatch = classes.match(/(?:language-|lang-)([a-zA-Z0-9+-]+)/);
|
|
147
|
+
language = langMatch ? langMatch[1] : undefined;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Build content with section context
|
|
151
|
+
const sectionContext = ctx.get();
|
|
152
|
+
const chunks = chunkTextByWords(rawText);
|
|
153
|
+
const chunkId = crypto.randomUUID();
|
|
154
|
+
|
|
155
|
+
for (const [chunkN, chunkText] of chunks.entries()) {
|
|
156
|
+
yield {
|
|
157
|
+
id: ctx.headerId ?? $(match).attr('id') ?? chunkId,
|
|
158
|
+
tag: isCode ? 'code' : tagName,
|
|
159
|
+
content: chunkText,
|
|
160
|
+
...(sectionContext ? { sectionContext } : {}),
|
|
161
|
+
...(language && { language }),
|
|
162
|
+
chunk: {
|
|
163
|
+
id: chunkId,
|
|
164
|
+
index: chunkN,
|
|
165
|
+
total: chunks.length,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
ctx.hasContent = true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function stainlessDocsAlgoliaProseIndexing({
|
|
174
|
+
apiReferenceBasePath,
|
|
175
|
+
}: {
|
|
176
|
+
apiReferenceBasePath: string | null;
|
|
177
|
+
}): AstroIntegration {
|
|
178
|
+
return {
|
|
179
|
+
name: 'stl-docs-prose-indexing',
|
|
180
|
+
hooks: {
|
|
181
|
+
'astro:build:done': async ({ logger: localLogger, dir }) => {
|
|
182
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
183
|
+
const outputBasePath = dir.pathname;
|
|
184
|
+
|
|
185
|
+
const {
|
|
186
|
+
PUBLIC_ALGOLIA_APP_ID: appId,
|
|
187
|
+
PUBLIC_ALGOLIA_INDEX: indexName,
|
|
188
|
+
PRIVATE_ALGOLIA_WRITE_KEY: algoliaWriteKey,
|
|
189
|
+
} = process.env;
|
|
190
|
+
|
|
191
|
+
if (!appId || !indexName || !algoliaWriteKey) {
|
|
192
|
+
logger.info('Skipping algolia indexing due to missing environment variables');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const pagesToRender = await getProsePages({ apiReferenceBasePath, outputBasePath });
|
|
197
|
+
logger.info(bold(`Indexing ${pagesToRender.length} prose pages for algolia search`));
|
|
198
|
+
|
|
199
|
+
const objects = [];
|
|
200
|
+
for (const absHtmlPath of pagesToRender) {
|
|
201
|
+
const content = await readFile(absHtmlPath, 'utf-8');
|
|
202
|
+
const idx = indexHTML(content);
|
|
203
|
+
for (const entry of idx)
|
|
204
|
+
objects.push({
|
|
205
|
+
...entry,
|
|
206
|
+
source: absHtmlPath.slice(outputBasePath.length),
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
await buildProseIndex(appId, `${indexName}-prose`, algoliaWriteKey, objects);
|
|
212
|
+
} catch (err) {
|
|
213
|
+
logger.error(`Failed to index prose content: ${err}`);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
}
|
|
@@ -3,6 +3,7 @@ import { defineRouteMiddleware } from '@astrojs/starlight/route-data';
|
|
|
3
3
|
|
|
4
4
|
import { SPLIT_TABS_ENABLED, TABS } from 'virtual:stl-docs-virtual-module';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
|
+
import path from 'path';
|
|
6
7
|
|
|
7
8
|
// this fn is loaded in the plugin via addRouteMiddleware
|
|
8
9
|
|
|
@@ -58,7 +59,7 @@ function getTabIndexForSlug(
|
|
|
58
59
|
match: 'exact' | 'prefix';
|
|
59
60
|
} | null {
|
|
60
61
|
// ↓ exact match eg. slug = "/blog" and there is a link containing "/blog"
|
|
61
|
-
|
|
62
|
+
const tab = linksByTab.get(slug)!;
|
|
62
63
|
if (typeof tab === 'string') {
|
|
63
64
|
return {
|
|
64
65
|
match: 'exact',
|
|
@@ -88,18 +89,24 @@ function getNonSplitLinksByTab() {
|
|
|
88
89
|
const linksByTab = new Map<string, string>();
|
|
89
90
|
|
|
90
91
|
for (let i = 0; i < TABS.length; i++) {
|
|
91
|
-
const tab = TABS[i]
|
|
92
|
+
const tab = TABS[i]!;
|
|
92
93
|
linksByTab.set(tab.link, String(i));
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
return linksByTab;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
export
|
|
99
|
+
export interface StarlightRouteWithStlDocs extends StarlightRouteData {
|
|
100
|
+
_stlDocs?: {
|
|
101
|
+
activeTabIndex: number;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const onRequest = defineRouteMiddleware((context) => {
|
|
99
106
|
// if using content collection schema, use: context.locals.starlightRoute.entry.data.stainlessStarlight
|
|
100
107
|
// this worked without collections but relied on hijacking starlightRoute: context.props.frontmatter.stainlessStarlight
|
|
101
108
|
|
|
102
|
-
const slug =
|
|
109
|
+
const slug = path.posix.join(import.meta.env.BASE_URL ?? '', context.locals.starlightRoute.id); // same as .slug but not deprecated
|
|
103
110
|
|
|
104
111
|
/*
|
|
105
112
|
In the index of our starlight plugin, we transform our "tabs" into a plain old Starlight sidebar.
|
|
@@ -143,7 +150,8 @@ export const onRequest = defineRouteMiddleware(async (context) => {
|
|
|
143
150
|
}
|
|
144
151
|
|
|
145
152
|
// We store the active tab index so we can use it in our nav tabs component
|
|
146
|
-
context.locals.starlightRoute
|
|
153
|
+
const routeData: StarlightRouteWithStlDocs = context.locals.starlightRoute;
|
|
154
|
+
routeData._stlDocs = {
|
|
147
155
|
activeTabIndex: activeTabIndex.index,
|
|
148
156
|
};
|
|
149
157
|
|
|
@@ -179,5 +187,6 @@ export const onRequest = defineRouteMiddleware(async (context) => {
|
|
|
179
187
|
|
|
180
188
|
matchingGroup?.entries.unshift(...mobileLinks);
|
|
181
189
|
|
|
190
|
+
(context.locals._stlStarlightPage ??= {}).fullSidebar = context.locals.starlightRoute.sidebar;
|
|
182
191
|
context.locals.starlightRoute.sidebar = matchingGroup.entries;
|
|
183
192
|
});
|
package/styles/code.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.expressive-code {
|
|
2
2
|
.frame {
|
|
3
|
-
--code-background: var(--
|
|
3
|
+
--code-background: var(--stl-color-faint-background);
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
figure.frame {
|
|
@@ -10,19 +10,19 @@
|
|
|
10
10
|
figure,
|
|
11
11
|
pre {
|
|
12
12
|
border-radius: var(--sl-button-border-radius);
|
|
13
|
-
border-color: var(--
|
|
13
|
+
border-color: var(--stl-color-border);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.frame.has-title:not(.is-terminal),
|
|
17
17
|
.frame.is-terminal {
|
|
18
18
|
figcaption {
|
|
19
19
|
border-radius: var(--sl-button-border-radius) var(--sl-button-border-radius) 0 0;
|
|
20
|
-
border-color: var(--
|
|
20
|
+
border-color: var(--stl-color-border);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
pre {
|
|
24
24
|
border-radius: 0 0 var(--sl-button-border-radius) var(--sl-button-border-radius);
|
|
25
|
-
border-color: var(--
|
|
25
|
+
border-color: var(--stl-color-border);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.header::before {
|
|
35
|
-
border-color: var(--
|
|
35
|
+
border-color: var(--stl-color-border);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
.title::after {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
.astro-code {
|
|
46
46
|
border-radius: var(--sl-button-border-radius);
|
|
47
|
-
border-color: var(--
|
|
47
|
+
border-color: var(--stl-color-border);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
.stl-snippet-request-container {
|
|
@@ -52,14 +52,34 @@
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
.stl-snippet-expand-button {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
position: relative;
|
|
55
|
+
position: absolute;
|
|
58
56
|
left: 50%;
|
|
59
|
-
transform: translateX(-50%);
|
|
60
|
-
bottom: 12px;
|
|
57
|
+
transform: translateX(-50%) translateY(-50%);
|
|
61
58
|
cursor: pointer;
|
|
62
59
|
height: auto;
|
|
60
|
+
z-index: 100;
|
|
61
|
+
|
|
62
|
+
&:not(.stl-snippet-collapsible .stl-snippet-expand-button) {
|
|
63
|
+
display: none;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&.stl-ui-button {
|
|
67
|
+
background-color: var(--stl-color-background);
|
|
68
|
+
background-image: linear-gradient(
|
|
69
|
+
to right,
|
|
70
|
+
var(--stl-color-ui-background),
|
|
71
|
+
var(--stl-color-ui-background)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&.stl-ui-button:hover {
|
|
76
|
+
background-color: var(--stl-color-background);
|
|
77
|
+
background-image: linear-gradient(
|
|
78
|
+
to right,
|
|
79
|
+
var(--stl-color-ui-background-hover),
|
|
80
|
+
var(--stl-color-ui-background-hover)
|
|
81
|
+
);
|
|
82
|
+
}
|
|
63
83
|
}
|
|
64
84
|
|
|
65
85
|
.stl-snippet-code-is-expanded {
|
|
@@ -69,13 +89,6 @@
|
|
|
69
89
|
}
|
|
70
90
|
|
|
71
91
|
.stl-snippet-collapsible {
|
|
72
|
-
.stl-snippet-expand-button {
|
|
73
|
-
display: block;
|
|
74
|
-
margin-bottom: -23px;
|
|
75
|
-
/* Prevent clipping of the button with the container below */
|
|
76
|
-
z-index: 100;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
92
|
.stl-snippet-code-is-collapsed {
|
|
80
93
|
.hidden {
|
|
81
94
|
display: none;
|
|
@@ -121,35 +134,25 @@
|
|
|
121
134
|
.stl-snippet-dropdown-button-text {
|
|
122
135
|
font-weight: 500;
|
|
123
136
|
font-style: normal;
|
|
124
|
-
font-family: var(--
|
|
137
|
+
font-family: var(--stl-typography-font);
|
|
125
138
|
line-height: 100%;
|
|
126
|
-
font-size: var(--
|
|
127
|
-
color: var(--
|
|
128
|
-
text-transform: capitalize;
|
|
129
|
-
|
|
130
|
-
&.http {
|
|
131
|
-
text-transform: uppercase;
|
|
132
|
-
}
|
|
139
|
+
font-size: var(--stl-typography-scale-sm);
|
|
140
|
+
color: var(--stl-color-foreground);
|
|
133
141
|
}
|
|
134
142
|
|
|
135
|
-
|
|
143
|
+
.shiki,
|
|
144
|
+
.astro-code,
|
|
145
|
+
.stldocs-snippet-response-pane {
|
|
146
|
+
background-color: var(--shiki-background, var(--stl-color-faint-background)) !important;
|
|
147
|
+
.shiki,
|
|
136
148
|
.astro-code,
|
|
137
|
-
.astro-code span {
|
|
138
|
-
background-color: var(--sl-color-bg-inline-code) !important;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
149
|
.stldocs-snippet-response-pane {
|
|
142
|
-
|
|
143
|
-
.shiki span,
|
|
144
|
-
.astro-code,
|
|
145
|
-
.astro-code span {
|
|
146
|
-
background-color: var(--sl-color-bg-inline-code) !important;
|
|
147
|
-
}
|
|
150
|
+
background-color: transparent !important;
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
:root[data-theme='dark'] {
|
|
152
|
-
/*
|
|
155
|
+
/*
|
|
153
156
|
Need to use important to override inline variables. This is the
|
|
154
157
|
recommended pattern in the shiki docs.
|
|
155
158
|
|
|
@@ -160,23 +163,24 @@
|
|
|
160
163
|
.astro-code,
|
|
161
164
|
.astro-code span {
|
|
162
165
|
color: var(--shiki-dark) !important;
|
|
163
|
-
background-color: var(--sl-color-bg) !important;
|
|
164
166
|
font-style: var(--shiki-dark-font-style) !important;
|
|
165
167
|
font-weight: var(--shiki-dark-font-weight) !important;
|
|
166
168
|
text-decoration: var(--shiki-dark-text-decoration) !important;
|
|
167
169
|
}
|
|
170
|
+
}
|
|
168
171
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
.stldocs-snippet .stldocs-snippet-footer.try-it-footer {
|
|
173
|
+
display: none;
|
|
174
|
+
justify-content: flex-end;
|
|
175
|
+
gap: 0.5rem;
|
|
176
|
+
|
|
177
|
+
/* only show footer if RequestBuilder was rendered successfully */
|
|
178
|
+
stl-island[component='SnippetStainlessIsland'] & {
|
|
179
|
+
display: flex;
|
|
172
180
|
}
|
|
173
181
|
|
|
174
|
-
.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
.astro-code,
|
|
178
|
-
.astro-code span {
|
|
179
|
-
background-color: var(--sl-color-bg-inline-code) !important;
|
|
180
|
-
}
|
|
182
|
+
.try-it-button,
|
|
183
|
+
.send-button {
|
|
184
|
+
width: 7rem;
|
|
181
185
|
}
|
|
182
186
|
}
|
package/styles/links.css
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* TODO: remove for real card component */
|
|
2
|
+
|
|
1
3
|
.sl-link-card {
|
|
2
4
|
box-shadow: none;
|
|
3
5
|
border-radius: var(--sl-button-border-radius);
|
|
@@ -10,40 +12,3 @@
|
|
|
10
12
|
border: 1px solid var(--sl-color-accent-high);
|
|
11
13
|
background-color: var(--sl-color-accent-low);
|
|
12
14
|
}
|
|
13
|
-
|
|
14
|
-
.pagination-links {
|
|
15
|
-
margin-bottom: 2rem;
|
|
16
|
-
|
|
17
|
-
> a {
|
|
18
|
-
border-radius: var(--sl-button-border-radius);
|
|
19
|
-
border: 1px solid transparent;
|
|
20
|
-
box-shadow: none;
|
|
21
|
-
max-width: 90%;
|
|
22
|
-
text-decoration: none;
|
|
23
|
-
|
|
24
|
-
svg {
|
|
25
|
-
margin-top: 0;
|
|
26
|
-
transform: translateY(6px);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
> a:hover {
|
|
31
|
-
transition: 0.3s;
|
|
32
|
-
border: 1px solid var(--sl-color-accent-high);
|
|
33
|
-
background-color: var(--sl-color-accent-low);
|
|
34
|
-
box-shadow: none;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* if only one pagination direction */
|
|
38
|
-
> a:first-child:nth-last-child(1) {
|
|
39
|
-
max-width: 45%;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
> a[rel='next'] {
|
|
43
|
-
margin-left: auto;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
> a[rel='prev'] {
|
|
47
|
-
margin-right: auto;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.stldocs-root {
|
|
2
|
+
.stl-method-description-overflow-wrapper {
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
/* Minimum height to minimize layout shift */
|
|
7
|
+
min-height: 24px;
|
|
8
|
+
}
|
|
9
|
+
.stl-method-description {
|
|
10
|
+
.stldocs-method-description {
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
max-height: 170px;
|
|
13
|
+
transition: max-height 0.3s ease;
|
|
14
|
+
position: relative;
|
|
15
|
+
|
|
16
|
+
&::after {
|
|
17
|
+
content: '';
|
|
18
|
+
position: absolute;
|
|
19
|
+
left: 0;
|
|
20
|
+
right: 0;
|
|
21
|
+
bottom: 0;
|
|
22
|
+
height: 3rem;
|
|
23
|
+
background: linear-gradient(to bottom, transparent, var(--stl-color-background));
|
|
24
|
+
pointer-events: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&[data-collapsed='false'] {
|
|
28
|
+
max-height: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&[data-collapsed='false']::after {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
package/styles/overrides.css
CHANGED
|
@@ -3,8 +3,7 @@ html {
|
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
.site-title {
|
|
6
|
-
color: var(--
|
|
7
|
-
max-width: 144px;
|
|
6
|
+
color: var(--stl-color-foreground);
|
|
8
7
|
|
|
9
8
|
img {
|
|
10
9
|
height: 32px;
|
|
@@ -12,66 +11,49 @@ html {
|
|
|
12
11
|
}
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
/*
|
|
16
|
-
starlight-theme-select select {
|
|
17
|
-
width: 0;
|
|
18
|
-
overflow: hidden;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.custom-select-wrapper select,
|
|
22
|
-
.stldocs-button-secondary {
|
|
23
|
-
background-color: var(--sl-color-bg-ui);
|
|
24
|
-
border: 1px solid var(--sl-color-hairline);
|
|
25
|
-
border-radius: var(--sl-button-border-radius);
|
|
26
|
-
|
|
27
|
-
&:hover {
|
|
28
|
-
border-color: var(--sl-color-hairline-shade);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.content-panel {
|
|
33
|
-
border-top: 0;
|
|
34
|
-
}
|
|
35
|
-
|
|
14
|
+
/* TODO: apply real button classes here */
|
|
36
15
|
starlight-menu-button button {
|
|
37
16
|
box-shadow: none;
|
|
38
|
-
background-color: var(--
|
|
39
|
-
border: 1px solid var(--
|
|
40
|
-
border-radius: var(--
|
|
41
|
-
height:
|
|
42
|
-
width:
|
|
17
|
+
background-color: var(--stl-color-ui-background);
|
|
18
|
+
border: 1px solid var(--stl-color-border);
|
|
19
|
+
border-radius: var(--stl-ui-layout-border-radius-sml);
|
|
20
|
+
height: 32px;
|
|
21
|
+
width: 32px;
|
|
43
22
|
display: flex;
|
|
44
23
|
align-items: center;
|
|
45
24
|
justify-content: center;
|
|
46
25
|
|
|
47
26
|
&:hover {
|
|
48
|
-
|
|
27
|
+
background-color: var(--stl-color-ui-background-hover);
|
|
49
28
|
}
|
|
50
29
|
}
|
|
51
30
|
|
|
52
31
|
mobile-starlight-toc {
|
|
53
32
|
nav {
|
|
54
|
-
background-color: var(--
|
|
33
|
+
background-color: var(--stl-color-background);
|
|
34
|
+
}
|
|
35
|
+
.toggle {
|
|
36
|
+
background-color: var(--stl-color-ui-background);
|
|
37
|
+
border: 1px solid var(--stl-color-border);
|
|
38
|
+
border-radius: var(--stl-ui-layout-border-radius-sml);
|
|
39
|
+
&:hover {
|
|
40
|
+
background-color: var(--stl-color-ui-background-hover);
|
|
41
|
+
border-color: var(--stl-color-border); /* unchanged */
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
.dropdown {
|
|
45
|
+
background-color: var(--stl-color-background);
|
|
46
|
+
border-color: var(--stl-color-border-faint);
|
|
55
47
|
}
|
|
56
|
-
|
|
57
48
|
summary {
|
|
58
49
|
padding: 2rem 1rem;
|
|
59
|
-
border-
|
|
50
|
+
border-color: var(--stl-color-border-faint);
|
|
60
51
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
@media (min-width: 50rem) {
|
|
64
|
-
starlight-menu-button button {
|
|
65
|
-
display: none;
|
|
52
|
+
a {
|
|
53
|
+
border-color: var(--stl-color-border-faint);
|
|
66
54
|
}
|
|
55
|
+
}
|
|
67
56
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
inset-inline-start: calc(var(--sl-content-inline-start, 0));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
summary {
|
|
74
|
-
padding: 2rem 2rem;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
57
|
+
starlight-menu-button {
|
|
58
|
+
display: none;
|
|
77
59
|
}
|