@stainless-api/docs 0.1.0-beta.2 → 0.1.0-beta.20
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 +147 -0
- package/components/variables.css +1 -27
- package/eslint-suppressions.json +47 -0
- package/locals.d.ts +14 -0
- package/package.json +30 -27
- package/plugin/buildAlgoliaIndex.ts +29 -4
- package/plugin/cms/server.ts +97 -54
- package/plugin/cms/sidebar-builder.ts +6 -25
- package/plugin/cms/worker.ts +2 -2
- package/plugin/components/SnippetCode.tsx +7 -4
- package/plugin/components/search/SearchAlgolia.astro +0 -7
- package/plugin/components/search/SearchIsland.tsx +30 -17
- package/plugin/generateAPIReferenceLink.ts +1 -1
- package/plugin/globalJs/ai-dropdown-options.ts +161 -0
- package/plugin/globalJs/navigation.ts +0 -23
- package/plugin/helpers/getPageLoadEvent.ts +1 -1
- package/plugin/index.ts +49 -17
- package/plugin/languages.ts +1 -1
- package/plugin/loadPluginConfig.ts +92 -13
- package/plugin/react/Routing.tsx +30 -33
- package/plugin/referencePlaceholderUtils.ts +1 -1
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +4 -0
- package/plugin/routes/Docs.astro +59 -85
- package/plugin/routes/Overview.astro +9 -15
- package/plugin/routes/markdown.ts +1 -1
- package/plugin/vendor/preview.worker.docs.js +6357 -6132
- package/resolveSrcFile.ts +10 -0
- package/shared/getSharedLogger.ts +15 -0
- package/shared/terminalUtils.ts +3 -0
- package/src/content.config.ts +9 -0
- package/stl-docs/components/AIDropdown.tsx +52 -0
- package/stl-docs/components/Head.astro +9 -0
- package/stl-docs/components/Header.astro +3 -2
- package/stl-docs/components/PageTitle.astro +65 -0
- package/stl-docs/components/TableOfContents.astro +34 -0
- package/stl-docs/components/ThemeSelect.astro +4 -2
- package/stl-docs/components/content-panel/ContentPanel.astro +9 -39
- package/stl-docs/components/headers/DefaultHeader.astro +1 -1
- package/stl-docs/components/headers/HeaderLinks.astro +1 -1
- package/stl-docs/components/headers/StackedHeader.astro +30 -25
- package/stl-docs/components/icons/chat-gpt.tsx +17 -0
- package/stl-docs/components/icons/claude.tsx +10 -0
- package/stl-docs/components/icons/markdown.tsx +10 -0
- package/stl-docs/components/index.ts +2 -0
- package/stl-docs/components/mintlify-compat/Accordion.astro +7 -38
- package/stl-docs/components/mintlify-compat/AccordionGroup.astro +9 -23
- package/stl-docs/components/mintlify-compat/Columns.astro +40 -42
- package/stl-docs/components/mintlify-compat/Frame.astro +16 -18
- package/stl-docs/components/mintlify-compat/Step.astro +30 -32
- package/stl-docs/components/mintlify-compat/Steps.astro +8 -10
- package/stl-docs/components/mintlify-compat/callouts/Callout.astro +10 -3
- package/stl-docs/components/mintlify-compat/callouts/Check.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Danger.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Info.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Note.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Tip.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Warning.astro +7 -3
- package/stl-docs/components/mintlify-compat/card.css +33 -35
- package/stl-docs/components/nav-tabs/NavDropdown.astro +1 -1
- package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -7
- package/stl-docs/components/nav-tabs/buildNavLinks.ts +4 -3
- package/stl-docs/components/pagination/HomeLink.astro +10 -0
- package/stl-docs/components/pagination/Pagination.astro +173 -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/{Sidebar.astro → sidebars/BaseSidebar.astro} +2 -3
- package/stl-docs/components/sidebars/SDKSelectSidebar.astro +8 -0
- package/stl-docs/disableCalloutSyntax.ts +36 -0
- package/stl-docs/index.ts +76 -13
- package/stl-docs/loadStlDocsConfig.ts +25 -3
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +64 -0
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +34 -0
- package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
- package/stl-docs/tabsMiddleware.ts +12 -4
- package/styles/code.css +115 -127
- package/styles/fonts.css +24 -9
- package/styles/links.css +10 -49
- package/styles/overrides.css +55 -57
- package/styles/page.css +89 -59
- package/styles/sdk_select.css +6 -7
- package/styles/search.css +65 -67
- package/styles/sidebar.css +199 -128
- package/styles/toc.css +37 -33
- package/theme.css +9 -1
- package/tsconfig.json +2 -5
- package/virtual-module.d.ts +4 -1
- package/plugin/globalJs/ai-dropdown.ts +0 -57
- package/stl-docs/components/APIReferenceAIDropdown.tsx +0 -86
- package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -64
- /package/stl-docs/components/{content-panel/ContentBreadcrumbs.tsx → ContentBreadcrumbs.tsx} +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
4
|
|
|
3
5
|
import type { CreateShikiHighlighterOptions } from '@astrojs/markdown-remark';
|
|
4
6
|
import type { DocsLanguage } from '@stainless-api/docs-ui/src/routing';
|
|
5
7
|
import type { PropertySettingsType } from '@stainless-api/docs-ui/src/contexts';
|
|
6
8
|
import type { InputFilePaths } from '../plugin/cms/server';
|
|
9
|
+
import { bold } from '../shared/terminalUtils';
|
|
7
10
|
|
|
8
11
|
export type AstroCommand = 'dev' | 'build' | 'preview' | 'sync';
|
|
9
12
|
|
|
@@ -18,7 +21,7 @@ export type VersionUserConfig = {
|
|
|
18
21
|
type BreadcrumbUserConfig = {
|
|
19
22
|
/**
|
|
20
23
|
* Include the current page in the breadcrumb list.
|
|
21
|
-
*
|
|
24
|
+
* Default: `false`
|
|
22
25
|
*/
|
|
23
26
|
includeCurrentPage?: boolean;
|
|
24
27
|
};
|
|
@@ -26,7 +29,12 @@ type BreadcrumbUserConfig = {
|
|
|
26
29
|
export type StainlessStarlightUserConfig = {
|
|
27
30
|
/**
|
|
28
31
|
* Optional api key for Stainless API.
|
|
29
|
-
* If not provided,
|
|
32
|
+
* If not provided, we will handle Stainless auth via the `stl` CLI or look for the STAINLESS_API_KEY environment variable.
|
|
33
|
+
* Precedence:
|
|
34
|
+
* 1. Explicity `apiKey` option provided
|
|
35
|
+
* 2. `STAINLESS_API_KEY` environment variable
|
|
36
|
+
* 3. Login status from the `stl` CLI
|
|
37
|
+
* 4. Error (no auth found)
|
|
30
38
|
*/
|
|
31
39
|
apiKey?: string;
|
|
32
40
|
|
|
@@ -42,7 +50,7 @@ export type StainlessStarlightUserConfig = {
|
|
|
42
50
|
|
|
43
51
|
/**
|
|
44
52
|
* Optional mount point for API reference docs.
|
|
45
|
-
*
|
|
53
|
+
* Default: `/api`
|
|
46
54
|
* Example: `/my-api` → docs available at `/my-api/…`.
|
|
47
55
|
*/
|
|
48
56
|
basePath?: string;
|
|
@@ -55,7 +63,7 @@ export type StainlessStarlightUserConfig = {
|
|
|
55
63
|
|
|
56
64
|
/**
|
|
57
65
|
* Optional language to treat as the default when the user hasn't selected one.
|
|
58
|
-
*
|
|
66
|
+
* Default: `"http"`
|
|
59
67
|
* Example: `"python"`
|
|
60
68
|
*/
|
|
61
69
|
defaultLanguage?: DocsLanguage;
|
|
@@ -90,7 +98,7 @@ export type StainlessStarlightUserConfig = {
|
|
|
90
98
|
contentPanel?: {
|
|
91
99
|
/**
|
|
92
100
|
* Optional layout for the content panel.
|
|
93
|
-
*
|
|
101
|
+
* Default: `"double-pane"`
|
|
94
102
|
*/
|
|
95
103
|
layout?: ContentLayout;
|
|
96
104
|
};
|
|
@@ -107,6 +115,8 @@ export type StainlessStarlightUserConfig = {
|
|
|
107
115
|
/**
|
|
108
116
|
* When set to `true`, the enableAISearch` setting turns on support for
|
|
109
117
|
* LLM-based conversations with the API documentation
|
|
118
|
+
*
|
|
119
|
+
* Default: `false`
|
|
110
120
|
*/
|
|
111
121
|
enableAISearch?: boolean;
|
|
112
122
|
};
|
|
@@ -114,7 +124,8 @@ export type StainlessStarlightUserConfig = {
|
|
|
114
124
|
/**
|
|
115
125
|
* Enable experimental collapsible code snippets. Snippets will be collapsed by default for
|
|
116
126
|
* single-pane and mobile layouts.
|
|
117
|
-
*
|
|
127
|
+
*
|
|
128
|
+
* Default: `false`
|
|
118
129
|
*/
|
|
119
130
|
experimentalCollapsibleSnippets?: boolean;
|
|
120
131
|
};
|
|
@@ -133,15 +144,29 @@ function getLocalFilePaths(command: AstroCommand): InputFilePaths | null {
|
|
|
133
144
|
if (command !== 'dev') {
|
|
134
145
|
return null;
|
|
135
146
|
}
|
|
136
|
-
|
|
147
|
+
|
|
148
|
+
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
149
|
+
const oasPath = process.env.OPENAPI_PATH;
|
|
150
|
+
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
151
|
+
const configPath = process.env.STAINLESS_CONFIG_PATH;
|
|
152
|
+
|
|
153
|
+
if (!oasPath || !configPath) {
|
|
137
154
|
return null;
|
|
138
155
|
}
|
|
156
|
+
|
|
139
157
|
return {
|
|
140
|
-
oasPath: resolvePath(
|
|
141
|
-
configPath: resolvePath(
|
|
158
|
+
oasPath: resolvePath(oasPath),
|
|
159
|
+
configPath: resolvePath(configPath),
|
|
142
160
|
};
|
|
143
161
|
}
|
|
144
162
|
|
|
163
|
+
export type ApiKeySource = 'explicit-config' | 'environment-variable' | 'cli';
|
|
164
|
+
|
|
165
|
+
export type LoadedApiKey = {
|
|
166
|
+
value: string;
|
|
167
|
+
source: ApiKeySource;
|
|
168
|
+
};
|
|
169
|
+
|
|
145
170
|
export type SpecRetrieverConfig =
|
|
146
171
|
| {
|
|
147
172
|
kind: 'external_spec_server';
|
|
@@ -152,16 +177,63 @@ export type SpecRetrieverConfig =
|
|
|
152
177
|
kind: 'local_spec_server_with_files';
|
|
153
178
|
stainlessProject: string;
|
|
154
179
|
devPaths: InputFilePaths;
|
|
155
|
-
apiKey:
|
|
180
|
+
apiKey: LoadedApiKey | null;
|
|
156
181
|
version: VersionUserConfig;
|
|
157
182
|
}
|
|
158
183
|
| {
|
|
159
184
|
kind: 'local_spec_server_with_remote_files';
|
|
160
185
|
stainlessProject: string;
|
|
161
|
-
apiKey:
|
|
186
|
+
apiKey: LoadedApiKey;
|
|
162
187
|
version: VersionUserConfig;
|
|
163
188
|
};
|
|
164
189
|
|
|
190
|
+
function parseAuthJson(authJsonStr: string) {
|
|
191
|
+
let json: unknown;
|
|
192
|
+
try {
|
|
193
|
+
json = JSON.parse(authJsonStr);
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
195
|
+
} catch (_error) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (typeof json !== 'object' || json === null) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
if (!('access_token' in json)) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
const accessToken = json['access_token'];
|
|
206
|
+
if (typeof accessToken !== 'string') {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return accessToken;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function loadApiKey(configValue: string | undefined): LoadedApiKey | null {
|
|
213
|
+
if (typeof configValue === 'string') {
|
|
214
|
+
return { value: configValue, source: 'explicit-config' };
|
|
215
|
+
}
|
|
216
|
+
if (process.env.STAINLESS_API_KEY) {
|
|
217
|
+
return { value: process.env.STAINLESS_API_KEY, source: 'environment-variable' };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const homeDirPath = homedir();
|
|
221
|
+
|
|
222
|
+
const authJsonPath = path.join(homeDirPath, '.config', 'stainless', 'auth.json');
|
|
223
|
+
|
|
224
|
+
if (!existsSync(authJsonPath)) {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const authJsonStr = readFileSync(authJsonPath, 'utf-8');
|
|
229
|
+
const accessToken = parseAuthJson(authJsonStr);
|
|
230
|
+
if (!accessToken) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return { value: accessToken, source: 'cli' };
|
|
235
|
+
}
|
|
236
|
+
|
|
165
237
|
function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: AstroCommand) {
|
|
166
238
|
const configWithDefaults = {
|
|
167
239
|
basePath: partial.basePath ?? '/api',
|
|
@@ -205,7 +277,7 @@ function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: Ast
|
|
|
205
277
|
throw new Error('You must provide a stainlessProject when using Stainless Starlight');
|
|
206
278
|
}
|
|
207
279
|
|
|
208
|
-
const apiKey = partial.apiKey
|
|
280
|
+
const apiKey = loadApiKey(partial.apiKey);
|
|
209
281
|
|
|
210
282
|
const version = {
|
|
211
283
|
stainlessProject: partial.stainlessProject,
|
|
@@ -226,7 +298,14 @@ function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: Ast
|
|
|
226
298
|
|
|
227
299
|
if (!apiKey) {
|
|
228
300
|
throw new Error(
|
|
229
|
-
|
|
301
|
+
[
|
|
302
|
+
bold(
|
|
303
|
+
'No Stainless credentials found. Please choose one of the following options to authenticate with Stainless:',
|
|
304
|
+
),
|
|
305
|
+
'- Run `stl auth login` to authenticate via the Stainless CLI',
|
|
306
|
+
'- Provide a Stainless API key via the `STAINLESS_API_KEY` environment variable (eg. in a .env file)',
|
|
307
|
+
'- Set the `apiKey` option in the Stainless Docs config',
|
|
308
|
+
].join('\n'),
|
|
230
309
|
);
|
|
231
310
|
}
|
|
232
311
|
|
package/plugin/react/Routing.tsx
CHANGED
|
@@ -6,8 +6,8 @@ import remarkGfmAlerts from 'remark-github-alerts';
|
|
|
6
6
|
|
|
7
7
|
import type { MarkdownHeading } from 'astro';
|
|
8
8
|
import type { StarlightRouteData } from '@astrojs/starlight/route-data';
|
|
9
|
-
import type * as SDKJSON from '
|
|
10
|
-
import type
|
|
9
|
+
import type * as SDKJSON from '@stainless/sdk-json';
|
|
10
|
+
import { LanguageNames, type DocsLanguage } from '@stainless-api/docs-ui/src/routing';
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
generateRouteList,
|
|
@@ -48,14 +48,14 @@ import {
|
|
|
48
48
|
HIGHLIGHT_THEMES,
|
|
49
49
|
BREADCRUMB_CONFIG,
|
|
50
50
|
PROPERTY_SETTINGS,
|
|
51
|
+
ENABLE_CONTEXT_MENU,
|
|
51
52
|
} from 'virtual:stl-starlight-virtual-module';
|
|
52
53
|
import style from '@stainless-api/docs-ui/src/style';
|
|
53
54
|
import { createHighlighter, type BundledLanguage, type BundledTheme, type HighlighterGeneric } from 'shiki';
|
|
54
55
|
import { SnippetCode, SnippetContainer, SnippetRequestContainer } from '../components/SnippetCode';
|
|
55
|
-
import clsx from 'clsx';
|
|
56
56
|
import type { StlStarlightMiddleware } from '../middlewareBuilder/stainlessMiddleware';
|
|
57
57
|
import { ComponentProvider } from '@stainless-api/docs-ui/src/contexts/component';
|
|
58
|
-
import {
|
|
58
|
+
import { AIDropdown } from '../../stl-docs/components/AIDropdown';
|
|
59
59
|
|
|
60
60
|
export function generateDocsRoutes(spec: SDKJSON.Spec) {
|
|
61
61
|
const paths = generateRouteList({
|
|
@@ -120,7 +120,6 @@ export function buildSidebar(
|
|
|
120
120
|
|
|
121
121
|
const meths: SidebarEntry[] = Object.values(resource.methods ?? [])
|
|
122
122
|
.filter((method) => spec.decls?.[language]?.[method.stainlessPath])
|
|
123
|
-
.toSorted((first, second) => first.name.localeCompare(second.name))
|
|
124
123
|
.map((method) => ({
|
|
125
124
|
type: 'link',
|
|
126
125
|
isCurrent: current === method.stainlessPath,
|
|
@@ -179,25 +178,25 @@ export function SDKSelectReactComponent({
|
|
|
179
178
|
return (
|
|
180
179
|
<Dropdown id={id} data-current-value={selected} className={className}>
|
|
181
180
|
<DropdownTrigger
|
|
182
|
-
className="dropdown-toggle
|
|
181
|
+
className="dropdown-toggle"
|
|
183
182
|
type="button"
|
|
184
|
-
id="
|
|
183
|
+
id="stl-docs-snippet-title-button"
|
|
185
184
|
aria-expanded="false"
|
|
186
185
|
withChevron
|
|
187
186
|
>
|
|
188
187
|
<SDKIcon language={getLanguageSnippet(selected)} size={16} />
|
|
189
|
-
<span className=
|
|
188
|
+
<span className="stl-snippet-dropdown-button-text">{LanguageNames[selected]}</span>
|
|
190
189
|
</DropdownTrigger>
|
|
191
190
|
<DropdownMenu
|
|
192
191
|
className="dropdown-menu stl-sdk-select-dropdown-menu"
|
|
193
192
|
position="below"
|
|
194
|
-
aria-labelledby="
|
|
193
|
+
aria-labelledby="stl-docs-snippet-title-button"
|
|
195
194
|
>
|
|
196
195
|
{languages.map((item) => (
|
|
197
196
|
<DropdownItem key={item} value={item} selected={item === selected}>
|
|
198
197
|
<div>
|
|
199
198
|
<SDKIcon language={getLanguageSnippet(item)} size={16} />
|
|
200
|
-
<span className=
|
|
199
|
+
<span className="stl-snippet-dropdown-button-text">{LanguageNames[item]}</span>
|
|
201
200
|
</div>
|
|
202
201
|
</DropdownItem>
|
|
203
202
|
))}
|
|
@@ -302,7 +301,10 @@ export function RenderSpec({
|
|
|
302
301
|
const parsed = parseStainlessPath(path);
|
|
303
302
|
const resource = getResourceFromSpec(path, spec);
|
|
304
303
|
|
|
305
|
-
if (!resource || !parsed)
|
|
304
|
+
if (!resource || !parsed) {
|
|
305
|
+
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
306
308
|
|
|
307
309
|
return (
|
|
308
310
|
<DocsProvider
|
|
@@ -323,7 +325,7 @@ export function RenderSpec({
|
|
|
323
325
|
>
|
|
324
326
|
<NavigationProvider basePath={BASE_PATH} selectedPath={path}>
|
|
325
327
|
<MarkdownProvider render={renderMarkdown} highlight={highlight}>
|
|
326
|
-
{
|
|
328
|
+
{
|
|
327
329
|
<div className="stldocs-root stl-ui-not-prose">
|
|
328
330
|
<div className="stl-page-nav-container">
|
|
329
331
|
<SDKBreadcrumbs
|
|
@@ -332,27 +334,18 @@ export function RenderSpec({
|
|
|
332
334
|
basePath={BASE_PATH}
|
|
333
335
|
config={BREADCRUMB_CONFIG}
|
|
334
336
|
/>
|
|
335
|
-
<
|
|
337
|
+
{ENABLE_CONTEXT_MENU && <AIDropdown />}
|
|
336
338
|
</div>
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
</div>
|
|
342
|
-
) : (
|
|
343
|
-
<div className="stldocs-root stl-ui-not-prose">
|
|
344
|
-
<div className="stl-page-nav-container">
|
|
345
|
-
<SDKBreadcrumbs
|
|
346
|
-
spec={spec as SDKJSON.Spec}
|
|
347
|
-
currentPath={currentPath}
|
|
348
|
-
basePath={BASE_PATH}
|
|
349
|
-
config={BREADCRUMB_CONFIG}
|
|
339
|
+
{kind === 'http_method' ? (
|
|
340
|
+
<SDKMethod
|
|
341
|
+
method={resource.methods[parsed.method!]!}
|
|
342
|
+
transformRequestSnippet={transformRequestSnippet}
|
|
350
343
|
/>
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
344
|
+
) : (
|
|
345
|
+
<SDKOverview resource={resource} />
|
|
346
|
+
)}
|
|
354
347
|
</div>
|
|
355
|
-
|
|
348
|
+
}
|
|
356
349
|
</MarkdownProvider>
|
|
357
350
|
</NavigationProvider>
|
|
358
351
|
</ComponentProvider>
|
|
@@ -366,10 +359,14 @@ export function RenderMethod({ path }: { path: string }) {
|
|
|
366
359
|
|
|
367
360
|
const parsed = parseStainlessPath(path);
|
|
368
361
|
const resource = getResourceFromSpec(path, spec);
|
|
369
|
-
if (!resource || !parsed) return null;
|
|
370
362
|
|
|
371
|
-
|
|
372
|
-
|
|
363
|
+
if (!resource || !parsed) {
|
|
364
|
+
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const method = resource.methods[parsed.method!]!;
|
|
369
|
+
return <SDKMethod method={method} />;
|
|
373
370
|
}
|
|
374
371
|
|
|
375
372
|
export async function getReadmeContent(spec: SDKJSON.Spec, language: DocsLanguage) {
|
|
@@ -58,7 +58,7 @@ function recursiveGetPlaceholderItems(
|
|
|
58
58
|
items: PlaceholderItemResult[],
|
|
59
59
|
): PlaceholderItemResult[] {
|
|
60
60
|
for (let i = 0; i < sidebar.length; i++) {
|
|
61
|
-
const entry = sidebar[i]
|
|
61
|
+
const entry = sidebar[i]!;
|
|
62
62
|
if ('attrs' in entry && entry.attrs?.about === INTERNAL_REFERENCE_ENTRY_MARKER) {
|
|
63
63
|
items.push({
|
|
64
64
|
index: i,
|
|
@@ -15,6 +15,10 @@ export const onRequest = defineRouteMiddleware(async (context) => {
|
|
|
15
15
|
|
|
16
16
|
const slug = `/${context.locals.starlightRoute.id}`; // same as .slug but not deprecated
|
|
17
17
|
|
|
18
|
+
context.locals.starlightRoute._stlStarlight = {
|
|
19
|
+
basePath: BASE_PATH,
|
|
20
|
+
};
|
|
21
|
+
|
|
18
22
|
const apiReferencePlaceholderItems = getAPIReferencePlaceholderItems(context.locals.starlightRoute.sidebar);
|
|
19
23
|
|
|
20
24
|
const spec = await cmsClient.getSpec();
|
package/plugin/routes/Docs.astro
CHANGED
|
@@ -1,24 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
import StarlightPage from
|
|
3
|
-
import { cmsClient } from
|
|
4
|
-
|
|
5
|
-
import "@stainless-api/docs-ui/src/styles/resets.css";
|
|
6
|
-
import "@stainless-api/docs-ui/src/styles/primitives.css";
|
|
7
|
-
import "@stainless-api/docs-ui/src/styles/main.css";
|
|
8
|
-
import "@stainless-api/docs-ui/src/styles/snippets.css";
|
|
9
|
-
// TODO: fix variables.css import
|
|
10
|
-
// import "./variables.css";
|
|
11
|
-
|
|
2
|
+
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
|
|
3
|
+
import { cmsClient } from '../cms/client';
|
|
12
4
|
import {
|
|
13
5
|
getReadmeContent,
|
|
14
6
|
generateDocsRoutes,
|
|
15
7
|
buildPageNavigation,
|
|
16
8
|
RenderSpec,
|
|
17
9
|
astroMarkdownRender,
|
|
18
|
-
} from
|
|
19
|
-
import { getResourceFromSpec } from
|
|
20
|
-
import { BASE_PATH, CONTENT_PANEL_LAYOUT,MIDDLEWARE } from
|
|
21
|
-
|
|
10
|
+
} from '../react/Routing';
|
|
11
|
+
import { getResourceFromSpec } from '@stainless-api/docs-ui/src/utils';
|
|
12
|
+
import { BASE_PATH, CONTENT_PANEL_LAYOUT, MIDDLEWARE } from 'virtual:stl-starlight-virtual-module';
|
|
22
13
|
|
|
23
14
|
const spec = await cmsClient.getSpec();
|
|
24
15
|
const routes = generateDocsRoutes(spec);
|
|
@@ -26,23 +17,23 @@ const routes = generateDocsRoutes(spec);
|
|
|
26
17
|
const route = routes.find((r) => r.params.slug === Astro.params.slug);
|
|
27
18
|
|
|
28
19
|
if (!route) {
|
|
29
|
-
throw new Error(
|
|
20
|
+
throw new Error(`Could not find a route for slug '${Astro.params.slug}'`);
|
|
30
21
|
}
|
|
31
22
|
|
|
23
|
+
// PageTitle override will skip rendering the default Starlight title
|
|
24
|
+
Astro.locals._stlStarlightPage = {
|
|
25
|
+
skipRenderingStarlightTitle: route.props.kind === 'readme' ? false : true,
|
|
26
|
+
};
|
|
27
|
+
|
|
32
28
|
const readmeContent = await getReadmeContent(spec, route.props.language);
|
|
33
|
-
const readme =
|
|
34
|
-
route.props.kind === "readme"
|
|
35
|
-
? await astroMarkdownRender(readmeContent ?? "")
|
|
36
|
-
: null;
|
|
29
|
+
const readme = route.props.kind === 'readme' ? await astroMarkdownRender(readmeContent ?? '') : null;
|
|
37
30
|
|
|
38
|
-
const resource = route.props.stainlessPath
|
|
39
|
-
? getResourceFromSpec(route.props.stainlessPath, spec)
|
|
40
|
-
: null;
|
|
31
|
+
const resource = route.props.stainlessPath ? getResourceFromSpec(route.props.stainlessPath, spec) : null;
|
|
41
32
|
|
|
42
33
|
const pageNav =
|
|
43
|
-
route.props.kind ===
|
|
34
|
+
route.props.kind === 'resource' && resource
|
|
44
35
|
? buildPageNavigation(resource)
|
|
45
|
-
: route.props.kind ===
|
|
36
|
+
: route.props.kind === 'readme' && readme?.metadata
|
|
46
37
|
? readme?.metadata.headings
|
|
47
38
|
: [];
|
|
48
39
|
|
|
@@ -50,38 +41,27 @@ const props = route.props;
|
|
|
50
41
|
|
|
51
42
|
if (readme) {
|
|
52
43
|
const repo = spec.metadata?.[props.language]?.code_url;
|
|
53
|
-
readme.code = readme.code.replace(
|
|
54
|
-
|
|
55
|
-
`<a href="${repo}/$1"`);
|
|
56
|
-
props.title = readme.metadata.headings[0].text ?? "Overview";
|
|
44
|
+
readme.code = readme.code.replace(/<a href="(?!(?:https?:\/\/|\/\/))([^"]+)"/g, `<a href="${repo}/$1"`);
|
|
45
|
+
props.title = readme.metadata.headings[0]!.text ?? 'Overview';
|
|
57
46
|
}
|
|
58
|
-
|
|
59
47
|
---
|
|
60
48
|
|
|
61
|
-
|
|
62
49
|
<StarlightPage
|
|
63
50
|
headings={pageNav}
|
|
64
51
|
frontmatter={{
|
|
65
52
|
title: props?.title,
|
|
66
53
|
head: [
|
|
67
54
|
{
|
|
68
|
-
tag:
|
|
55
|
+
tag: 'link',
|
|
69
56
|
attrs: {
|
|
70
|
-
rel:
|
|
71
|
-
type:
|
|
72
|
-
href: `${BASE_PATH}/${Astro.params.slug}.md
|
|
73
|
-
}
|
|
74
|
-
}
|
|
57
|
+
rel: 'alternate',
|
|
58
|
+
type: 'text/markdown',
|
|
59
|
+
href: `${BASE_PATH}/${Astro.params.slug}.md`,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
75
62
|
],
|
|
76
63
|
pagefind: false,
|
|
77
|
-
tableOfContents: [
|
|
78
|
-
? { maxHeadingLevel: 6 }
|
|
79
|
-
: false,
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
stainlessStarlight: {
|
|
82
|
-
basePath: BASE_PATH,
|
|
83
|
-
...props,
|
|
84
|
-
},
|
|
64
|
+
tableOfContents: ['resource', 'readme'].includes(props.kind) ? { maxHeadingLevel: 6 } : false,
|
|
85
65
|
}}
|
|
86
66
|
>
|
|
87
67
|
{
|
|
@@ -97,7 +77,9 @@ if (readme) {
|
|
|
97
77
|
transformRequestSnippet={MIDDLEWARE.transformRequestSnippet}
|
|
98
78
|
/>
|
|
99
79
|
|
|
100
|
-
<style
|
|
80
|
+
<style
|
|
81
|
+
is:inline
|
|
82
|
+
set:text={`
|
|
101
83
|
#stldocs-snippet-title {
|
|
102
84
|
display: flex;
|
|
103
85
|
gap: 5px;
|
|
@@ -105,61 +87,53 @@ if (readme) {
|
|
|
105
87
|
|
|
106
88
|
.stldocs-snippet-code:not(.stldocs-snippet-response .stldocs-snippet-code) {
|
|
107
89
|
padding: 0 !important;
|
|
108
|
-
|
|
90
|
+
|
|
109
91
|
.astro-code {
|
|
110
92
|
padding: 1rem;
|
|
111
93
|
}
|
|
112
94
|
}
|
|
113
95
|
|
|
114
|
-
|
|
115
96
|
[data-has-sidebar]:not([data-has-toc]) .sl-container {
|
|
116
97
|
max-width: 1428px;
|
|
117
98
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
display: none;
|
|
121
|
-
}
|
|
122
|
-
.content-panel:nth-of-type(2) .stl-page-nav-container {
|
|
123
|
-
display: none;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.content-panel:nth-of-type(2) .stldocs-root .stl-page-nav-container {
|
|
127
|
-
display: flex;
|
|
128
|
-
}
|
|
129
|
-
</style>
|
|
99
|
+
`}
|
|
100
|
+
/>
|
|
130
101
|
</div>
|
|
131
102
|
) : (
|
|
132
103
|
<>
|
|
133
104
|
<Fragment set:html={readme?.code} />
|
|
134
|
-
<style
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
105
|
+
<style
|
|
106
|
+
is:inline
|
|
107
|
+
set:text={`
|
|
108
|
+
.sl-markdown-content h1:first-of-type {
|
|
109
|
+
display: none;
|
|
110
|
+
}
|
|
138
111
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
112
|
+
.sl-markdown-content img {
|
|
113
|
+
display: inline-block;
|
|
114
|
+
vertical-align: text-bottom;
|
|
115
|
+
}
|
|
143
116
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
117
|
+
.sl-markdown-content .octicon {
|
|
118
|
+
margin-right: 0.2rem;
|
|
119
|
+
overflow: visible !important;
|
|
120
|
+
-webkit-mask: var(--oct-icon) no-repeat;
|
|
121
|
+
mask: var(--oct-icon) no-repeat;
|
|
122
|
+
-webkit-mask-size: 100% 100%;
|
|
123
|
+
mask-size: 100% 100%;
|
|
124
|
+
background-color: currentColor;
|
|
125
|
+
color: inherit;
|
|
126
|
+
display: inline-block;
|
|
127
|
+
vertical-align: text-bottom;
|
|
128
|
+
width: 1em;
|
|
129
|
+
height: 1em;
|
|
130
|
+
}
|
|
158
131
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
132
|
+
.sl-markdown-content code {
|
|
133
|
+
white-space: pre-wrap;
|
|
134
|
+
}
|
|
135
|
+
`}
|
|
136
|
+
/>
|
|
163
137
|
</>
|
|
164
138
|
)
|
|
165
139
|
}
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
|
|
3
|
-
import {
|
|
3
|
+
import { EXCLUDE_LANGUAGES } from 'virtual:stl-starlight-virtual-module';
|
|
4
4
|
import { cmsClient } from '../cms/client';
|
|
5
5
|
import type { DocsLanguage } from '@stainless-api/docs-ui/src/routing';
|
|
6
|
-
|
|
7
|
-
import '@stainless-api/docs-ui/src/styles/resets.css';
|
|
8
|
-
import '@stainless-api/docs-ui/src/styles/primitives.css';
|
|
9
|
-
import '@stainless-api/docs-ui/src/styles/main.css';
|
|
10
|
-
import '@stainless-api/docs-ui/src/styles/snippets.css';
|
|
11
|
-
// TODO: fix variables.css import
|
|
12
|
-
// import '../components/variables.css';
|
|
13
6
|
import { RenderLibraries, RenderSpecOverview, type SpecMetadata } from '../react/Routing';
|
|
14
7
|
|
|
15
8
|
const spec = await cmsClient.getSpec();
|
|
16
9
|
|
|
17
10
|
const languages: DocsLanguage[] = spec.docs!.languages ?? ['http'];
|
|
18
|
-
const metadata = languages
|
|
11
|
+
const metadata: SpecMetadata = languages
|
|
19
12
|
.filter((language) => !['http', 'terraform'].includes(language) && spec.metadata[language])
|
|
20
13
|
.filter((language) => !EXCLUDE_LANGUAGES.includes(language))
|
|
21
|
-
.map((language) => [language, spec.metadata[language]])
|
|
14
|
+
.map<SpecMetadata[number]>((language) => [language, spec.metadata[language]!]);
|
|
15
|
+
|
|
16
|
+
// PageTitle override will skip rendering the default Starlight title
|
|
17
|
+
Astro.locals._stlStarlightPage = {
|
|
18
|
+
hasMarkdownRoute: false,
|
|
19
|
+
};
|
|
22
20
|
---
|
|
23
21
|
|
|
24
22
|
<StarlightPage
|
|
@@ -26,15 +24,11 @@ const metadata = languages
|
|
|
26
24
|
title: 'API Reference',
|
|
27
25
|
pagefind: false,
|
|
28
26
|
tableOfContents: false,
|
|
29
|
-
stainlessStarlight: {
|
|
30
|
-
basePath: BASE_PATH,
|
|
31
|
-
language: 'http',
|
|
32
|
-
},
|
|
33
27
|
}}
|
|
34
28
|
>
|
|
35
29
|
<h3>Libraries</h3>
|
|
36
30
|
|
|
37
|
-
<div class="stldocs-root language-blocks stl-ui-not-prose">
|
|
31
|
+
<div class="stldocs-root language-blocks stl-ui-not-prose not-content">
|
|
38
32
|
<RenderLibraries metadata={metadata} />
|
|
39
33
|
</div>
|
|
40
34
|
|
|
@@ -47,7 +47,7 @@ export const GET: APIRoute<RouteProps> = async ({ props }) => {
|
|
|
47
47
|
},
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
const target = props.kind === 'http_method' && parsed?.method ? resource.methods[parsed.method] : resource;
|
|
50
|
+
const target = props.kind === 'http_method' && parsed?.method ? resource.methods[parsed.method]! : resource;
|
|
51
51
|
const output = renderMarkdown(env, target);
|
|
52
52
|
|
|
53
53
|
return new Response(output, {
|