@stainless-api/docs 0.1.0-beta.9 → 0.1.0-beta.90
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 +748 -0
- package/eslint-suppressions.json +32 -0
- package/locals.d.ts +17 -0
- package/package.json +49 -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/buildAlgoliaIndex.ts +38 -11
- 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 +31 -0
- package/plugin/components/RequestBuilder/props.ts +9 -0
- package/plugin/components/RequestBuilder/spec-helpers.ts +50 -0
- package/plugin/components/RequestBuilder/styles.css +67 -0
- package/plugin/components/SDKSelect.astro +20 -104
- package/plugin/components/SnippetCode.tsx +111 -66
- package/plugin/components/StainlessIslands.tsx +126 -0
- package/plugin/components/search/SearchAlgolia.astro +45 -28
- 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 +15 -8
- package/plugin/globalJs/copy.ts +94 -17
- package/plugin/globalJs/create-playground.shim.ts +3 -0
- package/plugin/globalJs/method-descriptions.ts +33 -0
- package/plugin/globalJs/navigation.ts +10 -29
- package/plugin/globalJs/playground-data.shim.ts +1 -0
- package/plugin/globalJs/playground-data.ts +14 -0
- package/plugin/helpers/generateDocsRoutes.ts +27 -0
- package/plugin/helpers/getDocsLanguages.ts +9 -0
- package/plugin/index.ts +292 -116
- package/plugin/languages.ts +7 -2
- package/plugin/loadPluginConfig.ts +155 -79
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +1 -1
- package/plugin/react/Routing.tsx +204 -132
- package/plugin/referencePlaceholderUtils.ts +18 -15
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +38 -34
- package/plugin/routes/Docs.astro +65 -117
- package/plugin/routes/DocsStatic.astro +7 -4
- package/plugin/routes/Overview.astro +20 -24
- package/plugin/routes/markdown.ts +12 -11
- package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +30 -54
- package/plugin/specs/fetchSpecSSR.ts +21 -0
- package/plugin/specs/generateSpec.ts +50 -0
- package/plugin/specs/index.ts +238 -0
- package/plugin/{cms → specs}/worker.ts +82 -5
- package/plugin/vendor/preview.worker.docs.js +20928 -17830
- package/plugin/vendor/templates/go.md +1 -1
- package/plugin/vendor/templates/python.md +1 -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 +6 -8
- 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 -139
- package/stl-docs/components/content-panel/ContentPanel.astro +16 -46
- 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 +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/Accordion.astro +7 -5
- package/stl-docs/components/mintlify-compat/AccordionGroup.astro +7 -3
- 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 +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Check.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Danger.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Info.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Note.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Tip.astro +1 -1
- package/stl-docs/components/mintlify-compat/callouts/Warning.astro +1 -1
- 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 -70
- 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 +3 -2
- 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 +9 -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 +153 -50
- package/stl-docs/loadStlDocsConfig.ts +51 -7
- 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 +13 -4
- package/styles/code.css +128 -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 +11 -11
- package/tsconfig.json +2 -5
- package/virtual-module.d.ts +47 -7
- package/components/variables.css +0 -135
- 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/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
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 getPort from 'get-port';
|
|
6
|
-
import { startDevServer } from './cms/server';
|
|
7
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 { getDocsLanguages } from './helpers/getDocsLanguages';
|
|
36
|
+
import { generateMissingRouteList } from '@stainless-api/docs-ui/routing';
|
|
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,132 +91,216 @@ 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 getSpec() {
|
|
106
|
+
if (!specLoader) throw new Error('Expected spec loader to exist');
|
|
107
|
+
const result = await specLoader.specPromise;
|
|
108
|
+
return {
|
|
109
|
+
spec: result.spec.data,
|
|
110
|
+
auth: result.spec.auth,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
115
113
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
114
|
+
let building: Promise<void> | undefined;
|
|
115
|
+
let reportError: ((message: string) => void) | null = null;
|
|
116
|
+
let collectedErrors: string[] | null = null;
|
|
117
|
+
|
|
118
|
+
function startPlaygroundsBuild(playgroundsCachePath: string) {
|
|
119
|
+
if (!pluginConfig.experimentalPlaygrounds) return;
|
|
120
|
+
if (building) return building;
|
|
121
|
+
return (building = (async () => {
|
|
122
|
+
const { spec, auth } = await getSpec();
|
|
123
|
+
|
|
124
|
+
const langs = getDocsLanguages(spec, pluginConfig.excludeLanguages);
|
|
125
|
+
|
|
126
|
+
await buildPlaygrounds!({
|
|
127
|
+
spec,
|
|
128
|
+
langs,
|
|
129
|
+
auth,
|
|
130
|
+
playPath: playgroundsCachePath,
|
|
131
|
+
reportError(message: string) {
|
|
132
|
+
(reportError ?? console.error)(message);
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
})());
|
|
136
|
+
}
|
|
133
137
|
|
|
134
138
|
return {
|
|
135
139
|
name: 'stl-starlight-astro',
|
|
136
140
|
hooks: {
|
|
137
|
-
'astro:config:setup': async ({
|
|
141
|
+
'astro:config:setup': async ({
|
|
142
|
+
injectRoute,
|
|
143
|
+
updateConfig,
|
|
144
|
+
logger: localLogger,
|
|
145
|
+
command,
|
|
146
|
+
config: astroConfig,
|
|
147
|
+
createCodegenDir,
|
|
148
|
+
}) => {
|
|
149
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
138
150
|
const projectDir = astroConfig.root.pathname;
|
|
151
|
+
astroBase = astroConfig.base;
|
|
152
|
+
|
|
153
|
+
specLoader = await startSpecLoader(pluginConfig, logger, createCodegenDir());
|
|
154
|
+
specLoader.specPromise.then((specResult) => {
|
|
155
|
+
if (specResult.result === 'generated') {
|
|
156
|
+
logger.info(`Generated new SDKJSON`);
|
|
157
|
+
} else if (specResult.result === 'exists') {
|
|
158
|
+
logger.info(`Loaded SDKJSON`);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
reportError = (message: string) => logger.error(message);
|
|
163
|
+
|
|
164
|
+
if (pluginConfig.experimentalPlaygrounds) {
|
|
165
|
+
playgroundsBase = pluginConfig.experimentalPlaygrounds.playgroundsBase;
|
|
166
|
+
}
|
|
139
167
|
|
|
140
168
|
const middlewareFile = path.join(projectDir, 'middleware.stainless.ts');
|
|
141
169
|
|
|
142
170
|
let vmMiddlewareExport = 'export const MIDDLEWARE = {};';
|
|
143
171
|
if (fs.existsSync(middlewareFile)) {
|
|
144
|
-
logger.
|
|
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',
|
|
191
|
+
entrypoint: resolveSrcFile('/plugin/routes/Overview.astro'),
|
|
192
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
166
193
|
});
|
|
167
194
|
|
|
168
195
|
updateConfig({
|
|
169
196
|
vite: {
|
|
170
|
-
ssr: {
|
|
171
|
-
noExternal: ['@stainless-api/ui-primitives'],
|
|
172
|
-
},
|
|
173
|
-
optimizeDeps: { include: ['@stainless-api/ui-primitives'] },
|
|
174
197
|
plugins: [
|
|
198
|
+
makeAsyncVirtualModPlugin<typeof ReferenceSidebarsVirtualModule>(
|
|
199
|
+
'virtual:stl-starlight-reference-sidebars',
|
|
200
|
+
async () => {
|
|
201
|
+
const { spec } = await getSpec();
|
|
202
|
+
const languages = getDocsLanguages(spec, pluginConfig.excludeLanguages);
|
|
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
|
+
languages.map((language) => ({
|
|
209
|
+
id,
|
|
210
|
+
config,
|
|
211
|
+
language,
|
|
212
|
+
})),
|
|
213
|
+
)
|
|
214
|
+
// produce a sidebar for each
|
|
215
|
+
// later we will .find() the sidebar that matches the (id, language)
|
|
216
|
+
.map(({ id, config, language }) => {
|
|
217
|
+
const configItemsBuilder = new SidebarConfigItemsBuilder(
|
|
218
|
+
spec,
|
|
219
|
+
language,
|
|
220
|
+
config.options,
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
let userSidebarConfig = configItemsBuilder.generateItems();
|
|
224
|
+
if (config.transformFn) {
|
|
225
|
+
const transformedSidebarConfig = config.transformFn(userSidebarConfig, language);
|
|
226
|
+
if (transformedSidebarConfig) userSidebarConfig = transformedSidebarConfig;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
id,
|
|
231
|
+
language,
|
|
232
|
+
// this has to run multpile times because it depends on the
|
|
233
|
+
// userSidebarConfig (which is per-id) and the language
|
|
234
|
+
entries: toStarlightSidebar({
|
|
235
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath), // TODO, is this right?
|
|
236
|
+
spec,
|
|
237
|
+
entries: userSidebarConfig,
|
|
238
|
+
currentLanguage: language,
|
|
239
|
+
}),
|
|
240
|
+
};
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
return { sidebars };
|
|
244
|
+
},
|
|
245
|
+
),
|
|
246
|
+
specLoader.vitePlugin,
|
|
175
247
|
{
|
|
176
248
|
name: 'stl-starlight-vite',
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
server.
|
|
249
|
+
buildStart() {
|
|
250
|
+
building = undefined;
|
|
251
|
+
},
|
|
252
|
+
async configureServer(server) {
|
|
253
|
+
if (playgroundsBase) {
|
|
254
|
+
buildPlaygrounds = (await server.ssrLoadModule(playgroundsBase + '/src/build.ts'))
|
|
255
|
+
.buildPlaygrounds;
|
|
183
256
|
}
|
|
184
257
|
|
|
185
|
-
|
|
186
|
-
if (Object.values(devPaths).includes(changed)) {
|
|
187
|
-
logger.info(`${changed} changed, reloading...`);
|
|
188
|
-
cmsServer.invalidate();
|
|
189
|
-
server.hot.send({
|
|
190
|
-
type: 'full-reload',
|
|
191
|
-
path: '*',
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
});
|
|
258
|
+
// TODO: eventually - re-add support for watching local input changes (eg. reloading when OAS/config files change)
|
|
195
259
|
},
|
|
196
260
|
resolveId(id) {
|
|
197
261
|
if (id === virtualId) {
|
|
198
262
|
return resolvedId;
|
|
199
263
|
}
|
|
264
|
+
if (id === 'virtual:stl-playground/unstable-update-language') {
|
|
265
|
+
return resolveSrcFile('plugin/languages.ts');
|
|
266
|
+
}
|
|
267
|
+
if (id === 'virtual:stl-playground/create') {
|
|
268
|
+
return fileURLToPath(
|
|
269
|
+
new URL(
|
|
270
|
+
pluginConfig.experimentalPlaygrounds
|
|
271
|
+
? path.join(playgroundsBase!, '/src/create.tsx')
|
|
272
|
+
: './globalJs/create-playground.shim.ts',
|
|
273
|
+
import.meta.url,
|
|
274
|
+
),
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
if (id === 'virtual:stl-playground/data') {
|
|
278
|
+
return fileURLToPath(
|
|
279
|
+
new URL(
|
|
280
|
+
pluginConfig.experimentalPlaygrounds
|
|
281
|
+
? './globalJs/playground-data.ts'
|
|
282
|
+
: './globalJs/playground-data.shim.ts',
|
|
283
|
+
import.meta.url,
|
|
284
|
+
),
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
if (id.startsWith('virtual:stl-playground/')) {
|
|
288
|
+
const result = path.join(
|
|
289
|
+
this.environment.getTopLevelConfig().cacheDir,
|
|
290
|
+
'stl-playground',
|
|
291
|
+
id.slice('virtual:stl-playground/'.length),
|
|
292
|
+
);
|
|
293
|
+
const config = this.environment.getTopLevelConfig();
|
|
294
|
+
return startPlaygroundsBuild(path.join(config.cacheDir, 'stl-playground'))?.then(
|
|
295
|
+
() => result,
|
|
296
|
+
);
|
|
297
|
+
}
|
|
200
298
|
},
|
|
201
299
|
load(id) {
|
|
202
300
|
if (id === resolvedId) {
|
|
203
301
|
return [
|
|
204
302
|
buildVirtualModuleString({
|
|
205
|
-
|
|
206
|
-
CMS_PORT,
|
|
303
|
+
RESOLVED_API_REFERENCE_PATH: path.posix.join(astroConfig.base, pluginConfig.basePath),
|
|
207
304
|
EXCLUDE_LANGUAGES: pluginConfig.excludeLanguages,
|
|
208
305
|
DEFAULT_LANGUAGE: pluginConfig.defaultLanguage,
|
|
209
306
|
BREADCRUMB_CONFIG: pluginConfig.breadcrumbs,
|
|
@@ -211,21 +308,76 @@ async function stlStarlightAstroIntegration(
|
|
|
211
308
|
HIGHLIGHT_THEMES: pluginConfig.highlighting.themes,
|
|
212
309
|
CONTENT_PANEL_LAYOUT: pluginConfig.contentPanel.layout,
|
|
213
310
|
EXPERIMENTAL_COLLAPSIBLE_SNIPPETS: pluginConfig.experimentalCollapsibleSnippets,
|
|
311
|
+
EXPERIMENTAL_COLLAPSIBLE_METHOD_DESCRIPTIONS:
|
|
312
|
+
pluginConfig.experimentalCollapsibleMethodDescriptions,
|
|
214
313
|
PROPERTY_SETTINGS: pluginConfig.propertySettings,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
314
|
+
ENABLE_CONTEXT_MENU: pluginConfig.contextMenu,
|
|
315
|
+
EXPERIMENTAL_PLAYGROUNDS: !!pluginConfig.experimentalPlaygrounds,
|
|
316
|
+
EXPERIMENTAL_REQUEST_BUILDER: pluginConfig.experimentalRequestBuilder,
|
|
317
|
+
STAINLESS_PROJECT: pluginConfig.specInputs.project,
|
|
318
|
+
} satisfies Omit<typeof StlStarlightVirtualModule, 'MIDDLEWARE'>),
|
|
218
319
|
vmMiddlewareExport,
|
|
219
320
|
].join('\n');
|
|
220
321
|
}
|
|
221
322
|
},
|
|
222
323
|
},
|
|
324
|
+
prebundleWorkers({
|
|
325
|
+
include: [
|
|
326
|
+
'**/typescript/runner*',
|
|
327
|
+
'**/typescript/worker*',
|
|
328
|
+
'**/pyright.worker*',
|
|
329
|
+
'**/python/pyodide*',
|
|
330
|
+
],
|
|
331
|
+
configureEsBuild(_, opts) {
|
|
332
|
+
opts.external ??= [];
|
|
333
|
+
opts.external.push('url');
|
|
334
|
+
opts.loader ??= {};
|
|
335
|
+
opts.loader['.wasm'] = 'dataurl';
|
|
336
|
+
return opts;
|
|
337
|
+
},
|
|
338
|
+
}),
|
|
223
339
|
],
|
|
224
340
|
},
|
|
225
341
|
});
|
|
226
342
|
},
|
|
227
|
-
'astro:
|
|
228
|
-
|
|
343
|
+
'astro:build:start'({ logger }) {
|
|
344
|
+
collectedErrors = [];
|
|
345
|
+
reportError = (message: string) => {
|
|
346
|
+
logger.error(message);
|
|
347
|
+
collectedErrors!.push(message);
|
|
348
|
+
};
|
|
349
|
+
},
|
|
350
|
+
'astro:build:done': async ({ dir, logger }) => {
|
|
351
|
+
const dist = fileURLToPath(dir);
|
|
352
|
+
const stainlessDir = path.join(dist, '_stainless');
|
|
353
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
354
|
+
if (collectedErrors) {
|
|
355
|
+
for (const error of collectedErrors) {
|
|
356
|
+
logger.error(error);
|
|
357
|
+
}
|
|
358
|
+
collectedErrors = null;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const manifest = {
|
|
362
|
+
astroBase,
|
|
363
|
+
};
|
|
364
|
+
await writeFile(path.join(stainlessDir, 'stl-manifest.json'), JSON.stringify(manifest, null, 2));
|
|
365
|
+
|
|
366
|
+
// Generate a list of missing API routes to enable graceful handling of unimplemented SDK methods.
|
|
367
|
+
// When users switch languages in the docs, some API methods may not be implemented in the target SDK.
|
|
368
|
+
// Instead of showing a generic 404, we statically generate pages for these routes and mark them
|
|
369
|
+
// in this file so Cloudflare can serve them with a 404 status. These pages display helpful information
|
|
370
|
+
// about the missing method and provide links to SDKs where it is available.
|
|
371
|
+
const { spec } = await getSpec();
|
|
372
|
+
const missingRoutes = generateMissingRouteList({
|
|
373
|
+
spec,
|
|
374
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
375
|
+
});
|
|
376
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
377
|
+
await writeFile(
|
|
378
|
+
path.join(stainlessDir, 'missing-routes.json'),
|
|
379
|
+
JSON.stringify(missingRoutes, null, 2),
|
|
380
|
+
);
|
|
229
381
|
},
|
|
230
382
|
},
|
|
231
383
|
};
|
|
@@ -242,17 +394,23 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
242
394
|
command,
|
|
243
395
|
config: starlightConfig,
|
|
244
396
|
astroConfig,
|
|
245
|
-
logger,
|
|
397
|
+
logger: localLogger,
|
|
246
398
|
}) => {
|
|
247
399
|
if (command !== 'build' && command !== 'dev') {
|
|
248
400
|
return;
|
|
249
401
|
}
|
|
250
402
|
|
|
403
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
404
|
+
|
|
251
405
|
const configParseResult = parseStarlightPluginConfig(someUserConfig, command);
|
|
252
406
|
if (configParseResult.result === 'error') {
|
|
253
|
-
|
|
407
|
+
const errorLines = configParseResult.message.split('\n');
|
|
408
|
+
for (const line of errorLines) {
|
|
409
|
+
logger.error(line);
|
|
410
|
+
}
|
|
254
411
|
process.exit(1);
|
|
255
412
|
}
|
|
413
|
+
|
|
256
414
|
const config = configParseResult.config;
|
|
257
415
|
|
|
258
416
|
const isReactLoaded = astroConfig.integrations.find(({ name }) => name === '@astrojs/react');
|
|
@@ -261,42 +419,60 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
261
419
|
addIntegration(react());
|
|
262
420
|
}
|
|
263
421
|
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
422
|
+
if ('apiKey' in config.specInputs) {
|
|
423
|
+
if (!config.specInputs.apiKey) {
|
|
424
|
+
logger.info(`Stainless credentials not loaded`);
|
|
425
|
+
} else if (config.specInputs.apiKey.source === 'explicit-config') {
|
|
426
|
+
logger.info(`Stainless credentials loaded from user config`);
|
|
427
|
+
} else if (config.specInputs.apiKey.source === 'environment-variable') {
|
|
428
|
+
logger.info('Stainless credentials loaded from `STAINLESS_API_KEY` environment variable');
|
|
429
|
+
} else if (config.specInputs.apiKey.source === 'cli') {
|
|
430
|
+
logger.info('Stainless credentials loaded from `stl` CLI');
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (command === 'build' && config.specInputs.kind === 'stainless_api_inputs') {
|
|
268
435
|
await buildAlgoliaIndex({
|
|
269
|
-
|
|
270
|
-
|
|
436
|
+
stainlessProject: config.specInputs.project,
|
|
437
|
+
branch: config.specInputs.branch,
|
|
438
|
+
apiKey: config.specInputs.apiKey.value,
|
|
439
|
+
logger,
|
|
271
440
|
});
|
|
272
441
|
}
|
|
273
442
|
|
|
274
|
-
addIntegration(await stlStarlightAstroIntegration(config));
|
|
275
|
-
|
|
276
443
|
if (starlightConfig.sidebar) {
|
|
277
444
|
// for pagination (https://starlight.astro.build/reference/configuration/#pagination) to work correctly
|
|
278
445
|
// update the placeholder link to be correct
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
446
|
+
for (const placeholder of getAPIReferencePlaceholderItemFromSidebarConfig(
|
|
447
|
+
starlightConfig.sidebar,
|
|
448
|
+
)) {
|
|
449
|
+
if (placeholder && typeof placeholder === 'object' && 'link' in placeholder) {
|
|
450
|
+
placeholder.link = config.basePath;
|
|
451
|
+
}
|
|
282
452
|
}
|
|
283
453
|
}
|
|
284
454
|
|
|
285
|
-
|
|
455
|
+
addIntegration(await stlStarlightAstroIntegration(config));
|
|
456
|
+
|
|
457
|
+
const expressiveCodeConfig =
|
|
286
458
|
typeof starlightConfig.expressiveCode === 'object' ? starlightConfig.expressiveCode : {};
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
},
|
|
292
|
-
});
|
|
459
|
+
|
|
460
|
+
const themes = expressiveCodeConfig.themes
|
|
461
|
+
? (expressiveCodeConfig.themes as BundledTheme[])
|
|
462
|
+
: (['github-light', 'github-dark'] as BundledTheme[]);
|
|
293
463
|
|
|
294
464
|
updateConfig({
|
|
295
465
|
sidebar: starlightConfig.sidebar,
|
|
466
|
+
...(expressiveCodeConfig && {
|
|
467
|
+
expressiveCode: {
|
|
468
|
+
...expressiveCodeConfig,
|
|
469
|
+
themes,
|
|
470
|
+
},
|
|
471
|
+
}),
|
|
296
472
|
});
|
|
297
473
|
|
|
298
474
|
addRouteMiddleware({
|
|
299
|
-
entrypoint: '
|
|
475
|
+
entrypoint: resolveSrcFile('/plugin/replaceSidebarPlaceholderMiddleware.ts'),
|
|
300
476
|
order: 'post',
|
|
301
477
|
});
|
|
302
478
|
},
|
|
@@ -305,5 +481,5 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
305
481
|
}
|
|
306
482
|
|
|
307
483
|
// Additional exports we want for Stainless <-> docs integration.
|
|
308
|
-
export { parseStainlessPath } from '@stainless-api/docs-ui/
|
|
309
|
-
export { renderMarkdown } from '@stainless-api/docs-ui/
|
|
484
|
+
export { parseStainlessPath } from '@stainless-api/docs-ui/routing';
|
|
485
|
+
export { renderMarkdown } from '@stainless-api/docs-ui/markdown';
|
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,8 @@ 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 CLIIcon from './assets/languages/cli.svg';
|
|
10
12
|
|
|
11
13
|
export const Languages: Record<
|
|
12
14
|
DocsLanguage,
|
|
@@ -29,6 +31,9 @@ export const Languages: Record<
|
|
|
29
31
|
http: { name: 'HTTP', icon: CurlIcon, alt: 'HTTP logo' },
|
|
30
32
|
terraform: { name: 'Terraform', icon: TerraformIcon, alt: 'Terraform logo' },
|
|
31
33
|
ruby: { name: 'Ruby', icon: RubyIcon, alt: 'Ruby logo' },
|
|
34
|
+
csharp: { name: 'C#', icon: CSharpIcon, alt: 'C# logo' },
|
|
35
|
+
cli: { name: 'CLI Tool', icon: CLIIcon, alt: 'CLI logo' },
|
|
36
|
+
php: { name: 'PHP', icon: CSharpIcon, alt: 'PHP logo' }, // TODO update PHP icon
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
export function generatePrefix(basePath: string, language: string) {
|
|
@@ -44,7 +49,7 @@ export function applyLanguageToLinks(basePath?: string, defaultLanguage?: string
|
|
|
44
49
|
`[data-stldocs-overview],[data-stldocs-method],a.nav-link[href^='${basePath}']`,
|
|
45
50
|
);
|
|
46
51
|
|
|
47
|
-
for (
|
|
52
|
+
for (const link of links) {
|
|
48
53
|
const href = link.getAttribute('href');
|
|
49
54
|
const prefix = generatePrefix(basePath, language);
|
|
50
55
|
if (href?.startsWith(basePath) && !href?.startsWith(prefix)) {
|