@stainless-api/docs 0.1.0-beta.1 → 0.1.0-beta.100
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 +917 -0
- package/eslint-suppressions.json +27 -0
- package/locals.d.ts +17 -0
- package/package.json +50 -40
- 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 +37 -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 -105
- package/plugin/components/SnippetCode.tsx +111 -66
- package/plugin/components/StainlessIslands.tsx +126 -0
- package/plugin/components/search/SearchAlgolia.astro +45 -35
- package/plugin/components/search/SearchIsland.tsx +47 -29
- package/plugin/generateAPIReferenceLink.ts +2 -2
- package/plugin/globalJs/ai-dropdown-options.ts +243 -0
- package/plugin/globalJs/code-snippets.ts +40 -11
- package/plugin/globalJs/copy.ts +95 -17
- package/plugin/globalJs/create-playground.shim.ts +3 -0
- package/plugin/globalJs/method-descriptions.ts +33 -0
- package/plugin/globalJs/navigation.ts +12 -33
- package/plugin/globalJs/playground-data.shim.ts +1 -0
- package/plugin/globalJs/playground-data.ts +14 -0
- package/plugin/helpers/generateDocsRoutes.ts +59 -0
- package/plugin/helpers/getPageLoadEvent.ts +1 -1
- package/plugin/helpers/multiSpec.ts +8 -0
- package/plugin/index.ts +299 -117
- package/plugin/languages.ts +8 -2
- package/plugin/loadPluginConfig.ts +254 -102
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +1 -1
- package/plugin/react/Routing.tsx +210 -140
- package/plugin/referencePlaceholderUtils.ts +18 -15
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +40 -32
- package/plugin/routes/Docs.astro +70 -119
- package/plugin/routes/DocsStatic.astro +6 -5
- package/plugin/routes/Overview.astro +37 -27
- package/plugin/routes/markdown.ts +13 -12
- package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +49 -60
- 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 +146 -0
- package/plugin/{cms → specs}/worker.ts +82 -5
- package/plugin/vendor/preview.worker.docs.js +22406 -17955
- package/plugin/vendor/templates/cli.md +1 -0
- package/plugin/vendor/templates/go.md +4 -2
- package/plugin/vendor/templates/java.md +3 -1
- package/plugin/vendor/templates/kotlin.md +3 -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/getProsePages.ts +42 -0
- package/shared/getSharedLogger.ts +15 -0
- package/shared/terminalUtils.ts +3 -0
- package/shared/virtualModule.ts +54 -1
- package/src/content.config.ts +9 -0
- package/stl-docs/components/AIDropdown.tsx +63 -0
- package/stl-docs/components/AiChatIsland.tsx +14 -0
- package/stl-docs/components/{content-panel/ContentBreadcrumbs.tsx → ContentBreadcrumbs.tsx} +2 -2
- package/stl-docs/components/Head.astro +20 -0
- package/stl-docs/components/Header.astro +7 -9
- package/stl-docs/components/PageFrame.astro +18 -0
- package/stl-docs/components/PageTitle.astro +82 -0
- package/stl-docs/components/TableOfContents.astro +34 -0
- package/stl-docs/components/ThemeProvider.astro +36 -0
- package/stl-docs/components/ThemeSelect.astro +84 -144
- package/stl-docs/components/content-panel/ContentPanel.astro +16 -46
- package/stl-docs/components/headers/DefaultHeader.astro +1 -1
- package/stl-docs/components/headers/HeaderLinks.astro +1 -1
- package/stl-docs/components/headers/SplashMobileMenuToggle.astro +17 -1
- package/stl-docs/components/headers/StackedHeader.astro +29 -24
- package/stl-docs/components/icons/chat-gpt.tsx +17 -0
- package/stl-docs/components/icons/claude.tsx +10 -0
- 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 +10 -0
- package/stl-docs/components/index.ts +1 -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/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/mintlify-compat/index.ts +2 -4
- package/stl-docs/components/nav-tabs/NavDropdown.astro +31 -75
- package/stl-docs/components/nav-tabs/NavTabs.astro +78 -80
- package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -8
- 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 +175 -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 +87 -0
- package/stl-docs/components/sidebars/SDKSelectSidebar.astro +8 -0
- 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 +159 -43
- package/stl-docs/loadStlDocsConfig.ts +60 -9
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +61 -0
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +41 -0
- package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
- package/stl-docs/proseSearchIndexing.ts +606 -0
- package/stl-docs/tabsMiddleware.ts +14 -5
- package/styles/code.css +133 -136
- package/styles/links.css +11 -48
- package/styles/method-descriptions.css +36 -0
- package/styles/overrides.css +49 -57
- package/styles/page.css +100 -59
- package/styles/sdk_select.css +9 -7
- package/styles/search.css +57 -69
- package/styles/sidebar.css +26 -156
- package/styles/{variables.css → sl-variables.css} +3 -2
- package/styles/stldocs-variables.css +6 -0
- package/styles/toc.css +41 -34
- package/theme.css +13 -3
- package/tsconfig.json +2 -5
- package/virtual-module.d.ts +65 -7
- package/components/variables.css +0 -139
- 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 -86
- package/stl-docs/components/Sidebar.astro +0 -11
- package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -64
- package/stl-docs/components/mintlify-compat/Step.astro +0 -58
- package/stl-docs/components/mintlify-compat/Steps.astro +0 -17
- 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,62 @@
|
|
|
1
|
+
import { StlSidebarEntry } from '@stainless-api/docs-ui/components';
|
|
2
|
+
import { SidebarEntry } from '../pagination/util';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
import { Badge, getHttpMethod } from '@stainless-api/ui-primitives';
|
|
5
|
+
import { FunctionIcon } from '@stainless-api/ui-primitives/icons';
|
|
6
|
+
import { BracesIcon } from 'lucide-react';
|
|
7
|
+
|
|
8
|
+
function getIcon(entry: SidebarEntry): ReactNode | undefined {
|
|
9
|
+
if (entry.type !== 'link') {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const methodAttr = entry.attrs['data-stldocs-method'];
|
|
13
|
+
const httpMethod = getHttpMethod(methodAttr);
|
|
14
|
+
if (httpMethod) {
|
|
15
|
+
return <Badge.HTTP method={httpMethod} iconOnly size="sm" />;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// special handling for the webhooks resource overview page
|
|
19
|
+
if (entry.attrs['data-stldocs-overview'] === 'webhooks') {
|
|
20
|
+
return (
|
|
21
|
+
<Badge size="sm" icon={<BracesIcon />} intent="info">
|
|
22
|
+
{''}
|
|
23
|
+
</Badge>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Support empty string as method to show generic "Function" badge
|
|
28
|
+
else if (methodAttr === '') {
|
|
29
|
+
return (
|
|
30
|
+
<Badge size="sm" icon={<FunctionIcon />} intent="info">
|
|
31
|
+
{''}
|
|
32
|
+
</Badge>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function convertAstroSidebarToStl(entries: SidebarEntry[]): StlSidebarEntry[] {
|
|
39
|
+
return entries.map((entry): StlSidebarEntry => {
|
|
40
|
+
if (entry.type === 'link') {
|
|
41
|
+
const icon = getIcon(entry);
|
|
42
|
+
return {
|
|
43
|
+
type: 'link',
|
|
44
|
+
attrs: entry.attrs,
|
|
45
|
+
label: entry.label,
|
|
46
|
+
target: {
|
|
47
|
+
type: 'href',
|
|
48
|
+
href: entry.href,
|
|
49
|
+
},
|
|
50
|
+
isCurrent: entry.isCurrent,
|
|
51
|
+
icon,
|
|
52
|
+
};
|
|
53
|
+
} else {
|
|
54
|
+
return {
|
|
55
|
+
type: 'group',
|
|
56
|
+
label: entry.label,
|
|
57
|
+
collapsed: entry.collapsed,
|
|
58
|
+
entries: convertAstroSidebarToStl(entry.entries),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AstroIntegration } from 'astro';
|
|
2
|
+
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
3
|
+
|
|
4
|
+
export const disableCalloutSyntaxAstroIntegration = {
|
|
5
|
+
name: 'stl-starlight-remove-callout-syntax',
|
|
6
|
+
hooks: {
|
|
7
|
+
'astro:config:setup': ({ config: astroConfig }) => {
|
|
8
|
+
// Remove starlight callout syntax in favor of our own callout component
|
|
9
|
+
// updateConfig always deeply merges arrays so we need to mutate remarkPlugins directly
|
|
10
|
+
// in order to remove plugins that starlight added
|
|
11
|
+
astroConfig.markdown.remarkPlugins = astroConfig.markdown.remarkPlugins.filter((plugin, i, arr) => {
|
|
12
|
+
if (typeof plugin !== 'function') return true;
|
|
13
|
+
// remove:
|
|
14
|
+
// 1. remarkDirective plugin
|
|
15
|
+
if (plugin.name === 'remarkDirective') return false;
|
|
16
|
+
// 2. directly followed by remarkAsides plugin (inner function named 'attacher')
|
|
17
|
+
if (plugin.name === 'attacher') {
|
|
18
|
+
const prev = arr[i - 1];
|
|
19
|
+
if (typeof prev === 'function' && prev.name === 'remarkDirective') return false;
|
|
20
|
+
}
|
|
21
|
+
// 3. remarkDirectivesRestoration plugin
|
|
22
|
+
if (plugin.name === 'remarkDirectivesRestoration') return false;
|
|
23
|
+
return true;
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
} satisfies AstroIntegration;
|
|
28
|
+
|
|
29
|
+
export const disableCalloutSyntaxStarlightPlugin = {
|
|
30
|
+
name: 'stl-starlight-remove-callout-syntax',
|
|
31
|
+
hooks: {
|
|
32
|
+
'config:setup': ({ addIntegration }) => {
|
|
33
|
+
addIntegration(disableCalloutSyntaxAstroIntegration);
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
} satisfies StarlightPlugin;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import type { AstroConfig } from 'astro';
|
|
2
|
+
import type { Defined } from './loadStlDocsConfig';
|
|
3
|
+
import { fontProviders } from 'astro/config';
|
|
4
|
+
import type { FontPreloadFilter } from 'astro:assets';
|
|
5
|
+
|
|
6
|
+
type AstroFontConfigEntry = Defined<AstroConfig['experimental']['fonts']>[number];
|
|
7
|
+
|
|
8
|
+
// Apply Omit to each member of the union while preserving union structure
|
|
9
|
+
type PreloadFilter = { preload?: FontPreloadFilter };
|
|
10
|
+
export type StlDocsFontConfigEntry = (AstroFontConfigEntry extends infer T
|
|
11
|
+
? T extends unknown
|
|
12
|
+
? Omit<T, 'cssVariable'>
|
|
13
|
+
: never
|
|
14
|
+
: never) &
|
|
15
|
+
PreloadFilter;
|
|
16
|
+
|
|
17
|
+
export type StlDocsFontConfig = {
|
|
18
|
+
primary?: StlDocsFontConfigEntry;
|
|
19
|
+
heading?: StlDocsFontConfigEntry;
|
|
20
|
+
mono?: StlDocsFontConfigEntry;
|
|
21
|
+
additional?: (AstroFontConfigEntry & PreloadFilter)[];
|
|
22
|
+
};
|
|
23
|
+
const latinFeatureSettings = "'ss01' on, 'ss03' on, 'ss04' on, 'ss06' on, 'ss08' on";
|
|
24
|
+
/* prettier-ignore */
|
|
25
|
+
const latinUnicodeRange: readonly string[] = ['U+0000-00FF', 'U+0131', 'U+0152-0153', 'U+02BB-02BC', 'U+02C6', 'U+02DA', 'U+02DC', 'U+0304', 'U+0308', 'U+0329', 'U+2000-206F', 'U+20AC', 'U+2122', 'U+2191', 'U+2193', 'U+2212', 'U+2215', 'U+FEFF', 'U+FFFD'];
|
|
26
|
+
// /* prettier-ignore */
|
|
27
|
+
// const latinExtUnicodeRange: readonly string[] = ['U+0100-02BA', 'U+02BD-02C5', 'U+02C7-02CC', 'U+02CE-02D7', 'U+02DD-02FF', 'U+0304', 'U+0308', 'U+0329', 'U+1D00-1DBF', 'U+1E00-1E9F', 'U+1EF2-1EFF', 'U+2020', 'U+20A0-20AB', 'U+20AD-20C0', 'U+2113', 'U+2C60-2C7F', 'U+A720-A7FF'];
|
|
28
|
+
|
|
29
|
+
export function getFontRoles(fonts: StlDocsFontConfig | undefined) {
|
|
30
|
+
if (!fonts) {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
const fontConfigs: {
|
|
34
|
+
primary?: { cssVariable: string; preload?: FontPreloadFilter };
|
|
35
|
+
heading?: { cssVariable: string; preload?: FontPreloadFilter };
|
|
36
|
+
mono?: { cssVariable: string; preload?: FontPreloadFilter };
|
|
37
|
+
additional?: { cssVariable: string; preload?: FontPreloadFilter }[];
|
|
38
|
+
} = {};
|
|
39
|
+
if (fonts.primary) {
|
|
40
|
+
fontConfigs['primary'] = {
|
|
41
|
+
cssVariable: '--stl-typography-font' as const,
|
|
42
|
+
preload: fonts.primary.preload ?? [{ style: 'normal' }],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (fonts.heading) {
|
|
46
|
+
fontConfigs['heading'] = {
|
|
47
|
+
cssVariable: '--stl-typography-font-heading' as const,
|
|
48
|
+
preload: fonts.heading.preload ?? [{ style: 'normal' }],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (fonts.mono) {
|
|
52
|
+
fontConfigs['mono'] = {
|
|
53
|
+
cssVariable: '--stl-typography-font-mono' as const,
|
|
54
|
+
preload: fonts.mono.preload ?? [{ style: 'normal' }],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (fonts.additional) {
|
|
58
|
+
fontConfigs['additional'] = fonts.additional.map((font) => ({
|
|
59
|
+
cssVariable: font.cssVariable,
|
|
60
|
+
preload: font.preload ?? [{ style: 'normal' }],
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
return fontConfigs;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function normalizeFonts(fonts: StlDocsFontConfig | undefined): StlDocsFontConfig {
|
|
67
|
+
const defaultPrimary: StlDocsFontConfigEntry = {
|
|
68
|
+
provider: fontProviders.local(),
|
|
69
|
+
name: 'Geist',
|
|
70
|
+
display: 'swap',
|
|
71
|
+
preload: [
|
|
72
|
+
{
|
|
73
|
+
weight: '100 900',
|
|
74
|
+
style: 'normal',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
options: {
|
|
78
|
+
variants: [
|
|
79
|
+
{
|
|
80
|
+
weight: '100 900',
|
|
81
|
+
style: 'normal',
|
|
82
|
+
src: [new URL('../assets/fonts/geist/geist-latin.woff2', import.meta.url)],
|
|
83
|
+
unicodeRange: latinUnicodeRange,
|
|
84
|
+
featureSettings: latinFeatureSettings,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
weight: '100 900',
|
|
88
|
+
style: 'italic',
|
|
89
|
+
src: [new URL('../assets/fonts/geist/geist-italic-latin.woff2', import.meta.url)],
|
|
90
|
+
unicodeRange: latinUnicodeRange,
|
|
91
|
+
featureSettings: latinFeatureSettings,
|
|
92
|
+
},
|
|
93
|
+
// {
|
|
94
|
+
// weight: '100 900',
|
|
95
|
+
// style: 'normal',
|
|
96
|
+
// src: [new URL('../assets/fonts/geist/geist-latin-ext.woff2', import.meta.url)],
|
|
97
|
+
// unicodeRange: latinExtUnicodeRange,
|
|
98
|
+
// featureSettings: latinFeatureSettings,
|
|
99
|
+
// },
|
|
100
|
+
// {
|
|
101
|
+
// weight: '100 900',
|
|
102
|
+
// style: 'italic',
|
|
103
|
+
// src: [new URL('../assets/fonts/geist/geist-italic-latin-ext.woff2', import.meta.url)],
|
|
104
|
+
// unicodeRange: latinExtUnicodeRange,
|
|
105
|
+
// featureSettings: latinFeatureSettings,
|
|
106
|
+
// },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
const defaultMono: StlDocsFontConfigEntry = {
|
|
111
|
+
provider: fontProviders.local(),
|
|
112
|
+
name: 'Geist Mono',
|
|
113
|
+
display: 'swap',
|
|
114
|
+
preload: [
|
|
115
|
+
{
|
|
116
|
+
weight: '100 900',
|
|
117
|
+
style: 'normal',
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
options: {
|
|
121
|
+
variants: [
|
|
122
|
+
{
|
|
123
|
+
weight: '100 900',
|
|
124
|
+
style: 'normal',
|
|
125
|
+
src: [new URL('../assets/fonts/geist/geist-mono-latin.woff2', import.meta.url)],
|
|
126
|
+
unicodeRange: latinUnicodeRange,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
weight: '100 900',
|
|
130
|
+
style: 'italic',
|
|
131
|
+
src: [new URL('../assets/fonts/geist/geist-mono-italic-latin.woff2', import.meta.url)],
|
|
132
|
+
unicodeRange: latinUnicodeRange,
|
|
133
|
+
},
|
|
134
|
+
// {
|
|
135
|
+
// weight: '100 900',
|
|
136
|
+
// style: 'normal',
|
|
137
|
+
// src: [new URL('../assets/fonts/geist/geist-mono-latin-ext.woff2', import.meta.url)],
|
|
138
|
+
// unicodeRange: latinExtUnicodeRange,
|
|
139
|
+
// },
|
|
140
|
+
// {
|
|
141
|
+
// weight: '100 900',
|
|
142
|
+
// style: 'italic',
|
|
143
|
+
// src: [new URL('../assets/fonts/geist/geist-mono-italic-latin-ext.woff2', import.meta.url)],
|
|
144
|
+
// unicodeRange: latinExtUnicodeRange,
|
|
145
|
+
// },
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
primary: fonts?.primary ?? defaultPrimary,
|
|
152
|
+
heading: fonts?.heading ?? undefined,
|
|
153
|
+
mono: fonts?.mono ?? defaultMono,
|
|
154
|
+
additional: fonts?.additional ?? [],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Normalize fonts for the Astro config
|
|
159
|
+
export function flattenFonts(fonts: StlDocsFontConfig | undefined): AstroFontConfigEntry[] {
|
|
160
|
+
if (!fonts) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
const fontConfigs: AstroFontConfigEntry[] = [];
|
|
164
|
+
if (fonts.primary) {
|
|
165
|
+
fontConfigs.push({
|
|
166
|
+
...fonts.primary,
|
|
167
|
+
cssVariable: '--stl-typography-font' as const,
|
|
168
|
+
} as AstroFontConfigEntry);
|
|
169
|
+
}
|
|
170
|
+
if (fonts.heading) {
|
|
171
|
+
fontConfigs.push({
|
|
172
|
+
...fonts.heading,
|
|
173
|
+
cssVariable: '--stl-typography-font-heading' as const,
|
|
174
|
+
} as AstroFontConfigEntry);
|
|
175
|
+
}
|
|
176
|
+
if (fonts.mono) {
|
|
177
|
+
fontConfigs.push({
|
|
178
|
+
...fonts.mono,
|
|
179
|
+
cssVariable: '--stl-typography-font-mono' as const,
|
|
180
|
+
} as AstroFontConfigEntry);
|
|
181
|
+
}
|
|
182
|
+
if (fonts.additional) {
|
|
183
|
+
fontConfigs.push(...fonts.additional.map((font) => font as AstroFontConfigEntry));
|
|
184
|
+
}
|
|
185
|
+
return fontConfigs;
|
|
186
|
+
}
|
package/stl-docs/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import starlight from '@astrojs/starlight';
|
|
2
2
|
import react from '@astrojs/react';
|
|
3
|
-
import {
|
|
3
|
+
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
4
|
+
import { disableCalloutSyntaxStarlightPlugin } from './disableCalloutSyntax';
|
|
4
5
|
|
|
5
6
|
import type { AstroIntegration } from 'astro';
|
|
6
7
|
|
|
@@ -16,11 +17,18 @@ import {
|
|
|
16
17
|
type StarlightSidebarConfig,
|
|
17
18
|
} from './loadStlDocsConfig';
|
|
18
19
|
import { buildVirtualModuleString } from '../shared/virtualModule';
|
|
19
|
-
|
|
20
|
-
import
|
|
20
|
+
import type * as StlDocsVirtualModule from 'virtual:stl-docs-virtual-module';
|
|
21
|
+
import { resolveSrcFile } from '../resolveSrcFile';
|
|
22
|
+
import { stainlessDocsMarkdownRenderer } from './proseMarkdown/proseMarkdownIntegration';
|
|
23
|
+
import { setSharedLogger } from '../shared/getSharedLogger';
|
|
24
|
+
import { stainlessDocsAlgoliaProseIndexing, stainlessDocsVectorProseIndexing } from './proseSearchIndexing';
|
|
25
|
+
import { stainlessStarlight } from '../plugin';
|
|
26
|
+
import { getFontRoles, flattenFonts } from './fonts';
|
|
21
27
|
|
|
22
28
|
export * from '../plugin';
|
|
23
29
|
|
|
30
|
+
const COMPONENTS_FOLDER = '/stl-docs/components';
|
|
31
|
+
|
|
24
32
|
function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig) {
|
|
25
33
|
// We transform our tabs into a Starlight sidebar
|
|
26
34
|
// This gives them all the built-in features of Starlight (eg. auto-generated entries by directory)
|
|
@@ -41,13 +49,43 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
41
49
|
|
|
42
50
|
type ComponentOverrides = StarlightConfigDefined['components'];
|
|
43
51
|
const componentOverrides: ComponentOverrides = {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
PageFrame: resolveSrcFile(COMPONENTS_FOLDER, './PageFrame.astro'),
|
|
53
|
+
|
|
54
|
+
Head: resolveSrcFile(COMPONENTS_FOLDER, './Head.astro'),
|
|
55
|
+
Header: resolveSrcFile(COMPONENTS_FOLDER, './Header.astro'),
|
|
56
|
+
ThemeProvider: resolveSrcFile(COMPONENTS_FOLDER, './ThemeProvider.astro'),
|
|
57
|
+
ThemeSelect: resolveSrcFile(COMPONENTS_FOLDER, './ThemeSelect.astro'),
|
|
58
|
+
|
|
59
|
+
Sidebar: resolveSrcFile(COMPONENTS_FOLDER, './sidebars/BaseSidebar.astro'),
|
|
60
|
+
ContentPanel: resolveSrcFile(COMPONENTS_FOLDER, './content-panel/ContentPanel.astro'),
|
|
61
|
+
TableOfContents: resolveSrcFile(COMPONENTS_FOLDER, './TableOfContents.astro'),
|
|
62
|
+
|
|
63
|
+
PageTitle: resolveSrcFile(COMPONENTS_FOLDER, './PageTitle.astro'),
|
|
64
|
+
Pagination: resolveSrcFile(COMPONENTS_FOLDER, './pagination/Pagination.astro'),
|
|
49
65
|
};
|
|
50
66
|
|
|
67
|
+
const plugins: StarlightPlugin[] = [
|
|
68
|
+
// Disable starlight callout syntax in favor of our own component
|
|
69
|
+
disableCalloutSyntaxStarlightPlugin,
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
if (config.apiReference !== null) {
|
|
73
|
+
plugins.push(
|
|
74
|
+
stainlessStarlight({
|
|
75
|
+
...config.apiReference,
|
|
76
|
+
contextMenu: config.contextMenu,
|
|
77
|
+
experimentalPrerender:
|
|
78
|
+
config.apiReference.experimentalPrerender === undefined
|
|
79
|
+
? config.starlightPassThrough.prerender
|
|
80
|
+
: config.apiReference.experimentalPrerender,
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
componentOverrides.Sidebar = resolveSrcFile(COMPONENTS_FOLDER, './sidebars/SDKSelectSidebar.astro');
|
|
84
|
+
componentOverrides.Search = resolveSrcFile('/plugin/components/search/Search.astro');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
plugins.push(...config.starlightCompat.plugins, ...config.plugins.map((p) => p(config)));
|
|
88
|
+
|
|
51
89
|
// TODO: re-add once we figure out what to do with the client router
|
|
52
90
|
// if (config.enableClientRouter) {
|
|
53
91
|
// // logger.info(`Client router is enabled`);
|
|
@@ -56,6 +94,8 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
56
94
|
// // logger.info(`Client router is disabled`);
|
|
57
95
|
// }
|
|
58
96
|
|
|
97
|
+
const userExpressiveCode = typeof config.expressiveCode === 'object' ? config.expressiveCode : {};
|
|
98
|
+
|
|
59
99
|
return starlight({
|
|
60
100
|
...config.starlightPassThrough,
|
|
61
101
|
sidebar,
|
|
@@ -79,64 +119,112 @@ function stainlessDocsStarlightIntegration(config: NormalizedStainlessDocsConfig
|
|
|
79
119
|
setupNavLinksInitial();
|
|
80
120
|
`,
|
|
81
121
|
},
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
122
|
+
],
|
|
123
|
+
routeMiddleware: [
|
|
124
|
+
...config.starlightCompat.routeMiddleware,
|
|
125
|
+
resolveSrcFile('/stl-docs/tabsMiddleware.ts'),
|
|
126
|
+
],
|
|
127
|
+
customCss: [resolveSrcFile('/theme.css'), ...config.customCss],
|
|
128
|
+
|
|
129
|
+
expressiveCode: {
|
|
130
|
+
...userExpressiveCode,
|
|
131
|
+
themes: userExpressiveCode.themes ?? ['github-light', 'github-dark'],
|
|
132
|
+
styleOverrides: {
|
|
133
|
+
...userExpressiveCode.styleOverrides,
|
|
134
|
+
textMarkers: {
|
|
135
|
+
insBackground: 'var(--stl-color-green-muted-background)',
|
|
136
|
+
insBorderColor: 'var(--stl-color-green-border)',
|
|
137
|
+
insDiffIndicatorColor: 'var(--stl-color-green-foreground-reduced)',
|
|
138
|
+
|
|
139
|
+
delBackground: 'var(--stl-color-red-muted-background)',
|
|
140
|
+
delBorderColor: 'var(--stl-color-red-border)',
|
|
141
|
+
delDiffIndicatorColor: 'var(--stl-color-red-foreground-reduced)',
|
|
142
|
+
|
|
143
|
+
markBackground: 'var(--stl-color-blue-muted-background)',
|
|
144
|
+
markBorderColor: 'var(--stl-color-blue-border)',
|
|
145
|
+
...userExpressiveCode.styleOverrides?.textMarkers,
|
|
92
146
|
},
|
|
93
147
|
},
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
customCss: ['@stainless-api/docs/theme', ...config.customCss],
|
|
97
|
-
plugins: [stainlessStarlight(config.apiReference), ...config.starlightCompat.plugins],
|
|
148
|
+
},
|
|
149
|
+
plugins,
|
|
98
150
|
});
|
|
99
151
|
}
|
|
100
152
|
|
|
101
|
-
function stainlessDocsIntegration(
|
|
102
|
-
|
|
153
|
+
function stainlessDocsIntegration(
|
|
154
|
+
config: NormalizedStainlessDocsConfig,
|
|
155
|
+
apiReferenceBasePath: string | null,
|
|
156
|
+
): AstroIntegration {
|
|
103
157
|
// The '\0' prefix tells Vite “this is a virtual module” and prevents it from being resolved again.
|
|
104
|
-
const
|
|
158
|
+
const resolveVirtualModuleId = (id: string) => `\0${id}`;
|
|
105
159
|
let redirects: NormalizedRedirectConfig | null = null;
|
|
106
160
|
|
|
107
161
|
return {
|
|
108
|
-
name: 'stl-docs-
|
|
162
|
+
name: 'stl-docs-astro',
|
|
109
163
|
hooks: {
|
|
110
164
|
'astro:config:setup': ({ updateConfig, command, config: astroConfig }) => {
|
|
111
|
-
//
|
|
112
|
-
//
|
|
165
|
+
// we only handle redirects for builds
|
|
166
|
+
// in dev, Astro handles them for us
|
|
113
167
|
if (command === 'build' && astroConfig.redirects) {
|
|
114
168
|
redirects = normalizeRedirects(astroConfig.redirects);
|
|
115
169
|
}
|
|
116
170
|
|
|
171
|
+
const virtualModules = new Map(
|
|
172
|
+
Object.entries({
|
|
173
|
+
'virtual:stl-docs-virtual-module': buildVirtualModuleString({
|
|
174
|
+
TABS: config.tabs,
|
|
175
|
+
SPLIT_TABS_ENABLED: config.splitTabsEnabled,
|
|
176
|
+
HEADER_LINKS: config.header.links,
|
|
177
|
+
HEADER_LAYOUT: config.header.layout,
|
|
178
|
+
ENABLE_CLIENT_ROUTER: config.enableClientRouter,
|
|
179
|
+
API_REFERENCE_BASE_PATH: apiReferenceBasePath ?? '/api',
|
|
180
|
+
ENABLE_PROSE_MARKDOWN_RENDERING: config.enableProseMarkdownRendering,
|
|
181
|
+
ENABLE_CONTEXT_MENU: config.contextMenu, // TODO: do not duplicate this between both virtual modules
|
|
182
|
+
RENDER_PAGE_DESCRIPTIONS: config.renderPageDescriptions,
|
|
183
|
+
FONTS: getFontRoles(config.fonts),
|
|
184
|
+
LINK_GROUP_TITLES_TO_OVERVIEW_PAGES: config.linkGroupTitlesToOverviewPages,
|
|
185
|
+
} satisfies typeof StlDocsVirtualModule),
|
|
186
|
+
|
|
187
|
+
'virtual:stl-docs/components/AiChat.tsx': `
|
|
188
|
+
${
|
|
189
|
+
config.aiChat
|
|
190
|
+
? `export { default } from ${JSON.stringify(config.aiChat.chatComponentPath)};`
|
|
191
|
+
: // export null when no AI chat component is provided
|
|
192
|
+
`export default null;`
|
|
193
|
+
}
|
|
194
|
+
export const STAINLESS_PROJECT = ${config.apiReference ? JSON.stringify(config.apiReference.stainlessProject) : 'undefined'};
|
|
195
|
+
`,
|
|
196
|
+
}),
|
|
197
|
+
);
|
|
198
|
+
|
|
117
199
|
updateConfig({
|
|
200
|
+
experimental: {
|
|
201
|
+
fonts: [...flattenFonts(config.fonts), ...(astroConfig.experimental?.fonts ?? [])],
|
|
202
|
+
},
|
|
118
203
|
vite: {
|
|
119
204
|
plugins: [
|
|
120
205
|
{
|
|
121
206
|
name: 'stl-docs-vite',
|
|
122
207
|
resolveId(id) {
|
|
123
|
-
if (id
|
|
124
|
-
return resolvedId;
|
|
125
|
-
}
|
|
208
|
+
if (virtualModules.has(id)) return resolveVirtualModuleId(id);
|
|
126
209
|
},
|
|
127
210
|
load(id) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
TABS: config.tabs,
|
|
131
|
-
SPLIT_TABS_ENABLED: config.splitTabsEnabled,
|
|
132
|
-
HEADER_LINKS: config.header.links,
|
|
133
|
-
HEADER_LAYOUT: config.header.layout,
|
|
134
|
-
ENABLE_CLIENT_ROUTER: config.enableClientRouter,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
211
|
+
const bare = id.replace(/^\0/, '');
|
|
212
|
+
if (virtualModules.has(bare)) return virtualModules.get(bare);
|
|
137
213
|
},
|
|
138
214
|
},
|
|
139
215
|
],
|
|
216
|
+
optimizeDeps: {
|
|
217
|
+
include: config.aiChat
|
|
218
|
+
? [
|
|
219
|
+
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > lucide-react',
|
|
220
|
+
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > motion',
|
|
221
|
+
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > motion > framer-motion',
|
|
222
|
+
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > react-markdown',
|
|
223
|
+
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > react-syntax-highlighter',
|
|
224
|
+
'@stainless-api/docs-ai-chat > @stainless-api/ai-chat > remark-gfm',
|
|
225
|
+
]
|
|
226
|
+
: [],
|
|
227
|
+
},
|
|
140
228
|
},
|
|
141
229
|
build: {
|
|
142
230
|
...astroConfig.build,
|
|
@@ -147,7 +235,7 @@ function stainlessDocsIntegration(config: NormalizedStainlessDocsConfig): AstroI
|
|
|
147
235
|
'astro:build:done': ({ dir }) => {
|
|
148
236
|
if (redirects !== null) {
|
|
149
237
|
const stainlessDir = join(dir.pathname, '_stainless');
|
|
150
|
-
mkdirSync(stainlessDir);
|
|
238
|
+
mkdirSync(stainlessDir, { recursive: true });
|
|
151
239
|
const outputPath = join(stainlessDir, 'redirects.json');
|
|
152
240
|
writeFileSync(outputPath, JSON.stringify(redirects, null, 2), {
|
|
153
241
|
encoding: 'utf-8',
|
|
@@ -158,7 +246,18 @@ function stainlessDocsIntegration(config: NormalizedStainlessDocsConfig): AstroI
|
|
|
158
246
|
};
|
|
159
247
|
}
|
|
160
248
|
|
|
161
|
-
|
|
249
|
+
function sharedLoggerIntegration(): AstroIntegration {
|
|
250
|
+
return {
|
|
251
|
+
name: 'stainless',
|
|
252
|
+
hooks: {
|
|
253
|
+
'astro:config:setup': ({ logger }) => {
|
|
254
|
+
setSharedLogger(logger);
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function stainlessDocs(config: StainlessDocsUserConfig): StarlightPlugin[] {
|
|
162
261
|
const normalizedConfigResult = parseStlDocsConfig(config);
|
|
163
262
|
if (normalizedConfigResult.result === 'error') {
|
|
164
263
|
// TODO: would be good to use the astro logger somehow
|
|
@@ -166,9 +265,26 @@ export function stainlessDocs(config: StainlessDocsUserConfig) {
|
|
|
166
265
|
process.exit(1);
|
|
167
266
|
}
|
|
168
267
|
const normalizedConfig = normalizedConfigResult.config;
|
|
268
|
+
|
|
269
|
+
// TODO: need to refactor this, but this allows us to get the base path for the API reference _if_ it exists
|
|
270
|
+
// if it doesn't exist, the value of basePath is null.
|
|
271
|
+
// the stl-starlight virtual module has base path, but it's not available when there's no API reference
|
|
272
|
+
const hasApiReference = normalizedConfig.apiReference !== null;
|
|
273
|
+
let apiReferenceBasePath: string | null = null;
|
|
274
|
+
if (hasApiReference) {
|
|
275
|
+
apiReferenceBasePath = normalizedConfig.apiReference?.basePath ?? '/api';
|
|
276
|
+
}
|
|
277
|
+
|
|
169
278
|
return [
|
|
279
|
+
sharedLoggerIntegration(), // this **must** be first so it can set the shared logger used by our other integrations
|
|
170
280
|
react(),
|
|
171
281
|
stainlessDocsStarlightIntegration(normalizedConfig),
|
|
172
|
-
stainlessDocsIntegration(normalizedConfig),
|
|
282
|
+
stainlessDocsIntegration(normalizedConfig, apiReferenceBasePath),
|
|
283
|
+
stainlessDocsMarkdownRenderer({
|
|
284
|
+
enabled: normalizedConfig.enableProseMarkdownRendering,
|
|
285
|
+
apiReferenceBasePath,
|
|
286
|
+
}),
|
|
287
|
+
stainlessDocsAlgoliaProseIndexing({ apiReferenceBasePath }),
|
|
288
|
+
stainlessDocsVectorProseIndexing(normalizedConfig, apiReferenceBasePath),
|
|
173
289
|
];
|
|
174
290
|
}
|