@stainless-api/docs 0.1.0-beta.15 → 0.1.0-beta.16
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 +9 -0
- package/package.json +9 -17
- package/plugin/buildAlgoliaIndex.ts +28 -3
- package/plugin/cms/server.ts +95 -52
- package/plugin/cms/sidebar-builder.ts +0 -9
- package/plugin/globalJs/ai-dropdown-options.ts +161 -0
- package/plugin/globalJs/navigation.ts +0 -22
- package/plugin/index.ts +46 -17
- package/plugin/loadPluginConfig.ts +90 -21
- package/plugin/react/Routing.tsx +13 -23
- package/plugin/routes/Docs.astro +7 -16
- package/plugin/routes/Overview.astro +7 -5
- 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/stl-docs/components/AIDropdown.tsx +52 -0
- package/stl-docs/components/Head.astro +9 -0
- package/stl-docs/components/PageTitle.astro +67 -0
- package/stl-docs/components/content-panel/ContentPanel.astro +8 -35
- package/stl-docs/components/icons/chat-gpt.tsx +1 -1
- package/stl-docs/index.ts +58 -23
- package/stl-docs/loadStlDocsConfig.ts +17 -2
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +64 -0
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +33 -0
- package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
- package/styles/page.css +31 -4
- package/virtual-module.d.ts +3 -2
- package/plugin/globalJs/ai-dropdown.ts +0 -57
- package/stl-docs/components/APIReferenceAIDropdown.tsx +0 -58
- package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -55
- /package/stl-docs/components/{content-panel/ContentBreadcrumbs.tsx → ContentBreadcrumbs.tsx} +0 -0
package/plugin/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import react from '@astrojs/react';
|
|
2
2
|
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
3
|
-
import type { AstroIntegration } from 'astro';
|
|
3
|
+
import type { AstroIntegration, AstroIntegrationLogger } from 'astro';
|
|
4
4
|
import { config } from 'dotenv';
|
|
5
5
|
import getPort from 'get-port';
|
|
6
6
|
import { startDevServer } from './cms/server';
|
|
@@ -23,11 +23,15 @@ import {
|
|
|
23
23
|
import { buildVirtualModuleString } from '../shared/virtualModule';
|
|
24
24
|
import path from 'path';
|
|
25
25
|
import fs from 'fs';
|
|
26
|
+
import { getSharedLogger } from '../shared/getSharedLogger';
|
|
27
|
+
import { resolveSrcFile } from '../resolveSrcFile';
|
|
26
28
|
|
|
27
29
|
export { generateAPILink } from './generateAPIReferenceLink';
|
|
28
30
|
export type { ReferenceSidebarConfigItem };
|
|
29
31
|
|
|
30
|
-
config(
|
|
32
|
+
config({
|
|
33
|
+
quiet: true,
|
|
34
|
+
});
|
|
31
35
|
|
|
32
36
|
let sidebarIdCounter = 0;
|
|
33
37
|
|
|
@@ -108,6 +112,7 @@ function tmpGetCMSServerConfig(specRetrieverConfig: SpecRetrieverConfig) {
|
|
|
108
112
|
|
|
109
113
|
async function stlStarlightAstroIntegration(
|
|
110
114
|
pluginConfig: NormalizedStainlessStarlightConfig,
|
|
115
|
+
stlStarlightPluginLogger: AstroIntegrationLogger,
|
|
111
116
|
): Promise<AstroIntegration> {
|
|
112
117
|
const virtualId = `virtual:stl-starlight-virtual-module`;
|
|
113
118
|
// The '\0' prefix tells Vite “this is a virtual module” and prevents it from being resolved again.
|
|
@@ -119,9 +124,10 @@ async function stlStarlightAstroIntegration(
|
|
|
119
124
|
|
|
120
125
|
const cmsServer = await startDevServer({
|
|
121
126
|
port: CMS_PORT,
|
|
122
|
-
apiKey,
|
|
127
|
+
apiKey: apiKey.value,
|
|
123
128
|
version,
|
|
124
129
|
devPaths,
|
|
130
|
+
logger: stlStarlightPluginLogger,
|
|
125
131
|
getGeneratedSidebarConfig: (id: number) => {
|
|
126
132
|
const config = sidebarConfigs.get(id);
|
|
127
133
|
if (!config) {
|
|
@@ -134,34 +140,40 @@ async function stlStarlightAstroIntegration(
|
|
|
134
140
|
return {
|
|
135
141
|
name: 'stl-starlight-astro',
|
|
136
142
|
hooks: {
|
|
137
|
-
'astro:config:setup': async ({
|
|
143
|
+
'astro:config:setup': async ({
|
|
144
|
+
injectRoute,
|
|
145
|
+
updateConfig,
|
|
146
|
+
logger: localLogger,
|
|
147
|
+
command,
|
|
148
|
+
config: astroConfig,
|
|
149
|
+
}) => {
|
|
150
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
138
151
|
const projectDir = astroConfig.root.pathname;
|
|
139
152
|
|
|
140
153
|
const middlewareFile = path.join(projectDir, 'middleware.stainless.ts');
|
|
141
154
|
|
|
142
155
|
let vmMiddlewareExport = 'export const MIDDLEWARE = {};';
|
|
143
156
|
if (fs.existsSync(middlewareFile)) {
|
|
144
|
-
logger.
|
|
157
|
+
logger.debug(`Loading middleware from ${middlewareFile}`);
|
|
145
158
|
vmMiddlewareExport = `export { default as MIDDLEWARE } from '${middlewareFile}';`;
|
|
146
159
|
}
|
|
147
160
|
|
|
148
161
|
injectRoute({
|
|
149
|
-
pattern: `${pluginConfig.basePath}/[...slug].md`,
|
|
150
|
-
entrypoint: '
|
|
162
|
+
pattern: `${pluginConfig.basePath}/[...slug]/index.md`,
|
|
163
|
+
entrypoint: resolveSrcFile('/plugin/routes/markdown.ts'),
|
|
151
164
|
prerender: command === 'build',
|
|
152
165
|
});
|
|
153
166
|
|
|
154
|
-
const astroFile = command === 'build' ? '
|
|
167
|
+
const astroFile = command === 'build' ? 'DocsStatic' : 'Docs';
|
|
155
168
|
injectRoute({
|
|
156
169
|
pattern: `${pluginConfig.basePath}/[...slug]`,
|
|
157
|
-
|
|
158
|
-
entrypoint: `@stainless-api/docs/${astroFile}`,
|
|
170
|
+
entrypoint: resolveSrcFile(`/plugin/routes/${astroFile}.astro`),
|
|
159
171
|
prerender: command === 'build',
|
|
160
172
|
});
|
|
161
173
|
|
|
162
174
|
injectRoute({
|
|
163
175
|
pattern: pluginConfig.basePath,
|
|
164
|
-
entrypoint: '
|
|
176
|
+
entrypoint: resolveSrcFile('/plugin/routes/Overview.astro'),
|
|
165
177
|
prerender: command === 'build',
|
|
166
178
|
});
|
|
167
179
|
|
|
@@ -213,7 +225,6 @@ async function stlStarlightAstroIntegration(
|
|
|
213
225
|
EXPERIMENTAL_COLLAPSIBLE_SNIPPETS: pluginConfig.experimentalCollapsibleSnippets,
|
|
214
226
|
PROPERTY_SETTINGS: pluginConfig.propertySettings,
|
|
215
227
|
SEARCH: pluginConfig.search,
|
|
216
|
-
INCLUDE_AI_DROPDOWN_OPTIONS: pluginConfig.includeAIDropdownOptions,
|
|
217
228
|
}),
|
|
218
229
|
vmMiddlewareExport,
|
|
219
230
|
].join('\n');
|
|
@@ -242,15 +253,20 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
242
253
|
command,
|
|
243
254
|
config: starlightConfig,
|
|
244
255
|
astroConfig,
|
|
245
|
-
logger,
|
|
256
|
+
logger: localLogger,
|
|
246
257
|
}) => {
|
|
247
258
|
if (command !== 'build' && command !== 'dev') {
|
|
248
259
|
return;
|
|
249
260
|
}
|
|
250
261
|
|
|
262
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
263
|
+
|
|
251
264
|
const configParseResult = parseStarlightPluginConfig(someUserConfig, command);
|
|
252
265
|
if (configParseResult.result === 'error') {
|
|
253
|
-
|
|
266
|
+
const errorLines = configParseResult.message.split('\n');
|
|
267
|
+
for (const line of errorLines) {
|
|
268
|
+
logger.error(line);
|
|
269
|
+
}
|
|
254
270
|
process.exit(1);
|
|
255
271
|
}
|
|
256
272
|
const config = configParseResult.config;
|
|
@@ -261,17 +277,30 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
261
277
|
addIntegration(react());
|
|
262
278
|
}
|
|
263
279
|
|
|
280
|
+
if ('apiKey' in config.specRetrieverConfig) {
|
|
281
|
+
if (!config.specRetrieverConfig.apiKey) {
|
|
282
|
+
logger.info(`Stainless credentials not loaded`);
|
|
283
|
+
} else if (config.specRetrieverConfig.apiKey.source === 'explicit-config') {
|
|
284
|
+
logger.info(`Stainless credentials loaded from user config`);
|
|
285
|
+
} else if (config.specRetrieverConfig.apiKey.source === 'environment-variable') {
|
|
286
|
+
logger.info('Stainless credentials loaded from `STAINLESS_API_KEY` environment variable');
|
|
287
|
+
} else if (config.specRetrieverConfig.apiKey.source === 'cli') {
|
|
288
|
+
logger.info('Stainless credentials loaded from `stl` CLI');
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
264
292
|
if (
|
|
265
293
|
command === 'build' &&
|
|
266
294
|
config.specRetrieverConfig.kind === 'local_spec_server_with_remote_files'
|
|
267
295
|
) {
|
|
268
296
|
await buildAlgoliaIndex({
|
|
269
297
|
version: config.specRetrieverConfig.version,
|
|
270
|
-
apiKey: config.specRetrieverConfig.apiKey,
|
|
298
|
+
apiKey: config.specRetrieverConfig.apiKey.value,
|
|
299
|
+
logger,
|
|
271
300
|
});
|
|
272
301
|
}
|
|
273
302
|
|
|
274
|
-
addIntegration(await stlStarlightAstroIntegration(config));
|
|
303
|
+
addIntegration(await stlStarlightAstroIntegration(config, logger));
|
|
275
304
|
|
|
276
305
|
if (starlightConfig.sidebar) {
|
|
277
306
|
// for pagination (https://starlight.astro.build/reference/configuration/#pagination) to work correctly
|
|
@@ -296,7 +325,7 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
296
325
|
});
|
|
297
326
|
|
|
298
327
|
addRouteMiddleware({
|
|
299
|
-
entrypoint: '
|
|
328
|
+
entrypoint: resolveSrcFile('/plugin/replaceSidebarPlaceholderMiddleware.ts'),
|
|
300
329
|
order: 'post',
|
|
301
330
|
});
|
|
302
331
|
},
|
|
@@ -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,16 +124,10 @@ 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
|
-
|
|
121
|
-
/**
|
|
122
|
-
* When set to `true`, a dropdown button will be included on all pages to allow users to
|
|
123
|
-
* view or send markdown to an LLM.
|
|
124
|
-
* Defaults to `false`.
|
|
125
|
-
*/
|
|
126
|
-
includeAIDropdownOptions?: boolean;
|
|
127
131
|
};
|
|
128
132
|
|
|
129
133
|
export type ExternalSpecServerUserConfig = Omit<StainlessStarlightUserConfig, 'stainlessProject'> & {
|
|
@@ -140,15 +144,29 @@ function getLocalFilePaths(command: AstroCommand): InputFilePaths | null {
|
|
|
140
144
|
if (command !== 'dev') {
|
|
141
145
|
return null;
|
|
142
146
|
}
|
|
143
|
-
|
|
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) {
|
|
144
154
|
return null;
|
|
145
155
|
}
|
|
156
|
+
|
|
146
157
|
return {
|
|
147
|
-
oasPath: resolvePath(
|
|
148
|
-
configPath: resolvePath(
|
|
158
|
+
oasPath: resolvePath(oasPath),
|
|
159
|
+
configPath: resolvePath(configPath),
|
|
149
160
|
};
|
|
150
161
|
}
|
|
151
162
|
|
|
163
|
+
export type ApiKeySource = 'explicit-config' | 'environment-variable' | 'cli';
|
|
164
|
+
|
|
165
|
+
export type LoadedApiKey = {
|
|
166
|
+
value: string;
|
|
167
|
+
source: ApiKeySource;
|
|
168
|
+
};
|
|
169
|
+
|
|
152
170
|
export type SpecRetrieverConfig =
|
|
153
171
|
| {
|
|
154
172
|
kind: 'external_spec_server';
|
|
@@ -159,16 +177,63 @@ export type SpecRetrieverConfig =
|
|
|
159
177
|
kind: 'local_spec_server_with_files';
|
|
160
178
|
stainlessProject: string;
|
|
161
179
|
devPaths: InputFilePaths;
|
|
162
|
-
apiKey:
|
|
180
|
+
apiKey: LoadedApiKey | null;
|
|
163
181
|
version: VersionUserConfig;
|
|
164
182
|
}
|
|
165
183
|
| {
|
|
166
184
|
kind: 'local_spec_server_with_remote_files';
|
|
167
185
|
stainlessProject: string;
|
|
168
|
-
apiKey:
|
|
186
|
+
apiKey: LoadedApiKey;
|
|
169
187
|
version: VersionUserConfig;
|
|
170
188
|
};
|
|
171
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
|
+
|
|
172
237
|
function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: AstroCommand) {
|
|
173
238
|
const configWithDefaults = {
|
|
174
239
|
basePath: partial.basePath ?? '/api',
|
|
@@ -197,7 +262,6 @@ function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: Ast
|
|
|
197
262
|
search: {
|
|
198
263
|
enableAISearch: partial.search?.enableAISearch ?? false,
|
|
199
264
|
},
|
|
200
|
-
includeAIDropdownOptions: partial.includeAIDropdownOptions ?? false,
|
|
201
265
|
};
|
|
202
266
|
|
|
203
267
|
function getSpecRetrieverConfig(): SpecRetrieverConfig {
|
|
@@ -213,7 +277,7 @@ function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: Ast
|
|
|
213
277
|
throw new Error('You must provide a stainlessProject when using Stainless Starlight');
|
|
214
278
|
}
|
|
215
279
|
|
|
216
|
-
const apiKey = partial.apiKey
|
|
280
|
+
const apiKey = loadApiKey(partial.apiKey);
|
|
217
281
|
|
|
218
282
|
const version = {
|
|
219
283
|
stainlessProject: partial.stainlessProject,
|
|
@@ -234,7 +298,12 @@ function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: Ast
|
|
|
234
298
|
|
|
235
299
|
if (!apiKey) {
|
|
236
300
|
throw new Error(
|
|
237
|
-
|
|
301
|
+
[
|
|
302
|
+
bold('No Stainless credentials found. Please choose one of the following options to authenticate with Stainless:'),
|
|
303
|
+
'- Run `stl auth login` to authenticate via the Stainless CLI',
|
|
304
|
+
'- Provide a Stainless API key via the `STAINLESS_API_KEY` environment variable (eg. in a .env file)',
|
|
305
|
+
'- Set the `apiKey` option in the Stainless Docs config',
|
|
306
|
+
].join('\n'),
|
|
238
307
|
);
|
|
239
308
|
}
|
|
240
309
|
|
package/plugin/react/Routing.tsx
CHANGED
|
@@ -48,15 +48,15 @@ import {
|
|
|
48
48
|
HIGHLIGHT_THEMES,
|
|
49
49
|
BREADCRUMB_CONFIG,
|
|
50
50
|
PROPERTY_SETTINGS,
|
|
51
|
-
INCLUDE_AI_DROPDOWN_OPTIONS,
|
|
52
51
|
} from 'virtual:stl-starlight-virtual-module';
|
|
52
|
+
// TODO (eventually): this file should really probably only be importing from the starlight virtual module
|
|
53
|
+
import { ENABLE_CONTEXT_MENU } from 'virtual:stl-docs-virtual-module';
|
|
53
54
|
import style from '@stainless-api/docs-ui/src/style';
|
|
54
55
|
import { createHighlighter, type BundledLanguage, type BundledTheme, type HighlighterGeneric } from 'shiki';
|
|
55
56
|
import { SnippetCode, SnippetContainer, SnippetRequestContainer } from '../components/SnippetCode';
|
|
56
|
-
import clsx from 'clsx';
|
|
57
57
|
import type { StlStarlightMiddleware } from '../middlewareBuilder/stainlessMiddleware';
|
|
58
58
|
import { ComponentProvider } from '@stainless-api/docs-ui/src/contexts/component';
|
|
59
|
-
import {
|
|
59
|
+
import { AIDropdown } from '../../stl-docs/components/AIDropdown';
|
|
60
60
|
|
|
61
61
|
export function generateDocsRoutes(spec: SDKJSON.Spec) {
|
|
62
62
|
const paths = generateRouteList({
|
|
@@ -121,7 +121,6 @@ export function buildSidebar(
|
|
|
121
121
|
|
|
122
122
|
const meths: SidebarEntry[] = Object.values(resource.methods ?? [])
|
|
123
123
|
.filter((method) => spec.decls?.[language]?.[method.stainlessPath])
|
|
124
|
-
.toSorted((first, second) => first.name.localeCompare(second.name))
|
|
125
124
|
.map((method) => ({
|
|
126
125
|
type: 'link',
|
|
127
126
|
isCurrent: current === method.stainlessPath,
|
|
@@ -324,7 +323,7 @@ export function RenderSpec({
|
|
|
324
323
|
>
|
|
325
324
|
<NavigationProvider basePath={BASE_PATH} selectedPath={path}>
|
|
326
325
|
<MarkdownProvider render={renderMarkdown} highlight={highlight}>
|
|
327
|
-
{
|
|
326
|
+
{
|
|
328
327
|
<div className="stldocs-root stl-ui-not-prose">
|
|
329
328
|
<div className="stl-page-nav-container">
|
|
330
329
|
<SDKBreadcrumbs
|
|
@@ -333,27 +332,18 @@ export function RenderSpec({
|
|
|
333
332
|
basePath={BASE_PATH}
|
|
334
333
|
config={BREADCRUMB_CONFIG}
|
|
335
334
|
/>
|
|
336
|
-
{
|
|
335
|
+
{ENABLE_CONTEXT_MENU && <AIDropdown />}
|
|
337
336
|
</div>
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
</div>
|
|
343
|
-
) : (
|
|
344
|
-
<div className="stldocs-root stl-ui-not-prose">
|
|
345
|
-
<div className="stl-page-nav-container">
|
|
346
|
-
<SDKBreadcrumbs
|
|
347
|
-
spec={spec as SDKJSON.Spec}
|
|
348
|
-
currentPath={currentPath}
|
|
349
|
-
basePath={BASE_PATH}
|
|
350
|
-
config={BREADCRUMB_CONFIG}
|
|
337
|
+
{kind === 'http_method' ? (
|
|
338
|
+
<SDKMethod
|
|
339
|
+
method={resource.methods[parsed.method]}
|
|
340
|
+
transformRequestSnippet={transformRequestSnippet}
|
|
351
341
|
/>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
342
|
+
) : (
|
|
343
|
+
<SDKOverview resource={resource} />
|
|
344
|
+
)}
|
|
355
345
|
</div>
|
|
356
|
-
|
|
346
|
+
}
|
|
357
347
|
</MarkdownProvider>
|
|
358
348
|
</NavigationProvider>
|
|
359
349
|
</ComponentProvider>
|
package/plugin/routes/Docs.astro
CHANGED
|
@@ -21,6 +21,12 @@ if (!route) {
|
|
|
21
21
|
throw new Error("No such route");
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
// PageTitle override will skip rendering the default Starlight title
|
|
25
|
+
// @ts-expect-error - _stlStarlightPage isn't typed yet
|
|
26
|
+
Astro.locals._stlStarlightPage = {
|
|
27
|
+
skipRenderingStarlightTitle: route.props.kind === 'readme' ? false : true,
|
|
28
|
+
}
|
|
29
|
+
|
|
24
30
|
const readmeContent = await getReadmeContent(spec, route.props.language);
|
|
25
31
|
const readme =
|
|
26
32
|
route.props.kind === "readme"
|
|
@@ -69,11 +75,6 @@ if (readme) {
|
|
|
69
75
|
tableOfContents: ["resource", "readme"].includes(props.kind)
|
|
70
76
|
? { maxHeadingLevel: 6 }
|
|
71
77
|
: false,
|
|
72
|
-
// @ts-ignore
|
|
73
|
-
stainlessStarlight: {
|
|
74
|
-
basePath: BASE_PATH,
|
|
75
|
-
...props,
|
|
76
|
-
},
|
|
77
78
|
}}
|
|
78
79
|
>
|
|
79
80
|
{
|
|
@@ -107,17 +108,7 @@ if (readme) {
|
|
|
107
108
|
[data-has-sidebar]:not([data-has-toc]) .sl-container {
|
|
108
109
|
max-width: 1428px;
|
|
109
110
|
}
|
|
110
|
-
|
|
111
|
-
.content-panel:nth-of-type(1) {
|
|
112
|
-
display: none;
|
|
113
|
-
}
|
|
114
|
-
.content-panel:nth-of-type(2) .stl-page-nav-container {
|
|
115
|
-
display: none;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.content-panel:nth-of-type(2) .stldocs-root .stl-page-nav-container {
|
|
119
|
-
display: flex;
|
|
120
|
-
}
|
|
111
|
+
|
|
121
112
|
</style>
|
|
122
113
|
</div>
|
|
123
114
|
) : (
|
|
@@ -1,6 +1,6 @@
|
|
|
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
6
|
import { RenderLibraries, RenderSpecOverview, type SpecMetadata } from '../react/Routing';
|
|
@@ -12,6 +12,12 @@ const metadata = languages
|
|
|
12
12
|
.filter((language) => !['http', 'terraform'].includes(language) && spec.metadata[language])
|
|
13
13
|
.filter((language) => !EXCLUDE_LANGUAGES.includes(language))
|
|
14
14
|
.map((language) => [language, spec.metadata[language]]) as SpecMetadata;
|
|
15
|
+
|
|
16
|
+
// PageTitle override will skip rendering the default Starlight title
|
|
17
|
+
// @ts-expect-error - _stlStarlightPage isn't typed yet
|
|
18
|
+
Astro.locals._stlStarlightPage = {
|
|
19
|
+
hasMarkdownRoute: false,
|
|
20
|
+
};
|
|
15
21
|
---
|
|
16
22
|
|
|
17
23
|
<StarlightPage
|
|
@@ -19,10 +25,6 @@ const metadata = languages
|
|
|
19
25
|
title: 'API Reference',
|
|
20
26
|
pagefind: false,
|
|
21
27
|
tableOfContents: false,
|
|
22
|
-
stainlessStarlight: {
|
|
23
|
-
basePath: BASE_PATH,
|
|
24
|
-
language: 'http',
|
|
25
|
-
},
|
|
26
28
|
}}
|
|
27
29
|
>
|
|
28
30
|
<h3>Libraries</h3>
|