@stainless-api/docs 0.1.0-beta.11 → 0.1.0-beta.110
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 +919 -0
- package/eslint-suppressions.json +27 -0
- package/locals.d.ts +17 -0
- package/package.json +50 -41
- 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 -111
- package/plugin/components/SnippetCode.tsx +110 -68
- package/plugin/components/StainlessIslands.tsx +126 -0
- package/plugin/components/search/SearchAlgolia.astro +46 -29
- 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 -32
- 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/multiSpec.ts +8 -0
- package/plugin/index.ts +304 -138
- 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 +212 -141
- package/plugin/referencePlaceholderUtils.ts +18 -15
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +38 -34
- package/plugin/routes/Docs.astro +70 -111
- package/plugin/routes/DocsStatic.astro +6 -5
- package/plugin/routes/Overview.astro +45 -21
- 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 +27303 -18260
- 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/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/content-panel/ContentPanel.astro +4 -64
- 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 +79 -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 +171 -51
- 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 +13 -4
- 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 +25 -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/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
|
@@ -1,33 +1,46 @@
|
|
|
1
1
|
import react from '@astrojs/react';
|
|
2
2
|
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
3
3
|
import type { AstroIntegration } from 'astro';
|
|
4
|
+
import type { BundledTheme } from 'shiki';
|
|
4
5
|
import { config } from 'dotenv';
|
|
5
|
-
import
|
|
6
|
-
import { startDevServer } from './cms/server';
|
|
7
|
-
import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
6
|
+
// import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
8
7
|
import {
|
|
9
8
|
getAPIReferencePlaceholderItemFromSidebarConfig,
|
|
10
9
|
makePlaceholderItems,
|
|
11
10
|
} from './referencePlaceholderUtils';
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
import {
|
|
12
|
+
SidebarConfigItemsBuilder,
|
|
13
|
+
toStarlightSidebar,
|
|
14
|
+
type GeneratedSidebarConfig,
|
|
15
|
+
type ReferenceSidebarConfigGenerateOptions,
|
|
16
|
+
type ReferenceSidebarConfigItem,
|
|
17
|
+
} from './sidebar-utils/sidebar-builder';
|
|
17
18
|
import {
|
|
18
19
|
parseStarlightPluginConfig,
|
|
19
20
|
type NormalizedStainlessStarlightConfig,
|
|
20
21
|
type SomeStainlessStarlightUserConfig,
|
|
21
|
-
type SpecRetrieverConfig,
|
|
22
22
|
} from './loadPluginConfig';
|
|
23
|
-
import { buildVirtualModuleString } from '../shared/virtualModule';
|
|
23
|
+
import { buildVirtualModuleString, makeAsyncVirtualModPlugin } from '../shared/virtualModule';
|
|
24
|
+
import type * as StlStarlightVirtualModule from 'virtual:stl-starlight-virtual-module';
|
|
24
25
|
import path from 'path';
|
|
25
26
|
import fs from 'fs';
|
|
27
|
+
import { getSharedLogger } from '../shared/getSharedLogger';
|
|
28
|
+
import { resolveSrcFile } from '../resolveSrcFile';
|
|
29
|
+
import { mkdir, writeFile } from 'fs/promises';
|
|
30
|
+
import { fileURLToPath } from 'url';
|
|
31
|
+
import prebundleWorkers from 'vite-plugin-prebundle-workers';
|
|
32
|
+
import { SpecLoader, startSpecLoader } from './specs';
|
|
33
|
+
|
|
34
|
+
import type * as ReferenceSidebarsVirtualModule from 'virtual:stl-starlight-reference-sidebars';
|
|
35
|
+
import { generateMissingRouteList } from '@stainless-api/docs-ui/routing';
|
|
36
|
+
import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
26
37
|
|
|
27
38
|
export { generateAPILink } from './generateAPIReferenceLink';
|
|
28
39
|
export type { ReferenceSidebarConfigItem };
|
|
29
40
|
|
|
30
|
-
config(
|
|
41
|
+
config({
|
|
42
|
+
quiet: true,
|
|
43
|
+
});
|
|
31
44
|
|
|
32
45
|
let sidebarIdCounter = 0;
|
|
33
46
|
|
|
@@ -78,150 +91,217 @@ export function generateAPIReferenceItems(
|
|
|
78
91
|
return makePlaceholderItems(id);
|
|
79
92
|
}
|
|
80
93
|
|
|
81
|
-
function tmpGetCMSServerConfig(specRetrieverConfig: SpecRetrieverConfig) {
|
|
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
94
|
async function stlStarlightAstroIntegration(
|
|
110
95
|
pluginConfig: NormalizedStainlessStarlightConfig,
|
|
111
96
|
): Promise<AstroIntegration> {
|
|
112
97
|
const virtualId = `virtual:stl-starlight-virtual-module`;
|
|
113
98
|
// The '\0' prefix tells Vite “this is a virtual module” and prevents it from being resolved again.
|
|
114
99
|
const resolvedId = `\0${virtualId}`;
|
|
100
|
+
let playgroundsBase: string | undefined;
|
|
101
|
+
let buildPlaygrounds;
|
|
102
|
+
let astroBase = '/';
|
|
103
|
+
|
|
104
|
+
let specLoader: SpecLoader | undefined;
|
|
105
|
+
async function resolveSpecs() {
|
|
106
|
+
if (!specLoader) throw new Error('Expected spec loader to exist');
|
|
107
|
+
const result = await specLoader.specPromise;
|
|
108
|
+
return result.specComposite;
|
|
109
|
+
}
|
|
115
110
|
|
|
116
|
-
|
|
111
|
+
let building: Promise<void> | undefined;
|
|
112
|
+
let reportError: ((message: string) => void) | null = null;
|
|
113
|
+
let collectedErrors: string[] | null = null;
|
|
117
114
|
|
|
118
|
-
|
|
115
|
+
function startPlaygroundsBuild(playgroundsCachePath: string) {
|
|
116
|
+
if (!pluginConfig.experimentalPlaygrounds) return;
|
|
117
|
+
if (building) return building;
|
|
118
|
+
return (building = (async () => {
|
|
119
|
+
const specComposite = await resolveSpecs();
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
apiKey,
|
|
123
|
-
version,
|
|
124
|
-
devPaths,
|
|
125
|
-
getGeneratedSidebarConfig: (id: number) => {
|
|
126
|
-
const config = sidebarConfigs.get(id);
|
|
127
|
-
if (!config) {
|
|
128
|
-
return null;
|
|
121
|
+
if (specComposite.listUniqueSpecs().length > 1) {
|
|
122
|
+
throw new Error('Multiple specs found. This is not supported for Playgrounds.');
|
|
129
123
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
124
|
+
|
|
125
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
126
|
+
const auth = specComposite.listUniqueSpecs()[0]!.data.auth;
|
|
127
|
+
|
|
128
|
+
const langs = specComposite.getLanguages();
|
|
129
|
+
|
|
130
|
+
await buildPlaygrounds!({
|
|
131
|
+
spec,
|
|
132
|
+
langs,
|
|
133
|
+
auth,
|
|
134
|
+
playPath: playgroundsCachePath,
|
|
135
|
+
reportError(message: string) {
|
|
136
|
+
(reportError ?? console.error)(message);
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
})());
|
|
140
|
+
}
|
|
133
141
|
|
|
134
142
|
return {
|
|
135
143
|
name: 'stl-starlight-astro',
|
|
136
144
|
hooks: {
|
|
137
|
-
'astro:config:setup': async ({
|
|
145
|
+
'astro:config:setup': async ({
|
|
146
|
+
injectRoute,
|
|
147
|
+
updateConfig,
|
|
148
|
+
logger: localLogger,
|
|
149
|
+
command,
|
|
150
|
+
config: astroConfig,
|
|
151
|
+
createCodegenDir,
|
|
152
|
+
}) => {
|
|
153
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
138
154
|
const projectDir = astroConfig.root.pathname;
|
|
155
|
+
astroBase = astroConfig.base;
|
|
139
156
|
|
|
140
|
-
|
|
157
|
+
specLoader = await startSpecLoader(pluginConfig, logger, createCodegenDir());
|
|
158
|
+
|
|
159
|
+
reportError = (message: string) => logger.error(message);
|
|
160
|
+
|
|
161
|
+
if (pluginConfig.experimentalPlaygrounds) {
|
|
162
|
+
playgroundsBase = pluginConfig.experimentalPlaygrounds.playgroundsBase;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const middlewareFileBase = path.join(projectDir, 'middleware.stainless');
|
|
166
|
+
const middlewareFile = ['.tsx', '.ts']
|
|
167
|
+
.map((ext) => middlewareFileBase + ext)
|
|
168
|
+
.find((f) => fs.existsSync(f));
|
|
141
169
|
|
|
142
170
|
let vmMiddlewareExport = 'export const MIDDLEWARE = {};';
|
|
143
|
-
if (
|
|
144
|
-
logger.
|
|
171
|
+
if (middlewareFile) {
|
|
172
|
+
logger.debug(`Loading middleware from ${middlewareFile}`);
|
|
145
173
|
vmMiddlewareExport = `export { default as MIDDLEWARE } from '${middlewareFile}';`;
|
|
146
174
|
}
|
|
147
175
|
|
|
148
176
|
injectRoute({
|
|
149
|
-
pattern: `${pluginConfig.basePath}/[...slug].md`,
|
|
150
|
-
entrypoint: '
|
|
151
|
-
prerender: command === 'build',
|
|
177
|
+
pattern: `${pluginConfig.basePath}/[...slug]/index.md`,
|
|
178
|
+
entrypoint: resolveSrcFile('/plugin/routes/markdown.ts'),
|
|
179
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
152
180
|
});
|
|
153
181
|
|
|
154
|
-
const astroFile = command === 'build' ? '
|
|
182
|
+
const astroFile = command === 'build' ? 'DocsStatic' : 'Docs';
|
|
155
183
|
injectRoute({
|
|
156
184
|
pattern: `${pluginConfig.basePath}/[...slug]`,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
prerender: command === 'build',
|
|
185
|
+
entrypoint: resolveSrcFile(`/plugin/routes/${astroFile}.astro`),
|
|
186
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
160
187
|
});
|
|
161
188
|
|
|
162
189
|
injectRoute({
|
|
163
190
|
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;
|
|
191
|
+
entrypoint: resolveSrcFile('/plugin/routes/Overview.astro'),
|
|
192
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
184
193
|
});
|
|
185
194
|
|
|
186
195
|
updateConfig({
|
|
187
196
|
vite: {
|
|
188
|
-
ssr: {
|
|
189
|
-
noExternal: ['@stainless-api/ui-primitives'],
|
|
190
|
-
},
|
|
191
|
-
optimizeDeps: { include: ['@stainless-api/ui-primitives'] },
|
|
192
197
|
plugins: [
|
|
198
|
+
makeAsyncVirtualModPlugin<typeof ReferenceSidebarsVirtualModule>(
|
|
199
|
+
'virtual:stl-starlight-reference-sidebars',
|
|
200
|
+
async () => {
|
|
201
|
+
// we know specLoader exists here
|
|
202
|
+
const { specComposite } = await specLoader!.specPromise;
|
|
203
|
+
|
|
204
|
+
const sidebars = [...sidebarConfigs.entries()]
|
|
205
|
+
// produce all { id, language } combos with the attached config
|
|
206
|
+
// flattens to one item per language * id combo
|
|
207
|
+
.flatMap(([id, config]) =>
|
|
208
|
+
specComposite.listAllLanguagesAndIncludeSpecs().map((res) => ({
|
|
209
|
+
id,
|
|
210
|
+
config,
|
|
211
|
+
language: res.language,
|
|
212
|
+
spec: res.spec.data.sdkJson,
|
|
213
|
+
})),
|
|
214
|
+
)
|
|
215
|
+
// produce a sidebar for each
|
|
216
|
+
// later we will .find() the sidebar that matches the (id, language)
|
|
217
|
+
.map(({ id, config, language, spec }) => {
|
|
218
|
+
const configItemsBuilder = new SidebarConfigItemsBuilder(
|
|
219
|
+
spec,
|
|
220
|
+
language,
|
|
221
|
+
config.options,
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
let userSidebarConfig = configItemsBuilder.generateItems();
|
|
225
|
+
if (config.transformFn) {
|
|
226
|
+
const transformedSidebarConfig = config.transformFn(userSidebarConfig, language);
|
|
227
|
+
if (transformedSidebarConfig) userSidebarConfig = transformedSidebarConfig;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
id,
|
|
232
|
+
language,
|
|
233
|
+
// this has to run multpile times because it depends on the
|
|
234
|
+
// userSidebarConfig (which is per-id) and the language
|
|
235
|
+
entries: toStarlightSidebar({
|
|
236
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
237
|
+
spec,
|
|
238
|
+
entries: userSidebarConfig,
|
|
239
|
+
currentLanguage: language,
|
|
240
|
+
}),
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
return { sidebars };
|
|
245
|
+
},
|
|
246
|
+
),
|
|
247
|
+
...specLoader.vitePlugins,
|
|
193
248
|
{
|
|
194
249
|
name: 'stl-starlight-vite',
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
server.
|
|
250
|
+
buildStart() {
|
|
251
|
+
building = undefined;
|
|
252
|
+
},
|
|
253
|
+
async configureServer(server) {
|
|
254
|
+
if (playgroundsBase) {
|
|
255
|
+
buildPlaygrounds = (await server.ssrLoadModule(playgroundsBase + '/src/build.ts'))
|
|
256
|
+
.buildPlaygrounds;
|
|
201
257
|
}
|
|
202
258
|
|
|
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
|
-
});
|
|
259
|
+
// TODO: eventually - re-add support for watching local input changes (eg. reloading when OAS/config files change)
|
|
213
260
|
},
|
|
214
261
|
resolveId(id) {
|
|
215
262
|
if (id === virtualId) {
|
|
216
263
|
return resolvedId;
|
|
217
264
|
}
|
|
265
|
+
if (id === 'virtual:stl-playground/unstable-update-language') {
|
|
266
|
+
return resolveSrcFile('plugin/languages.ts');
|
|
267
|
+
}
|
|
268
|
+
if (id === 'virtual:stl-playground/create') {
|
|
269
|
+
return fileURLToPath(
|
|
270
|
+
new URL(
|
|
271
|
+
pluginConfig.experimentalPlaygrounds
|
|
272
|
+
? path.join(playgroundsBase!, '/src/create.tsx')
|
|
273
|
+
: './globalJs/create-playground.shim.ts',
|
|
274
|
+
import.meta.url,
|
|
275
|
+
),
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
if (id === 'virtual:stl-playground/data') {
|
|
279
|
+
return fileURLToPath(
|
|
280
|
+
new URL(
|
|
281
|
+
pluginConfig.experimentalPlaygrounds
|
|
282
|
+
? './globalJs/playground-data.ts'
|
|
283
|
+
: './globalJs/playground-data.shim.ts',
|
|
284
|
+
import.meta.url,
|
|
285
|
+
),
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
if (id.startsWith('virtual:stl-playground/')) {
|
|
289
|
+
const result = path.join(
|
|
290
|
+
this.environment.getTopLevelConfig().cacheDir,
|
|
291
|
+
'stl-playground',
|
|
292
|
+
id.slice('virtual:stl-playground/'.length),
|
|
293
|
+
);
|
|
294
|
+
const config = this.environment.getTopLevelConfig();
|
|
295
|
+
return startPlaygroundsBuild(path.join(config.cacheDir, 'stl-playground'))?.then(
|
|
296
|
+
() => result,
|
|
297
|
+
);
|
|
298
|
+
}
|
|
218
299
|
},
|
|
219
300
|
load(id) {
|
|
220
301
|
if (id === resolvedId) {
|
|
221
302
|
return [
|
|
222
303
|
buildVirtualModuleString({
|
|
223
|
-
|
|
224
|
-
CMS_PORT,
|
|
304
|
+
RESOLVED_API_REFERENCE_PATH: path.posix.join(astroConfig.base, pluginConfig.basePath),
|
|
225
305
|
EXCLUDE_LANGUAGES: pluginConfig.excludeLanguages,
|
|
226
306
|
DEFAULT_LANGUAGE: pluginConfig.defaultLanguage,
|
|
227
307
|
BREADCRUMB_CONFIG: pluginConfig.breadcrumbs,
|
|
@@ -229,21 +309,86 @@ async function stlStarlightAstroIntegration(
|
|
|
229
309
|
HIGHLIGHT_THEMES: pluginConfig.highlighting.themes,
|
|
230
310
|
CONTENT_PANEL_LAYOUT: pluginConfig.contentPanel.layout,
|
|
231
311
|
EXPERIMENTAL_COLLAPSIBLE_SNIPPETS: pluginConfig.experimentalCollapsibleSnippets,
|
|
312
|
+
EXPERIMENTAL_COLLAPSIBLE_METHOD_DESCRIPTIONS:
|
|
313
|
+
pluginConfig.experimentalCollapsibleMethodDescriptions,
|
|
232
314
|
PROPERTY_SETTINGS: pluginConfig.propertySettings,
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
315
|
+
ENABLE_CONTEXT_MENU: pluginConfig.contextMenu,
|
|
316
|
+
EXPERIMENTAL_PLAYGROUNDS: !!pluginConfig.experimentalPlaygrounds,
|
|
317
|
+
EXPERIMENTAL_REQUEST_BUILDER: pluginConfig.experimentalRequestBuilder,
|
|
318
|
+
STAINLESS_PROJECT: pluginConfig.stainlessProject,
|
|
319
|
+
} satisfies Omit<typeof StlStarlightVirtualModule, 'MIDDLEWARE'>),
|
|
236
320
|
vmMiddlewareExport,
|
|
237
321
|
].join('\n');
|
|
238
322
|
}
|
|
239
323
|
},
|
|
240
324
|
},
|
|
325
|
+
prebundleWorkers({
|
|
326
|
+
include: [
|
|
327
|
+
'**/typescript/runner*',
|
|
328
|
+
'**/typescript/worker*',
|
|
329
|
+
'**/pyright.worker*',
|
|
330
|
+
'**/python/pyodide*',
|
|
331
|
+
],
|
|
332
|
+
configureEsBuild(_, opts) {
|
|
333
|
+
opts.external ??= [];
|
|
334
|
+
opts.external.push('url');
|
|
335
|
+
opts.loader ??= {};
|
|
336
|
+
opts.loader['.wasm'] = 'dataurl';
|
|
337
|
+
return opts;
|
|
338
|
+
},
|
|
339
|
+
}),
|
|
241
340
|
],
|
|
242
341
|
},
|
|
243
342
|
});
|
|
244
343
|
},
|
|
245
|
-
'astro:
|
|
246
|
-
|
|
344
|
+
'astro:build:start'({ logger }) {
|
|
345
|
+
collectedErrors = [];
|
|
346
|
+
reportError = (message: string) => {
|
|
347
|
+
logger.error(message);
|
|
348
|
+
collectedErrors!.push(message);
|
|
349
|
+
};
|
|
350
|
+
},
|
|
351
|
+
'astro:build:done': async ({ dir, logger }) => {
|
|
352
|
+
const dist = fileURLToPath(dir);
|
|
353
|
+
const stainlessDir = path.join(dist, '_stainless');
|
|
354
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
355
|
+
if (collectedErrors) {
|
|
356
|
+
for (const error of collectedErrors) {
|
|
357
|
+
logger.error(error);
|
|
358
|
+
}
|
|
359
|
+
collectedErrors = null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const manifest = {
|
|
363
|
+
astroBase,
|
|
364
|
+
};
|
|
365
|
+
await writeFile(path.join(stainlessDir, 'stl-manifest.json'), JSON.stringify(manifest, null, 2));
|
|
366
|
+
|
|
367
|
+
const specComposite = await resolveSpecs();
|
|
368
|
+
|
|
369
|
+
await buildAlgoliaIndex({
|
|
370
|
+
specComposite,
|
|
371
|
+
logger,
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// Generate a list of missing API routes to enable graceful handling of unimplemented SDK methods.
|
|
375
|
+
// When users switch languages in the docs, some API methods may not be implemented in the target SDK.
|
|
376
|
+
// Instead of showing a generic 404, we statically generate pages for these routes and mark them
|
|
377
|
+
// in this file so Cloudflare can serve them with a 404 status. These pages display helpful information
|
|
378
|
+
// about the missing method and provide links to SDKs where it is available.
|
|
379
|
+
|
|
380
|
+
// TODO: (multi-spec) support multiple specs
|
|
381
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
382
|
+
|
|
383
|
+
const missingRoutes = generateMissingRouteList({
|
|
384
|
+
spec,
|
|
385
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
386
|
+
});
|
|
387
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
388
|
+
await writeFile(
|
|
389
|
+
path.join(stainlessDir, 'missing-routes.json'),
|
|
390
|
+
JSON.stringify(missingRoutes, null, 2),
|
|
391
|
+
);
|
|
247
392
|
},
|
|
248
393
|
},
|
|
249
394
|
};
|
|
@@ -260,17 +405,26 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
260
405
|
command,
|
|
261
406
|
config: starlightConfig,
|
|
262
407
|
astroConfig,
|
|
263
|
-
logger,
|
|
408
|
+
logger: localLogger,
|
|
264
409
|
}) => {
|
|
265
410
|
if (command !== 'build' && command !== 'dev') {
|
|
266
411
|
return;
|
|
267
412
|
}
|
|
268
413
|
|
|
269
|
-
const
|
|
414
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
415
|
+
|
|
416
|
+
const configParseResult = parseStarlightPluginConfig(someUserConfig, {
|
|
417
|
+
command,
|
|
418
|
+
base: astroConfig.base,
|
|
419
|
+
});
|
|
270
420
|
if (configParseResult.result === 'error') {
|
|
271
|
-
|
|
421
|
+
const errorLines = configParseResult.message.split('\n');
|
|
422
|
+
for (const line of errorLines) {
|
|
423
|
+
logger.error(line);
|
|
424
|
+
}
|
|
272
425
|
process.exit(1);
|
|
273
426
|
}
|
|
427
|
+
|
|
274
428
|
const config = configParseResult.config;
|
|
275
429
|
|
|
276
430
|
const isReactLoaded = astroConfig.integrations.find(({ name }) => name === '@astrojs/react');
|
|
@@ -279,42 +433,52 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
279
433
|
addIntegration(react());
|
|
280
434
|
}
|
|
281
435
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
436
|
+
// TODO: (multi-spec) re-add this? not strictly necessary to merge
|
|
437
|
+
// if ('apiKey' in config.specInputs) {
|
|
438
|
+
// if (!config.specInputs.apiKey) {
|
|
439
|
+
// logger.info(`Stainless credentials not loaded`);
|
|
440
|
+
// } else if (config.specInputs.apiKey.source === 'explicit-config') {
|
|
441
|
+
// logger.info(`Stainless credentials loaded from user config`);
|
|
442
|
+
// } else if (config.specInputs.apiKey.source === 'environment-variable') {
|
|
443
|
+
// logger.info('Stainless credentials loaded from `STAINLESS_API_KEY` environment variable');
|
|
444
|
+
// } else if (config.specInputs.apiKey.source === 'cli') {
|
|
445
|
+
// logger.info('Stainless credentials loaded from `stl` CLI');
|
|
446
|
+
// }
|
|
447
|
+
// })
|
|
293
448
|
|
|
294
449
|
if (starlightConfig.sidebar) {
|
|
295
450
|
// for pagination (https://starlight.astro.build/reference/configuration/#pagination) to work correctly
|
|
296
451
|
// update the placeholder link to be correct
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
452
|
+
for (const placeholder of getAPIReferencePlaceholderItemFromSidebarConfig(
|
|
453
|
+
starlightConfig.sidebar,
|
|
454
|
+
)) {
|
|
455
|
+
if (placeholder && typeof placeholder === 'object' && 'link' in placeholder) {
|
|
456
|
+
placeholder.link = config.basePath;
|
|
457
|
+
}
|
|
300
458
|
}
|
|
301
459
|
}
|
|
302
460
|
|
|
303
|
-
|
|
461
|
+
addIntegration(await stlStarlightAstroIntegration(config));
|
|
462
|
+
|
|
463
|
+
const expressiveCodeConfig =
|
|
304
464
|
typeof starlightConfig.expressiveCode === 'object' ? starlightConfig.expressiveCode : {};
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
},
|
|
310
|
-
});
|
|
465
|
+
|
|
466
|
+
const themes = expressiveCodeConfig.themes
|
|
467
|
+
? (expressiveCodeConfig.themes as BundledTheme[])
|
|
468
|
+
: (['github-light', 'github-dark'] as BundledTheme[]);
|
|
311
469
|
|
|
312
470
|
updateConfig({
|
|
313
471
|
sidebar: starlightConfig.sidebar,
|
|
472
|
+
...(expressiveCodeConfig && {
|
|
473
|
+
expressiveCode: {
|
|
474
|
+
...expressiveCodeConfig,
|
|
475
|
+
themes,
|
|
476
|
+
},
|
|
477
|
+
}),
|
|
314
478
|
});
|
|
315
479
|
|
|
316
480
|
addRouteMiddleware({
|
|
317
|
-
entrypoint: '
|
|
481
|
+
entrypoint: resolveSrcFile('/plugin/replaceSidebarPlaceholderMiddleware.ts'),
|
|
318
482
|
order: 'post',
|
|
319
483
|
});
|
|
320
484
|
},
|
|
@@ -323,5 +487,7 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
323
487
|
}
|
|
324
488
|
|
|
325
489
|
// Additional exports we want for Stainless <-> docs integration.
|
|
326
|
-
export { parseStainlessPath } from '@stainless-api/docs-ui/
|
|
327
|
-
export { renderMarkdown } from '@stainless-api/docs-ui/
|
|
490
|
+
export { parseStainlessPath } from '@stainless-api/docs-ui/routing';
|
|
491
|
+
export { renderMarkdown } from '@stainless-api/docs-ui/markdown';
|
|
492
|
+
|
|
493
|
+
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)) {
|