@stainless-api/docs 0.1.0-beta.125 → 0.1.0-beta.127
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 +22 -0
- package/package.json +9 -10
- package/plugin/components/RequestBuilder/index.tsx +1 -1
- package/plugin/globalJs/copy.ts +1 -1
- package/plugin/globalJs/navigation.ts +10 -12
- package/plugin/index.ts +16 -6
- package/plugin/markdown/highlighter.ts +100 -0
- package/plugin/markdown/index.ts +39 -0
- package/plugin/react/Routing.tsx +7 -159
- package/plugin/routes/Docs.astro +2 -1
- package/plugin/vendor/preview.worker.docs.js +7078 -6453
- package/shared/getProsePages.test.ts +130 -0
- package/shared/getProsePages.ts +22 -16
- package/stl-docs/index.ts +3 -3
- package/stl-docs/proseDocSync.ts +2 -5
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +2 -6
- package/stl-docs/proseSearchIndexing.ts +2 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @stainless-api/docs
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.127
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e0d595f: Fix snippet copy button click handler
|
|
8
|
+
- 8752b4e: Fix getProsePages treating all pages as prose when API reference basePath is ""
|
|
9
|
+
- Updated dependencies [871f3c0]
|
|
10
|
+
- Updated dependencies [871f3c0]
|
|
11
|
+
- @stainless-api/docs-ui@0.1.0-beta.91
|
|
12
|
+
- @stainless-api/docs-search@0.1.0-beta.44
|
|
13
|
+
|
|
14
|
+
## 0.1.0-beta.126
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 992a07a: Update vendored preview worker
|
|
19
|
+
- 1d1fa35: Use astro remark instead of `marked` to process api reference markdown
|
|
20
|
+
- Updated dependencies [374c0e4]
|
|
21
|
+
- @stainless-api/ui-primitives@0.1.0-beta.51
|
|
22
|
+
- @stainless-api/docs-ui@0.1.0-beta.90
|
|
23
|
+
- @stainless-api/docs-search@0.1.0-beta.43
|
|
24
|
+
|
|
3
25
|
## 0.1.0-beta.125
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stainless-api/docs",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.127",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
"vite": ">=7.3.1"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@astrojs/markdown-remark": "^7.0
|
|
45
|
-
"@astrojs/react": "^5.0.
|
|
44
|
+
"@astrojs/markdown-remark": "^7.1.0",
|
|
45
|
+
"@astrojs/react": "^5.0.2",
|
|
46
|
+
"@markdoc/markdoc": "^0.5.7",
|
|
46
47
|
"@stainless-api/sdk": "0.5.0",
|
|
47
48
|
"astro-expressive-code": "^0.41.7",
|
|
48
49
|
"cheerio": "^1.2.0",
|
|
49
50
|
"clsx": "^2.1.1",
|
|
50
|
-
"dotenv": "17.
|
|
51
|
+
"dotenv": "17.4.0",
|
|
51
52
|
"lucide-react": "^0.577.0",
|
|
52
|
-
"marked": "^17.0.5",
|
|
53
53
|
"node-html-parser": "^7.1.0",
|
|
54
54
|
"rehype-parse": "^9.0.1",
|
|
55
55
|
"rehype-remark": "^10.0.1",
|
|
@@ -61,20 +61,19 @@
|
|
|
61
61
|
"vite-plugin-prebundle-workers": "^0.2.0",
|
|
62
62
|
"web-worker": "^1.5.0",
|
|
63
63
|
"yaml": "^2.8.3",
|
|
64
|
-
"@stainless-api/docs-search": "0.1.0-beta.
|
|
65
|
-
"@stainless-api/docs-ui": "0.1.0-beta.
|
|
66
|
-
"@stainless-api/ui-primitives": "0.1.0-beta.
|
|
64
|
+
"@stainless-api/docs-search": "0.1.0-beta.44",
|
|
65
|
+
"@stainless-api/docs-ui": "0.1.0-beta.91",
|
|
66
|
+
"@stainless-api/ui-primitives": "0.1.0-beta.51"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@astrojs/check": "^0.9.8",
|
|
70
|
-
"@markdoc/markdoc": "^0.5.6",
|
|
71
70
|
"@types/node": "24.12.0",
|
|
72
71
|
"@types/react": "19.2.14",
|
|
73
72
|
"@types/react-dom": "^19.2.3",
|
|
74
73
|
"react": "^19.2.4",
|
|
75
74
|
"react-dom": "^19.2.4",
|
|
76
75
|
"tsx": "^4.21.0",
|
|
77
|
-
"typescript": "
|
|
76
|
+
"typescript": "6.0.2",
|
|
78
77
|
"vite": "^7.3.1",
|
|
79
78
|
"vitest": "^4.1.2",
|
|
80
79
|
"zod": "^4.3.6",
|
|
@@ -22,7 +22,7 @@ export function RequestBuilder({
|
|
|
22
22
|
if (!spec) throw new Error('Spec is required for RequestBuilder');
|
|
23
23
|
params = spec && extractParams(spec, method);
|
|
24
24
|
} catch (e) {
|
|
25
|
-
console.warn(e);
|
|
25
|
+
console.warn(e);
|
|
26
26
|
return <div className={className}>{children}</div>;
|
|
27
27
|
}
|
|
28
28
|
/* eslint-enable */
|
package/plugin/globalJs/copy.ts
CHANGED
|
@@ -33,7 +33,7 @@ const preloadPlayground = (event: Event) => {
|
|
|
33
33
|
};
|
|
34
34
|
addEventListener('mouseover', preloadPlayground);
|
|
35
35
|
addEventListener('click', (event) => {
|
|
36
|
-
if (!(event.target instanceof
|
|
36
|
+
if (!(event.target instanceof Element)) return;
|
|
37
37
|
const copyButton = event.target.closest('[data-stldocs-snippet-copy]');
|
|
38
38
|
if (!(copyButton instanceof HTMLElement)) return;
|
|
39
39
|
|
|
@@ -39,24 +39,22 @@ document.addEventListener(getPageLoadEvent(), () => {
|
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
document.addEventListener('click', (event) => {
|
|
42
|
-
const toggle =
|
|
43
|
-
'[data-stldocs-property-toggle-expanded]
|
|
44
|
-
)
|
|
42
|
+
const toggle =
|
|
43
|
+
event.target instanceof HTMLElement && event.target.closest('[data-stldocs-property-toggle-expanded]');
|
|
44
|
+
if (!toggle || !(toggle instanceof HTMLElement)) return;
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
toggle.dataset.stldocsPropertyToggleExpanded = state ? 'false' : 'true';
|
|
46
|
+
// Toggle the “expanded” state of the toggle
|
|
47
|
+
const toggleIsExpanded = toggle.dataset.stldocsPropertyToggleExpanded === 'true';
|
|
48
|
+
toggle.dataset.stldocsPropertyToggleExpanded = (!toggleIsExpanded).toString();
|
|
50
49
|
|
|
50
|
+
// Find the described “property group”
|
|
51
51
|
const targetGroup = toggle.dataset.stldocsPropertyToggleTarget;
|
|
52
52
|
if (!targetGroup) return;
|
|
53
|
-
|
|
54
53
|
const target = document.querySelector(`[data-stldocs-property-group=${targetGroup}]`);
|
|
55
54
|
if (!target) return;
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
el.open = initial === 'true' ? true : !state;
|
|
56
|
+
// Expand or collapse all <details> elements within the target group
|
|
57
|
+
[...target.getElementsByTagName('details')].forEach((el) => {
|
|
58
|
+
el.open = el.dataset.stldocsExpanderInitialState === 'true' ? true : !toggleIsExpanded;
|
|
61
59
|
});
|
|
62
60
|
});
|
package/plugin/index.ts
CHANGED
|
@@ -30,7 +30,7 @@ import prebundleWorkers from 'vite-plugin-prebundle-workers';
|
|
|
30
30
|
import { SpecLoader, startSpecLoader } from './specs';
|
|
31
31
|
|
|
32
32
|
import type * as ReferenceSidebarsVirtualModule from 'virtual:stl-starlight-reference-sidebars';
|
|
33
|
-
import { generateMissingRouteList } from '@stainless-api/docs-ui/routing';
|
|
33
|
+
import { generateMissingRouteList, generateRouteList } from '@stainless-api/docs-ui/routing';
|
|
34
34
|
import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
35
35
|
|
|
36
36
|
export { generateAPILink } from './generateAPIReferenceLink';
|
|
@@ -357,13 +357,26 @@ function stlStarlightAstroIntegration(pluginConfig: NormalizedStainlessStarlight
|
|
|
357
357
|
collectedErrors = null;
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
+
const specComposite = await resolveSpecs();
|
|
361
|
+
|
|
362
|
+
// TODO: (multi-spec) support multiple specs
|
|
363
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
364
|
+
|
|
365
|
+
const basePrefixInOutput = path.posix.join(astroBase, pluginConfig.basePath).replace(/^\/+/, '');
|
|
366
|
+
const routeList = generateRouteList({ spec });
|
|
367
|
+
const apiReferencePages = [
|
|
368
|
+
// overview page
|
|
369
|
+
path.posix.join(basePrefixInOutput, 'index.html'),
|
|
370
|
+
// all route pages
|
|
371
|
+
...routeList.map((r) => path.posix.join(basePrefixInOutput, r.slug, 'index.html')),
|
|
372
|
+
];
|
|
373
|
+
|
|
360
374
|
const manifest = {
|
|
361
375
|
astroBase,
|
|
376
|
+
apiReferencePages,
|
|
362
377
|
};
|
|
363
378
|
await writeFile(path.join(stainlessDir, 'stl-manifest.json'), JSON.stringify(manifest, null, 2));
|
|
364
379
|
|
|
365
|
-
const specComposite = await resolveSpecs();
|
|
366
|
-
|
|
367
380
|
await buildAlgoliaIndex({
|
|
368
381
|
specComposite,
|
|
369
382
|
logger,
|
|
@@ -375,9 +388,6 @@ function stlStarlightAstroIntegration(pluginConfig: NormalizedStainlessStarlight
|
|
|
375
388
|
// in this file so Cloudflare can serve them with a 404 status. These pages display helpful information
|
|
376
389
|
// about the missing method and provide links to SDKs where it is available.
|
|
377
390
|
|
|
378
|
-
// TODO: (multi-spec) support multiple specs
|
|
379
|
-
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
380
|
-
|
|
381
391
|
const missingRoutes = generateMissingRouteList({
|
|
382
392
|
spec,
|
|
383
393
|
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createHighlighter,
|
|
3
|
+
type HighlighterGeneric,
|
|
4
|
+
type ThemeInput,
|
|
5
|
+
type BundledTheme,
|
|
6
|
+
type BundledLanguage,
|
|
7
|
+
} from 'shiki';
|
|
8
|
+
import { HIGHLIGHT_THEMES } from 'virtual:stl-starlight-virtual-module';
|
|
9
|
+
import { SupportedLanguageSyntaxes } from '@stainless-api/docs-ui/routing';
|
|
10
|
+
import type { CreateShikiHighlighterOptions } from '@astrojs/markdown-remark';
|
|
11
|
+
|
|
12
|
+
const STAINLESS_DOCS_JSON_THEME = {
|
|
13
|
+
name: 'stainless-docs-json',
|
|
14
|
+
colors: {
|
|
15
|
+
'editor.background': 'var(--stl-color-background)',
|
|
16
|
+
'editor.foreground': 'var(--stl-color-foreground)',
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
tokenColors: [
|
|
20
|
+
{
|
|
21
|
+
scope: ['comment', 'punctuation.definition.comment'],
|
|
22
|
+
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
23
|
+
},
|
|
24
|
+
// numbers, booleans, null
|
|
25
|
+
{
|
|
26
|
+
scope: ['constant.numeric', 'constant.language'],
|
|
27
|
+
settings: { foreground: 'var(--stl-color-orange-foreground)' },
|
|
28
|
+
},
|
|
29
|
+
// strings
|
|
30
|
+
{
|
|
31
|
+
scope: ['string', 'string.quoted', 'string.template'],
|
|
32
|
+
settings: { foreground: 'var(--stl-color-green-foreground)' },
|
|
33
|
+
},
|
|
34
|
+
// Keys, brackets
|
|
35
|
+
{
|
|
36
|
+
scope: ['support.type', 'meta'],
|
|
37
|
+
settings: { foreground: 'var(--stl-color-foreground)' },
|
|
38
|
+
},
|
|
39
|
+
// brackets
|
|
40
|
+
{
|
|
41
|
+
scope: ['meta'],
|
|
42
|
+
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
43
|
+
},
|
|
44
|
+
// built-in types
|
|
45
|
+
{
|
|
46
|
+
scope: ['support.type.builtin'],
|
|
47
|
+
settings: { foreground: 'var(--stl-color-purple-foreground)' },
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
} satisfies ThemeInput;
|
|
51
|
+
|
|
52
|
+
// singleton
|
|
53
|
+
let astroShikiHighlighter:
|
|
54
|
+
| HighlighterGeneric<BundledLanguage, BundledTheme>
|
|
55
|
+
| Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>
|
|
56
|
+
| null = null;
|
|
57
|
+
export async function getAstroHighlighter() {
|
|
58
|
+
if (astroShikiHighlighter) {
|
|
59
|
+
return astroShikiHighlighter;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
astroShikiHighlighter = createHighlighter({
|
|
63
|
+
themes: [
|
|
64
|
+
HIGHLIGHT_THEMES?.dark ?? 'github-dark',
|
|
65
|
+
HIGHLIGHT_THEMES?.light ?? 'github-light',
|
|
66
|
+
STAINLESS_DOCS_JSON_THEME,
|
|
67
|
+
],
|
|
68
|
+
langs: SupportedLanguageSyntaxes,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return astroShikiHighlighter;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function runHighlight({
|
|
75
|
+
highlighter,
|
|
76
|
+
content,
|
|
77
|
+
language,
|
|
78
|
+
themes,
|
|
79
|
+
}: {
|
|
80
|
+
highlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
|
|
81
|
+
content: string;
|
|
82
|
+
language?: string;
|
|
83
|
+
themes?: CreateShikiHighlighterOptions['themes'] | Record<string, 'stainless-docs-json'>;
|
|
84
|
+
}) {
|
|
85
|
+
return highlighter.codeToHtml(content, {
|
|
86
|
+
lang: language ?? 'javascript',
|
|
87
|
+
themes:
|
|
88
|
+
// Default to user-provided themes except in case of json
|
|
89
|
+
themes ??
|
|
90
|
+
(language === 'JSON'
|
|
91
|
+
? { light: 'stainless-docs-json', dark: 'stainless-docs-json' }
|
|
92
|
+
: HIGHLIGHT_THEMES) ??
|
|
93
|
+
{},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function highlight(content: string, language?: string) {
|
|
98
|
+
const highlighter = await getAstroHighlighter();
|
|
99
|
+
return runHighlight({ highlighter, content, language });
|
|
100
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createMarkdownProcessor, type MarkdownProcessor } from '@astrojs/markdown-remark';
|
|
2
|
+
import remarkGfmAlerts from 'remark-github-alerts';
|
|
3
|
+
import { HIGHLIGHT_THEMES } from 'virtual:stl-starlight-virtual-module';
|
|
4
|
+
|
|
5
|
+
// singleton
|
|
6
|
+
let astroMarkdownProcessor: MarkdownProcessor;
|
|
7
|
+
async function getAstroMarkdown() {
|
|
8
|
+
if (!astroMarkdownProcessor) {
|
|
9
|
+
astroMarkdownProcessor = await createMarkdownProcessor({
|
|
10
|
+
gfm: true,
|
|
11
|
+
remarkPlugins: [remarkGfmAlerts],
|
|
12
|
+
shikiConfig: { themes: HIGHLIGHT_THEMES },
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return astroMarkdownProcessor;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function astroMarkdownRender(content: string) {
|
|
20
|
+
const md = await getAstroMarkdown();
|
|
21
|
+
const output = await md.render(content);
|
|
22
|
+
|
|
23
|
+
// Map GFM callouts to the closest Starlight equivalent
|
|
24
|
+
// TODO: this sucks; we should be rendering via ui-primitives callouts instead of ugly theme-incompatible starlight ones
|
|
25
|
+
output.code = output.code
|
|
26
|
+
.replaceAll('markdown-alert-caution', 'markdown-alert-danger')
|
|
27
|
+
.replaceAll('markdown-alert-warning', 'markdown-alert-caution')
|
|
28
|
+
.replaceAll('markdown-alert-important', 'markdown-alert-caution')
|
|
29
|
+
.replaceAll('markdown-alert-title', 'starlight-aside__title')
|
|
30
|
+
.replaceAll('markdown-alert-', 'starlight-aside--')
|
|
31
|
+
.replaceAll('markdown-alert', 'starlight-aside');
|
|
32
|
+
|
|
33
|
+
return output;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function astroMarkdownRenderText(content: string) {
|
|
37
|
+
const result = await astroMarkdownRender(content);
|
|
38
|
+
return result.code;
|
|
39
|
+
}
|
package/plugin/react/Routing.tsx
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { marked, Tokens } from 'marked';
|
|
3
2
|
import { getDocsLanguages } from '../helpers/multiSpec';
|
|
4
3
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
CreateShikiHighlighterOptions,
|
|
8
|
-
type MarkdownProcessor,
|
|
9
|
-
} from '@astrojs/markdown-remark';
|
|
10
|
-
import remarkGfmAlerts from 'remark-github-alerts';
|
|
4
|
+
import { astroMarkdownRenderText } from '../markdown';
|
|
5
|
+
import { highlight } from '../markdown/highlighter';
|
|
11
6
|
|
|
12
7
|
import type { MarkdownHeading } from 'astro';
|
|
13
8
|
import type { StarlightRouteData } from '@astrojs/starlight/route-data';
|
|
14
9
|
import type * as SDKJSON from '@stainless/sdk-json';
|
|
15
|
-
import { LanguageNames,
|
|
10
|
+
import { LanguageNames, type DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
16
11
|
|
|
17
12
|
import {
|
|
18
13
|
generateRoute,
|
|
@@ -46,7 +41,6 @@ import { Dropdown } from '@stainless-api/docs/components';
|
|
|
46
41
|
import {
|
|
47
42
|
RESOLVED_API_REFERENCE_PATH,
|
|
48
43
|
EXPAND_RESOURCES,
|
|
49
|
-
HIGHLIGHT_THEMES,
|
|
50
44
|
BREADCRUMB_CONFIG,
|
|
51
45
|
PROPERTY_SETTINGS,
|
|
52
46
|
ENABLE_CONTEXT_MENU,
|
|
@@ -54,7 +48,6 @@ import {
|
|
|
54
48
|
MIDDLEWARE,
|
|
55
49
|
} from 'virtual:stl-starlight-virtual-module';
|
|
56
50
|
import style from '@stainless-api/docs-ui/style';
|
|
57
|
-
import { BundledTheme, createHighlighter, HighlighterGeneric, type BundledLanguage } from 'shiki';
|
|
58
51
|
import {
|
|
59
52
|
SnippetCode,
|
|
60
53
|
SnippetContainer,
|
|
@@ -138,58 +131,6 @@ export function buildPageNavigation(resource: SDKJSON.Resource, depth: number =
|
|
|
138
131
|
return [...output, ...subs];
|
|
139
132
|
}
|
|
140
133
|
|
|
141
|
-
async function renderMarkdown(content: string) {
|
|
142
|
-
const highlighter = await astroHighlight();
|
|
143
|
-
|
|
144
|
-
const renderer = {
|
|
145
|
-
code({ text, lang }: Tokens.Code) {
|
|
146
|
-
return shikiHighlight({
|
|
147
|
-
highlighter,
|
|
148
|
-
content: text,
|
|
149
|
-
language: lang,
|
|
150
|
-
});
|
|
151
|
-
},
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
marked.use({ renderer });
|
|
155
|
-
return marked.parse(content, {
|
|
156
|
-
gfm: true,
|
|
157
|
-
}) as string;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function shikiHighlight({
|
|
161
|
-
highlighter,
|
|
162
|
-
content,
|
|
163
|
-
language,
|
|
164
|
-
themes,
|
|
165
|
-
}: {
|
|
166
|
-
highlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
|
|
167
|
-
content: string;
|
|
168
|
-
language?: string;
|
|
169
|
-
themes?: CreateShikiHighlighterOptions['themes'] | Record<string, 'stainless-docs-json'>;
|
|
170
|
-
}) {
|
|
171
|
-
let _themes = themes;
|
|
172
|
-
if (!themes && language === 'json') {
|
|
173
|
-
_themes = {
|
|
174
|
-
light: 'stainless-docs-json',
|
|
175
|
-
dark: 'stainless-docs-json',
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (!_themes) {
|
|
180
|
-
_themes = HIGHLIGHT_THEMES;
|
|
181
|
-
}
|
|
182
|
-
return highlighter.codeToHtml(content, {
|
|
183
|
-
lang: language ?? 'javascript',
|
|
184
|
-
themes: _themes || {},
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async function highlight(content: string, language?: string) {
|
|
189
|
-
const highlighter = await astroHighlight();
|
|
190
|
-
return shikiHighlight({ highlighter, content, language });
|
|
191
|
-
}
|
|
192
|
-
|
|
193
134
|
export function SDKSelectReactComponent({
|
|
194
135
|
selected,
|
|
195
136
|
languages,
|
|
@@ -295,7 +236,7 @@ export function RenderSpecOverview({ spec, language }: { spec: SDKJSON.Spec; lan
|
|
|
295
236
|
<DocsProvider spec={spec} language={language ?? 'node'}>
|
|
296
237
|
<ComponentProvider components={componentOverrides}>
|
|
297
238
|
<NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH}>
|
|
298
|
-
<MarkdownProvider render={
|
|
239
|
+
<MarkdownProvider render={astroMarkdownRenderText} highlight={highlight}>
|
|
299
240
|
<div className={style.Overview}>
|
|
300
241
|
{resources
|
|
301
242
|
.filter(({ resource }) => !resource.name.startsWith('$'))
|
|
@@ -336,7 +277,7 @@ export function RenderSpec({
|
|
|
336
277
|
const resource = getResourceFromSpec(path, spec);
|
|
337
278
|
|
|
338
279
|
if (!resource || !parsed) {
|
|
339
|
-
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
280
|
+
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
340
281
|
return null;
|
|
341
282
|
}
|
|
342
283
|
|
|
@@ -351,7 +292,7 @@ export function RenderSpec({
|
|
|
351
292
|
>
|
|
352
293
|
<ComponentProvider components={componentOverrides}>
|
|
353
294
|
<NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH} selectedPath={path}>
|
|
354
|
-
<MarkdownProvider render={
|
|
295
|
+
<MarkdownProvider render={astroMarkdownRenderText} highlight={highlight}>
|
|
355
296
|
{
|
|
356
297
|
<div className="stldocs-root stl-ui-not-prose">
|
|
357
298
|
<div className="stl-page-nav-container">
|
|
@@ -388,7 +329,7 @@ export function RenderMethod({ path }: { path: string }) {
|
|
|
388
329
|
const resource = getResourceFromSpec(path, spec);
|
|
389
330
|
|
|
390
331
|
if (!resource || !parsed) {
|
|
391
|
-
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
332
|
+
console.warn(`Could not find resource or parsed path for '${path}'`);
|
|
392
333
|
return null;
|
|
393
334
|
}
|
|
394
335
|
|
|
@@ -412,96 +353,3 @@ export async function getReadmeContent(spec: SDKJSON.Spec, language: DocsLanguag
|
|
|
412
353
|
|
|
413
354
|
return spec.readme[language];
|
|
414
355
|
}
|
|
415
|
-
|
|
416
|
-
let astroShikiHighlighter:
|
|
417
|
-
| HighlighterGeneric<BundledLanguage, BundledTheme>
|
|
418
|
-
| Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>
|
|
419
|
-
| null = null;
|
|
420
|
-
|
|
421
|
-
async function astroHighlight() {
|
|
422
|
-
if (astroShikiHighlighter) {
|
|
423
|
-
return astroShikiHighlighter;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
astroShikiHighlighter = createHighlighter({
|
|
427
|
-
themes: [
|
|
428
|
-
HIGHLIGHT_THEMES?.dark ?? 'github-dark',
|
|
429
|
-
HIGHLIGHT_THEMES?.light ?? 'github-light',
|
|
430
|
-
{
|
|
431
|
-
name: 'stainless-docs-json',
|
|
432
|
-
colors: {
|
|
433
|
-
'editor.background': 'var(--stl-color-background)',
|
|
434
|
-
'editor.foreground': 'var(--stl-color-foreground)',
|
|
435
|
-
},
|
|
436
|
-
|
|
437
|
-
tokenColors: [
|
|
438
|
-
{
|
|
439
|
-
scope: ['comment', 'punctuation.definition.comment'],
|
|
440
|
-
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
441
|
-
},
|
|
442
|
-
// numbers, booleans, null
|
|
443
|
-
{
|
|
444
|
-
scope: ['constant.numeric', 'constant.language'],
|
|
445
|
-
settings: { foreground: 'var(--stl-color-orange-foreground)' },
|
|
446
|
-
},
|
|
447
|
-
// strings
|
|
448
|
-
{
|
|
449
|
-
scope: ['string', 'string.quoted', 'string.template'],
|
|
450
|
-
settings: { foreground: 'var(--stl-color-green-foreground)' },
|
|
451
|
-
},
|
|
452
|
-
// Keys, brackets
|
|
453
|
-
{
|
|
454
|
-
scope: ['support.type', 'meta'],
|
|
455
|
-
settings: { foreground: 'var(--stl-color-foreground)' },
|
|
456
|
-
},
|
|
457
|
-
// brackets
|
|
458
|
-
{
|
|
459
|
-
scope: ['meta'],
|
|
460
|
-
settings: { foreground: 'var(--stl-color-foreground-muted)' },
|
|
461
|
-
},
|
|
462
|
-
// built-in types
|
|
463
|
-
{
|
|
464
|
-
scope: ['support.type.builtin'],
|
|
465
|
-
settings: { foreground: 'var(--stl-color-purple-foreground)' },
|
|
466
|
-
},
|
|
467
|
-
],
|
|
468
|
-
},
|
|
469
|
-
],
|
|
470
|
-
langs: SupportedLanguageSyntaxes,
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
return astroShikiHighlighter;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Astro's markdown processor is a singleton
|
|
477
|
-
// Need to cache it instead of instantiating per request
|
|
478
|
-
let astroMarkdownProcessor: MarkdownProcessor;
|
|
479
|
-
async function astroMarkdown() {
|
|
480
|
-
if (!astroMarkdownProcessor) {
|
|
481
|
-
astroMarkdownProcessor = await createMarkdownProcessor({
|
|
482
|
-
gfm: true,
|
|
483
|
-
remarkPlugins: [remarkGfmAlerts],
|
|
484
|
-
shikiConfig: {
|
|
485
|
-
themes: HIGHLIGHT_THEMES,
|
|
486
|
-
},
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
return astroMarkdownProcessor;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
export async function astroMarkdownRender(content: string) {
|
|
494
|
-
const md = await astroMarkdown();
|
|
495
|
-
const output = await md.render(content);
|
|
496
|
-
|
|
497
|
-
// Map GFM callouts to the closest Starlight equivalent
|
|
498
|
-
output.code = output.code
|
|
499
|
-
.replaceAll('markdown-alert-caution', 'markdown-alert-danger')
|
|
500
|
-
.replaceAll('markdown-alert-warning', 'markdown-alert-caution')
|
|
501
|
-
.replaceAll('markdown-alert-important', 'markdown-alert-caution')
|
|
502
|
-
.replaceAll('markdown-alert-title', 'starlight-aside__title')
|
|
503
|
-
.replaceAll('markdown-alert-', 'starlight-aside--')
|
|
504
|
-
.replaceAll('markdown-alert', 'starlight-aside');
|
|
505
|
-
|
|
506
|
-
return output;
|
|
507
|
-
}
|
package/plugin/routes/Docs.astro
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
|
|
3
|
-
import { getReadmeContent, buildPageNavigation, RenderSpec
|
|
3
|
+
import { getReadmeContent, buildPageNavigation, RenderSpec } from '../react/Routing';
|
|
4
|
+
import { astroMarkdownRender } from '../markdown';
|
|
4
5
|
import { getResourceFromSpec } from '@stainless-api/docs-ui/utils';
|
|
5
6
|
import { parseRoute, parseStainlessPath } from '@stainless-api/docs-ui/routing';
|
|
6
7
|
import {
|