@stainless-api/docs 0.1.0-beta.12 → 0.1.0-beta.121
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 +1012 -0
- package/eslint-suppressions.json +95 -0
- package/{eslint.config.js → eslint.config.ts} +0 -2
- package/locals.d.ts +17 -0
- package/package.json +57 -43
- package/playground-virtual-modules.d.ts +96 -0
- package/plugin/assets/languages/cli.svg +14 -0
- package/plugin/assets/languages/csharp.svg +1 -0
- package/plugin/assets/languages/php.svg +4 -0
- package/plugin/buildAlgoliaIndex.ts +40 -39
- package/plugin/components/MethodDescription.tsx +54 -0
- package/plugin/components/RequestBuilder/ParamEditor.tsx +55 -0
- package/plugin/components/RequestBuilder/SnippetStainlessIsland.tsx +107 -0
- package/plugin/components/RequestBuilder/index.tsx +40 -0
- package/plugin/components/RequestBuilder/props.ts +9 -0
- package/plugin/components/RequestBuilder/spec-helpers.ts +47 -0
- package/plugin/components/RequestBuilder/styles.css +67 -0
- package/plugin/components/SDKSelect.astro +18 -111
- package/plugin/components/SnippetCode.tsx +112 -70
- package/plugin/components/StainlessIslands.tsx +126 -0
- package/plugin/components/search/SearchAlgolia.astro +46 -29
- package/plugin/components/search/SearchIsland.tsx +61 -37
- package/plugin/generateAPIReferenceLink.ts +2 -2
- package/plugin/globalJs/ai-dropdown-options.ts +248 -0
- package/plugin/globalJs/code-snippets.ts +45 -16
- package/plugin/globalJs/copy.ts +115 -27
- package/plugin/globalJs/create-playground.shim.ts +3 -0
- package/plugin/globalJs/method-descriptions.ts +33 -0
- package/plugin/globalJs/navigation.ts +15 -33
- package/plugin/globalJs/playground-data.shim.ts +1 -0
- package/plugin/globalJs/playground-data.ts +14 -0
- package/plugin/globalJs/summary-selection-tweak.ts +29 -0
- package/plugin/helpers/generateDocsRoutes.ts +59 -0
- package/plugin/helpers/multiSpec.ts +8 -0
- package/plugin/index.ts +306 -142
- package/plugin/languages.ts +8 -2
- package/plugin/loadPluginConfig.ts +251 -107
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +3 -1
- package/plugin/react/Routing.tsx +214 -143
- package/plugin/referencePlaceholderUtils.ts +18 -15
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +39 -35
- package/plugin/routes/Docs.astro +71 -111
- package/plugin/routes/DocsStatic.astro +6 -5
- package/plugin/routes/Overview.astro +46 -22
- package/plugin/routes/markdown.ts +13 -12
- package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +83 -63
- 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 +137 -0
- package/plugin/specs/inputResolver.ts +148 -0
- package/plugin/{cms → specs}/worker.ts +82 -5
- package/plugin/vendor/preview.worker.docs.js +27234 -17991
- package/plugin/vendor/templates/cli.md +1 -0
- package/plugin/vendor/templates/go.md +4 -2
- package/plugin/vendor/templates/java.md +5 -1
- package/plugin/vendor/templates/kotlin.md +5 -1
- package/plugin/vendor/templates/node.md +4 -2
- package/plugin/vendor/templates/python.md +4 -2
- package/plugin/vendor/templates/ruby.md +4 -2
- package/plugin/vendor/templates/terraform.md +1 -1
- package/plugin/vendor/templates/typescript.md +3 -1
- package/resolveSrcFile.ts +10 -0
- package/scripts/vendor_deps.ts +5 -5
- package/shared/conditionalIntegration.ts +28 -0
- package/shared/getProsePages.ts +41 -0
- package/shared/getSharedLogger.ts +15 -0
- package/shared/terminalUtils.ts +3 -0
- package/shared/virtualModule.ts +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/ContentPanel.astro +9 -0
- package/stl-docs/components/Footer.astro +89 -0
- package/stl-docs/components/Head.astro +20 -0
- package/stl-docs/components/Header.astro +3 -10
- package/stl-docs/components/PageFrame.astro +34 -0
- package/stl-docs/components/PageSidebar.astro +11 -0
- package/stl-docs/components/PageTitle.astro +82 -0
- package/stl-docs/components/StainlessLogo.svg +4 -0
- package/stl-docs/components/TableOfContents.astro +34 -0
- package/stl-docs/components/ThemeProvider.astro +36 -0
- package/stl-docs/components/ThemeSelect.astro +84 -146
- package/stl-docs/components/TwoColumnContent.astro +2 -0
- package/stl-docs/components/headers/DefaultHeader.astro +4 -6
- package/stl-docs/components/headers/StackedHeader.astro +8 -51
- package/stl-docs/components/icons/chat-gpt.tsx +2 -2
- package/stl-docs/components/icons/cursor.tsx +10 -0
- package/stl-docs/components/icons/gemini.tsx +19 -0
- package/stl-docs/components/icons/markdown.tsx +1 -1
- package/stl-docs/components/index.ts +1 -0
- package/stl-docs/components/mintlify-compat/Frame.astro +4 -4
- package/stl-docs/components/mintlify-compat/card.css +4 -4
- package/stl-docs/components/mintlify-compat/index.ts +2 -4
- package/stl-docs/components/nav-tabs/NavDropdown.astro +31 -75
- package/stl-docs/components/nav-tabs/NavTabs.astro +79 -81
- package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -7
- package/stl-docs/components/nav-tabs/buildNavLinks.ts +3 -2
- package/stl-docs/components/pagination/HomeLink.astro +10 -0
- package/stl-docs/components/pagination/Pagination.astro +177 -0
- package/stl-docs/components/pagination/PaginationLinkEmphasized.astro +22 -0
- package/stl-docs/components/pagination/PaginationLinkQuiet.astro +13 -0
- package/stl-docs/components/pagination/util.ts +71 -0
- package/stl-docs/components/scripts.ts +1 -0
- package/stl-docs/components/sidebars/BaseSidebar.astro +80 -2
- package/stl-docs/components/sidebars/SidebarWithComponents.tsx +10 -0
- package/stl-docs/components/sidebars/convertAstroSidebarToStl.tsx +62 -0
- package/stl-docs/disableCalloutSyntax.ts +36 -0
- package/stl-docs/fonts.ts +186 -0
- package/stl-docs/index.ts +178 -54
- package/stl-docs/loadStlDocsConfig.ts +64 -8
- package/stl-docs/proseDocSync.ts +314 -0
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +53 -0
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +41 -0
- package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
- package/stl-docs/proseSearchIndexing.ts +222 -0
- package/stl-docs/tabsMiddleware.ts +14 -5
- package/styles/code.css +53 -49
- package/styles/links.css +2 -37
- package/styles/method-descriptions.css +36 -0
- package/styles/overrides.css +28 -46
- package/styles/page.css +230 -52
- package/styles/sdk_select.css +9 -6
- package/styles/search.css +11 -21
- package/styles/sidebar.css +28 -211
- package/styles/{variables.css → sl-variables.css} +4 -8
- package/styles/stldocs-variables.css +6 -0
- package/styles/toc.css +19 -8
- package/theme.css +11 -9
- package/tsconfig.json +1 -4
- package/virtual-module.d.ts +65 -8
- package/components/variables.css +0 -112
- package/plugin/cms/client.ts +0 -62
- package/plugin/cms/server.ts +0 -268
- package/plugin/globalJs/ai-dropdown.ts +0 -57
- package/stl-docs/components/APIReferenceAIDropdown.tsx +0 -58
- package/stl-docs/components/content-panel/ContentPanel.astro +0 -69
- package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -55
- package/stl-docs/components/headers/SplashMobileMenuToggle.astro +0 -49
- package/stl-docs/components/mintlify-compat/Step.astro +0 -56
- package/stl-docs/components/mintlify-compat/Steps.astro +0 -15
- package/styles/fonts.css +0 -68
- /package/{plugin/assets → assets}/fonts/geist/OFL.txt +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin.woff2 +0 -0
package/plugin/index.ts
CHANGED
|
@@ -2,32 +2,43 @@ import react from '@astrojs/react';
|
|
|
2
2
|
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
3
3
|
import type { AstroIntegration } from 'astro';
|
|
4
4
|
import { config } from 'dotenv';
|
|
5
|
-
import getPort from 'get-port';
|
|
6
|
-
import { startDevServer } from './cms/server';
|
|
7
|
-
import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
8
5
|
import {
|
|
9
6
|
getAPIReferencePlaceholderItemFromSidebarConfig,
|
|
10
7
|
makePlaceholderItems,
|
|
11
8
|
} from './referencePlaceholderUtils';
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
import {
|
|
10
|
+
SidebarConfigItemsBuilder,
|
|
11
|
+
toStarlightSidebar,
|
|
12
|
+
type GeneratedSidebarConfig,
|
|
13
|
+
type ReferenceSidebarConfigGenerateOptions,
|
|
14
|
+
type ReferenceSidebarConfigItem,
|
|
15
|
+
} from './sidebar-utils/sidebar-builder';
|
|
17
16
|
import {
|
|
18
17
|
parseStarlightPluginConfig,
|
|
19
18
|
type NormalizedStainlessStarlightConfig,
|
|
20
19
|
type SomeStainlessStarlightUserConfig,
|
|
21
|
-
type SpecRetrieverConfig,
|
|
22
20
|
} from './loadPluginConfig';
|
|
23
|
-
import { buildVirtualModuleString } from '../shared/virtualModule';
|
|
21
|
+
import { buildVirtualModuleString, makeAsyncVirtualModPlugin } from '../shared/virtualModule';
|
|
22
|
+
import type * as StlStarlightVirtualModule from 'virtual:stl-starlight-virtual-module';
|
|
24
23
|
import path from 'path';
|
|
25
24
|
import fs from 'fs';
|
|
25
|
+
import { getSharedLogger } from '../shared/getSharedLogger';
|
|
26
|
+
import { resolveSrcFile } from '../resolveSrcFile';
|
|
27
|
+
import { mkdir, writeFile } from 'fs/promises';
|
|
28
|
+
import { fileURLToPath } from 'url';
|
|
29
|
+
import prebundleWorkers from 'vite-plugin-prebundle-workers';
|
|
30
|
+
import { SpecLoader, startSpecLoader } from './specs';
|
|
31
|
+
|
|
32
|
+
import type * as ReferenceSidebarsVirtualModule from 'virtual:stl-starlight-reference-sidebars';
|
|
33
|
+
import { generateMissingRouteList } from '@stainless-api/docs-ui/routing';
|
|
34
|
+
import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
26
35
|
|
|
27
36
|
export { generateAPILink } from './generateAPIReferenceLink';
|
|
28
37
|
export type { ReferenceSidebarConfigItem };
|
|
29
38
|
|
|
30
|
-
config(
|
|
39
|
+
config({
|
|
40
|
+
quiet: true,
|
|
41
|
+
});
|
|
31
42
|
|
|
32
43
|
let sidebarIdCounter = 0;
|
|
33
44
|
|
|
@@ -78,150 +89,217 @@ export function generateAPIReferenceItems(
|
|
|
78
89
|
return makePlaceholderItems(id);
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
function
|
|
82
|
-
if (specRetrieverConfig.kind === 'external_spec_server') {
|
|
83
|
-
throw new Error('External spec server is not yet supported');
|
|
84
|
-
}
|
|
85
|
-
if (specRetrieverConfig.kind === 'local_spec_server_with_files') {
|
|
86
|
-
if (!specRetrieverConfig.apiKey) {
|
|
87
|
-
throw new Error('API key is required');
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
apiKey: specRetrieverConfig.apiKey,
|
|
91
|
-
version: specRetrieverConfig.version,
|
|
92
|
-
devPaths: specRetrieverConfig.devPaths,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (specRetrieverConfig.kind === 'local_spec_server_with_remote_files') {
|
|
97
|
-
return {
|
|
98
|
-
apiKey: specRetrieverConfig.apiKey,
|
|
99
|
-
version: specRetrieverConfig.version,
|
|
100
|
-
devPaths: {
|
|
101
|
-
oasPath: undefined,
|
|
102
|
-
configPath: undefined,
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
throw new Error('Invalid spec retriever config');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async function stlStarlightAstroIntegration(
|
|
110
|
-
pluginConfig: NormalizedStainlessStarlightConfig,
|
|
111
|
-
): Promise<AstroIntegration> {
|
|
92
|
+
function stlStarlightAstroIntegration(pluginConfig: NormalizedStainlessStarlightConfig): AstroIntegration {
|
|
112
93
|
const virtualId = `virtual:stl-starlight-virtual-module`;
|
|
113
94
|
// The '\0' prefix tells Vite “this is a virtual module” and prevents it from being resolved again.
|
|
114
95
|
const resolvedId = `\0${virtualId}`;
|
|
96
|
+
let playgroundsBase: string | undefined;
|
|
97
|
+
let buildPlaygrounds: (args: unknown) => Promise<void> | undefined;
|
|
98
|
+
let astroBase = '/';
|
|
99
|
+
|
|
100
|
+
let specLoader: SpecLoader | undefined;
|
|
101
|
+
async function resolveSpecs() {
|
|
102
|
+
if (!specLoader) throw new Error('Expected spec loader to exist');
|
|
103
|
+
const result = await specLoader.specPromise;
|
|
104
|
+
return result.specComposite;
|
|
105
|
+
}
|
|
115
106
|
|
|
116
|
-
|
|
107
|
+
let building: Promise<void> | undefined;
|
|
108
|
+
let reportError: ((message: string) => void) | null = null;
|
|
109
|
+
let collectedErrors: string[] | null = null;
|
|
117
110
|
|
|
118
|
-
|
|
111
|
+
function startPlaygroundsBuild(playgroundsCachePath: string) {
|
|
112
|
+
if (!pluginConfig.experimentalPlaygrounds) return;
|
|
113
|
+
if (building) return building;
|
|
114
|
+
return (building = (async () => {
|
|
115
|
+
const specComposite = await resolveSpecs();
|
|
119
116
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
apiKey,
|
|
123
|
-
version,
|
|
124
|
-
devPaths,
|
|
125
|
-
getGeneratedSidebarConfig: (id: number) => {
|
|
126
|
-
const config = sidebarConfigs.get(id);
|
|
127
|
-
if (!config) {
|
|
128
|
-
return null;
|
|
117
|
+
if (specComposite.listUniqueSpecs().length > 1) {
|
|
118
|
+
throw new Error('Multiple specs found. This is not supported for Playgrounds.');
|
|
129
119
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
120
|
+
|
|
121
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
122
|
+
const auth = specComposite.listUniqueSpecs()[0]!.data.auth;
|
|
123
|
+
|
|
124
|
+
const langs = specComposite.getLanguages();
|
|
125
|
+
|
|
126
|
+
return buildPlaygrounds?.({
|
|
127
|
+
spec,
|
|
128
|
+
langs,
|
|
129
|
+
auth,
|
|
130
|
+
playPath: playgroundsCachePath,
|
|
131
|
+
reportError(message: string) {
|
|
132
|
+
(reportError ?? console.error)(message);
|
|
133
|
+
},
|
|
134
|
+
})?.catch(() => {
|
|
135
|
+
console.error('Failed to build playgrounds');
|
|
136
|
+
});
|
|
137
|
+
})());
|
|
138
|
+
}
|
|
133
139
|
|
|
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
|
+
createCodegenDir,
|
|
150
|
+
}) => {
|
|
151
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
138
152
|
const projectDir = astroConfig.root.pathname;
|
|
153
|
+
astroBase = astroConfig.base;
|
|
154
|
+
|
|
155
|
+
specLoader = await startSpecLoader(pluginConfig, logger, createCodegenDir());
|
|
156
|
+
|
|
157
|
+
reportError = (message: string) => logger.error(message);
|
|
158
|
+
|
|
159
|
+
if (pluginConfig.experimentalPlaygrounds) {
|
|
160
|
+
playgroundsBase = pluginConfig.experimentalPlaygrounds.playgroundsBase;
|
|
161
|
+
}
|
|
139
162
|
|
|
140
|
-
const
|
|
163
|
+
const middlewareFileBase = path.join(projectDir, 'middleware.stainless');
|
|
164
|
+
const middlewareFile = ['.tsx', '.ts']
|
|
165
|
+
.map((ext) => middlewareFileBase + ext)
|
|
166
|
+
.find((f) => fs.existsSync(f));
|
|
141
167
|
|
|
142
168
|
let vmMiddlewareExport = 'export const MIDDLEWARE = {};';
|
|
143
|
-
if (
|
|
144
|
-
logger.
|
|
169
|
+
if (middlewareFile) {
|
|
170
|
+
logger.debug(`Loading middleware from ${middlewareFile}`);
|
|
145
171
|
vmMiddlewareExport = `export { default as MIDDLEWARE } from '${middlewareFile}';`;
|
|
146
172
|
}
|
|
147
173
|
|
|
148
174
|
injectRoute({
|
|
149
|
-
pattern: `${pluginConfig.basePath}/[...slug].md`,
|
|
150
|
-
entrypoint: '
|
|
151
|
-
prerender: command === 'build',
|
|
175
|
+
pattern: `${pluginConfig.basePath}/[...slug]/index.md`,
|
|
176
|
+
entrypoint: resolveSrcFile('/plugin/routes/markdown.ts'),
|
|
177
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
152
178
|
});
|
|
153
179
|
|
|
154
|
-
const astroFile = command === 'build' ? '
|
|
180
|
+
const astroFile = command === 'build' ? 'DocsStatic' : 'Docs';
|
|
155
181
|
injectRoute({
|
|
156
182
|
pattern: `${pluginConfig.basePath}/[...slug]`,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
prerender: command === 'build',
|
|
183
|
+
entrypoint: resolveSrcFile(`/plugin/routes/${astroFile}.astro`),
|
|
184
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
160
185
|
});
|
|
161
186
|
|
|
162
187
|
injectRoute({
|
|
163
188
|
pattern: pluginConfig.basePath,
|
|
164
|
-
entrypoint: '
|
|
165
|
-
prerender: command === 'build',
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// Remove starlight callout syntax in favor of our own callout component
|
|
169
|
-
// updateConfig always deeply merges arrays so we need to mutate remarkPlugins directly
|
|
170
|
-
// in order to remove plugins that starlight added
|
|
171
|
-
astroConfig.markdown.remarkPlugins = astroConfig.markdown.remarkPlugins.filter((plugin, i, arr) => {
|
|
172
|
-
if (typeof plugin !== 'function') return true;
|
|
173
|
-
// remove:
|
|
174
|
-
// 1. remarkDirective plugin
|
|
175
|
-
if (plugin.name === 'remarkDirective') return false;
|
|
176
|
-
// 2. directly followed by remarkAsides plugin (inner function named 'attacher')
|
|
177
|
-
if (plugin.name === 'attacher') {
|
|
178
|
-
const prev = arr[i - 1];
|
|
179
|
-
if (typeof prev === 'function' && prev.name === 'remarkDirective') return false;
|
|
180
|
-
}
|
|
181
|
-
// 3. remarkDirectivesRestoration plugin
|
|
182
|
-
if (plugin.name === 'remarkDirectivesRestoration') return false;
|
|
183
|
-
return true;
|
|
189
|
+
entrypoint: resolveSrcFile('/plugin/routes/Overview.astro'),
|
|
190
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
184
191
|
});
|
|
185
192
|
|
|
186
193
|
updateConfig({
|
|
187
194
|
vite: {
|
|
188
|
-
ssr: {
|
|
189
|
-
noExternal: ['@stainless-api/ui-primitives'],
|
|
190
|
-
},
|
|
191
|
-
optimizeDeps: { include: ['@stainless-api/ui-primitives'] },
|
|
192
195
|
plugins: [
|
|
196
|
+
makeAsyncVirtualModPlugin<typeof ReferenceSidebarsVirtualModule>(
|
|
197
|
+
'virtual:stl-starlight-reference-sidebars',
|
|
198
|
+
async () => {
|
|
199
|
+
// we know specLoader exists here
|
|
200
|
+
const { specComposite } = await specLoader!.specPromise;
|
|
201
|
+
|
|
202
|
+
const sidebars = [...sidebarConfigs.entries()]
|
|
203
|
+
// produce all { id, language } combos with the attached config
|
|
204
|
+
// flattens to one item per language * id combo
|
|
205
|
+
.flatMap(([id, config]) =>
|
|
206
|
+
specComposite.listAllLanguagesAndIncludeSpecs().map((res) => ({
|
|
207
|
+
id,
|
|
208
|
+
config,
|
|
209
|
+
language: res.language,
|
|
210
|
+
spec: res.spec.data.sdkJson,
|
|
211
|
+
})),
|
|
212
|
+
)
|
|
213
|
+
// produce a sidebar for each
|
|
214
|
+
// later we will .find() the sidebar that matches the (id, language)
|
|
215
|
+
.map(({ id, config, language, spec }) => {
|
|
216
|
+
const configItemsBuilder = new SidebarConfigItemsBuilder(
|
|
217
|
+
spec,
|
|
218
|
+
language,
|
|
219
|
+
config.options,
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
let userSidebarConfig = configItemsBuilder.generateItems();
|
|
223
|
+
if (config.transformFn) {
|
|
224
|
+
const transformedSidebarConfig = config.transformFn(userSidebarConfig, language);
|
|
225
|
+
if (transformedSidebarConfig) userSidebarConfig = transformedSidebarConfig;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
id,
|
|
230
|
+
language,
|
|
231
|
+
// this has to run multpile times because it depends on the
|
|
232
|
+
// userSidebarConfig (which is per-id) and the language
|
|
233
|
+
entries: toStarlightSidebar({
|
|
234
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
235
|
+
spec,
|
|
236
|
+
entries: userSidebarConfig,
|
|
237
|
+
currentLanguage: language,
|
|
238
|
+
}),
|
|
239
|
+
};
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return { sidebars };
|
|
243
|
+
},
|
|
244
|
+
),
|
|
245
|
+
...specLoader.vitePlugins,
|
|
193
246
|
{
|
|
194
247
|
name: 'stl-starlight-vite',
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
server.
|
|
248
|
+
buildStart() {
|
|
249
|
+
building = undefined;
|
|
250
|
+
},
|
|
251
|
+
async configureServer(server) {
|
|
252
|
+
if (playgroundsBase) {
|
|
253
|
+
buildPlaygrounds = (await server.ssrLoadModule(playgroundsBase + '/src/build.ts'))
|
|
254
|
+
.buildPlaygrounds;
|
|
201
255
|
}
|
|
202
256
|
|
|
203
|
-
|
|
204
|
-
if (Object.values(devPaths).includes(changed)) {
|
|
205
|
-
logger.info(`${changed} changed, reloading...`);
|
|
206
|
-
cmsServer.invalidate();
|
|
207
|
-
server.hot.send({
|
|
208
|
-
type: 'full-reload',
|
|
209
|
-
path: '*',
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
});
|
|
257
|
+
// TODO: eventually - re-add support for watching local input changes (eg. reloading when OAS/config files change)
|
|
213
258
|
},
|
|
214
259
|
resolveId(id) {
|
|
215
260
|
if (id === virtualId) {
|
|
216
261
|
return resolvedId;
|
|
217
262
|
}
|
|
263
|
+
if (id === 'virtual:stl-playground/unstable-update-language') {
|
|
264
|
+
return resolveSrcFile('plugin/languages.ts');
|
|
265
|
+
}
|
|
266
|
+
if (id === 'virtual:stl-playground/create') {
|
|
267
|
+
return fileURLToPath(
|
|
268
|
+
new URL(
|
|
269
|
+
pluginConfig.experimentalPlaygrounds
|
|
270
|
+
? path.join(playgroundsBase!, '/src/create.tsx')
|
|
271
|
+
: './globalJs/create-playground.shim.ts',
|
|
272
|
+
import.meta.url,
|
|
273
|
+
),
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
if (id === 'virtual:stl-playground/data') {
|
|
277
|
+
return fileURLToPath(
|
|
278
|
+
new URL(
|
|
279
|
+
pluginConfig.experimentalPlaygrounds
|
|
280
|
+
? './globalJs/playground-data.ts'
|
|
281
|
+
: './globalJs/playground-data.shim.ts',
|
|
282
|
+
import.meta.url,
|
|
283
|
+
),
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
if (id.startsWith('virtual:stl-playground/')) {
|
|
287
|
+
const result = path.join(
|
|
288
|
+
this.environment.getTopLevelConfig().cacheDir,
|
|
289
|
+
'stl-playground',
|
|
290
|
+
id.slice('virtual:stl-playground/'.length),
|
|
291
|
+
);
|
|
292
|
+
const config = this.environment.getTopLevelConfig();
|
|
293
|
+
return startPlaygroundsBuild(path.join(config.cacheDir, 'stl-playground'))?.then(
|
|
294
|
+
() => result,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
218
297
|
},
|
|
219
298
|
load(id) {
|
|
220
299
|
if (id === resolvedId) {
|
|
221
300
|
return [
|
|
222
301
|
buildVirtualModuleString({
|
|
223
|
-
|
|
224
|
-
CMS_PORT,
|
|
302
|
+
RESOLVED_API_REFERENCE_PATH: path.posix.join(astroConfig.base, pluginConfig.basePath),
|
|
225
303
|
EXCLUDE_LANGUAGES: pluginConfig.excludeLanguages,
|
|
226
304
|
DEFAULT_LANGUAGE: pluginConfig.defaultLanguage,
|
|
227
305
|
BREADCRUMB_CONFIG: pluginConfig.breadcrumbs,
|
|
@@ -229,21 +307,86 @@ async function stlStarlightAstroIntegration(
|
|
|
229
307
|
HIGHLIGHT_THEMES: pluginConfig.highlighting.themes,
|
|
230
308
|
CONTENT_PANEL_LAYOUT: pluginConfig.contentPanel.layout,
|
|
231
309
|
EXPERIMENTAL_COLLAPSIBLE_SNIPPETS: pluginConfig.experimentalCollapsibleSnippets,
|
|
310
|
+
EXPERIMENTAL_COLLAPSIBLE_METHOD_DESCRIPTIONS:
|
|
311
|
+
pluginConfig.experimentalCollapsibleMethodDescriptions,
|
|
232
312
|
PROPERTY_SETTINGS: pluginConfig.propertySettings,
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
313
|
+
ENABLE_CONTEXT_MENU: pluginConfig.contextMenu,
|
|
314
|
+
EXPERIMENTAL_PLAYGROUNDS: !!pluginConfig.experimentalPlaygrounds,
|
|
315
|
+
EXPERIMENTAL_REQUEST_BUILDER: pluginConfig.experimentalRequestBuilder,
|
|
316
|
+
STAINLESS_PROJECT: pluginConfig.stainlessProject,
|
|
317
|
+
} satisfies Omit<typeof StlStarlightVirtualModule, 'MIDDLEWARE'>),
|
|
236
318
|
vmMiddlewareExport,
|
|
237
319
|
].join('\n');
|
|
238
320
|
}
|
|
239
321
|
},
|
|
240
322
|
},
|
|
323
|
+
prebundleWorkers({
|
|
324
|
+
include: [
|
|
325
|
+
'**/typescript/runner*',
|
|
326
|
+
'**/typescript/worker*',
|
|
327
|
+
'**/pyright.worker*',
|
|
328
|
+
'**/python/pyodide*',
|
|
329
|
+
],
|
|
330
|
+
configureEsBuild(_, opts) {
|
|
331
|
+
opts.external ??= [];
|
|
332
|
+
opts.external.push('url');
|
|
333
|
+
opts.loader ??= {};
|
|
334
|
+
opts.loader['.wasm'] = 'dataurl';
|
|
335
|
+
return opts;
|
|
336
|
+
},
|
|
337
|
+
}),
|
|
241
338
|
],
|
|
242
339
|
},
|
|
243
340
|
});
|
|
244
341
|
},
|
|
245
|
-
'astro:
|
|
246
|
-
|
|
342
|
+
'astro:build:start'({ logger }) {
|
|
343
|
+
collectedErrors = [];
|
|
344
|
+
reportError = (message: string) => {
|
|
345
|
+
logger.error(message);
|
|
346
|
+
collectedErrors!.push(message);
|
|
347
|
+
};
|
|
348
|
+
},
|
|
349
|
+
'astro:build:done': async ({ dir, logger }) => {
|
|
350
|
+
const dist = fileURLToPath(dir);
|
|
351
|
+
const stainlessDir = path.join(dist, '_stainless');
|
|
352
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
353
|
+
if (collectedErrors) {
|
|
354
|
+
for (const error of collectedErrors) {
|
|
355
|
+
logger.error(error);
|
|
356
|
+
}
|
|
357
|
+
collectedErrors = null;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const manifest = {
|
|
361
|
+
astroBase,
|
|
362
|
+
};
|
|
363
|
+
await writeFile(path.join(stainlessDir, 'stl-manifest.json'), JSON.stringify(manifest, null, 2));
|
|
364
|
+
|
|
365
|
+
const specComposite = await resolveSpecs();
|
|
366
|
+
|
|
367
|
+
await buildAlgoliaIndex({
|
|
368
|
+
specComposite,
|
|
369
|
+
logger,
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// Generate a list of missing API routes to enable graceful handling of unimplemented SDK methods.
|
|
373
|
+
// When users switch languages in the docs, some API methods may not be implemented in the target SDK.
|
|
374
|
+
// Instead of showing a generic 404, we statically generate pages for these routes and mark them
|
|
375
|
+
// in this file so Cloudflare can serve them with a 404 status. These pages display helpful information
|
|
376
|
+
// about the missing method and provide links to SDKs where it is available.
|
|
377
|
+
|
|
378
|
+
// TODO: (multi-spec) support multiple specs
|
|
379
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
380
|
+
|
|
381
|
+
const missingRoutes = generateMissingRouteList({
|
|
382
|
+
spec,
|
|
383
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
384
|
+
});
|
|
385
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
386
|
+
await writeFile(
|
|
387
|
+
path.join(stainlessDir, 'missing-routes.json'),
|
|
388
|
+
JSON.stringify(missingRoutes, null, 2),
|
|
389
|
+
);
|
|
247
390
|
},
|
|
248
391
|
},
|
|
249
392
|
};
|
|
@@ -253,24 +396,33 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
253
396
|
return {
|
|
254
397
|
name: 'stl-starlight',
|
|
255
398
|
hooks: {
|
|
256
|
-
'config:setup':
|
|
399
|
+
'config:setup': ({
|
|
257
400
|
addIntegration,
|
|
258
401
|
updateConfig,
|
|
259
402
|
addRouteMiddleware,
|
|
260
403
|
command,
|
|
261
404
|
config: starlightConfig,
|
|
262
405
|
astroConfig,
|
|
263
|
-
logger,
|
|
406
|
+
logger: localLogger,
|
|
264
407
|
}) => {
|
|
265
408
|
if (command !== 'build' && command !== 'dev') {
|
|
266
409
|
return;
|
|
267
410
|
}
|
|
268
411
|
|
|
269
|
-
const
|
|
412
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
413
|
+
|
|
414
|
+
const configParseResult = parseStarlightPluginConfig(someUserConfig, {
|
|
415
|
+
command,
|
|
416
|
+
base: astroConfig.base,
|
|
417
|
+
});
|
|
270
418
|
if (configParseResult.result === 'error') {
|
|
271
|
-
|
|
419
|
+
const errorLines = configParseResult.message.split('\n');
|
|
420
|
+
for (const line of errorLines) {
|
|
421
|
+
logger.error(line);
|
|
422
|
+
}
|
|
272
423
|
process.exit(1);
|
|
273
424
|
}
|
|
425
|
+
|
|
274
426
|
const config = configParseResult.config;
|
|
275
427
|
|
|
276
428
|
const isReactLoaded = astroConfig.integrations.find(({ name }) => name === '@astrojs/react');
|
|
@@ -279,42 +431,52 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
279
431
|
addIntegration(react());
|
|
280
432
|
}
|
|
281
433
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
434
|
+
// TODO: (multi-spec) re-add this? not strictly necessary to merge
|
|
435
|
+
// if ('apiKey' in config.specInputs) {
|
|
436
|
+
// if (!config.specInputs.apiKey) {
|
|
437
|
+
// logger.info(`Stainless credentials not loaded`);
|
|
438
|
+
// } else if (config.specInputs.apiKey.source === 'explicit-config') {
|
|
439
|
+
// logger.info(`Stainless credentials loaded from user config`);
|
|
440
|
+
// } else if (config.specInputs.apiKey.source === 'environment-variable') {
|
|
441
|
+
// logger.info('Stainless credentials loaded from `STAINLESS_API_KEY` environment variable');
|
|
442
|
+
// } else if (config.specInputs.apiKey.source === 'cli') {
|
|
443
|
+
// logger.info('Stainless credentials loaded from `stl` CLI');
|
|
444
|
+
// }
|
|
445
|
+
// })
|
|
293
446
|
|
|
294
447
|
if (starlightConfig.sidebar) {
|
|
295
448
|
// for pagination (https://starlight.astro.build/reference/configuration/#pagination) to work correctly
|
|
296
449
|
// update the placeholder link to be correct
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
450
|
+
for (const placeholder of getAPIReferencePlaceholderItemFromSidebarConfig(
|
|
451
|
+
starlightConfig.sidebar,
|
|
452
|
+
)) {
|
|
453
|
+
if (placeholder && typeof placeholder === 'object' && 'link' in placeholder) {
|
|
454
|
+
placeholder.link = config.basePath;
|
|
455
|
+
}
|
|
300
456
|
}
|
|
301
457
|
}
|
|
302
458
|
|
|
303
|
-
|
|
459
|
+
addIntegration(stlStarlightAstroIntegration(config));
|
|
460
|
+
|
|
461
|
+
const expressiveCodeConfig =
|
|
304
462
|
typeof starlightConfig.expressiveCode === 'object' ? starlightConfig.expressiveCode : {};
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
},
|
|
310
|
-
});
|
|
463
|
+
|
|
464
|
+
const themes = expressiveCodeConfig.themes
|
|
465
|
+
? expressiveCodeConfig.themes
|
|
466
|
+
: (['github-light', 'github-dark'] satisfies (typeof expressiveCodeConfig)['themes']);
|
|
311
467
|
|
|
312
468
|
updateConfig({
|
|
313
469
|
sidebar: starlightConfig.sidebar,
|
|
470
|
+
...(expressiveCodeConfig && {
|
|
471
|
+
expressiveCode: {
|
|
472
|
+
...expressiveCodeConfig,
|
|
473
|
+
themes,
|
|
474
|
+
},
|
|
475
|
+
}),
|
|
314
476
|
});
|
|
315
477
|
|
|
316
478
|
addRouteMiddleware({
|
|
317
|
-
entrypoint: '
|
|
479
|
+
entrypoint: resolveSrcFile('/plugin/replaceSidebarPlaceholderMiddleware.ts'),
|
|
318
480
|
order: 'post',
|
|
319
481
|
});
|
|
320
482
|
},
|
|
@@ -323,5 +485,7 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
323
485
|
}
|
|
324
486
|
|
|
325
487
|
// Additional exports we want for Stainless <-> docs integration.
|
|
326
|
-
export { parseStainlessPath } from '@stainless-api/docs-ui/
|
|
327
|
-
export { renderMarkdown } from '@stainless-api/docs-ui/
|
|
488
|
+
export { parseStainlessPath } from '@stainless-api/docs-ui/routing';
|
|
489
|
+
export { renderMarkdown } from '@stainless-api/docs-ui/markdown';
|
|
490
|
+
|
|
491
|
+
export { resolveSpec } from './specs/inputResolver';
|
package/plugin/languages.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DocsLanguage } from '@stainless-api/docs-ui/
|
|
1
|
+
import type { DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
2
2
|
import KotlinIcon from './assets/languages/kotlin.svg';
|
|
3
3
|
import RubyIcon from './assets/languages/ruby.svg';
|
|
4
4
|
import TerraformIcon from './assets/languages/terraform.svg';
|
|
@@ -7,6 +7,9 @@ import PythonIcon from './assets/languages/python.svg';
|
|
|
7
7
|
import JavaIcon from './assets/languages/java.svg';
|
|
8
8
|
import GoIcon from './assets/languages/go.svg';
|
|
9
9
|
import CurlIcon from './assets/languages/curl.svg';
|
|
10
|
+
import CSharpIcon from './assets/languages/csharp.svg';
|
|
11
|
+
import PHPIcon from './assets/languages/php.svg';
|
|
12
|
+
import CLIIcon from './assets/languages/cli.svg';
|
|
10
13
|
|
|
11
14
|
export const Languages: Record<
|
|
12
15
|
DocsLanguage,
|
|
@@ -29,6 +32,9 @@ export const Languages: Record<
|
|
|
29
32
|
http: { name: 'HTTP', icon: CurlIcon, alt: 'HTTP logo' },
|
|
30
33
|
terraform: { name: 'Terraform', icon: TerraformIcon, alt: 'Terraform logo' },
|
|
31
34
|
ruby: { name: 'Ruby', icon: RubyIcon, alt: 'Ruby logo' },
|
|
35
|
+
csharp: { name: 'C#', icon: CSharpIcon, alt: 'C# logo' },
|
|
36
|
+
cli: { name: 'CLI Tool', icon: CLIIcon, alt: 'CLI logo' },
|
|
37
|
+
php: { name: 'PHP', icon: PHPIcon, alt: 'PHP logo' },
|
|
32
38
|
};
|
|
33
39
|
|
|
34
40
|
export function generatePrefix(basePath: string, language: string) {
|
|
@@ -44,7 +50,7 @@ export function applyLanguageToLinks(basePath?: string, defaultLanguage?: string
|
|
|
44
50
|
`[data-stldocs-overview],[data-stldocs-method],a.nav-link[href^='${basePath}']`,
|
|
45
51
|
);
|
|
46
52
|
|
|
47
|
-
for (
|
|
53
|
+
for (const link of links) {
|
|
48
54
|
const href = link.getAttribute('href');
|
|
49
55
|
const prefix = generatePrefix(basePath, language);
|
|
50
56
|
if (href?.startsWith(basePath) && !href?.startsWith(prefix)) {
|