@stainless-api/docs 0.1.0-beta.1 → 0.1.0-beta.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +917 -0
- package/eslint-suppressions.json +27 -0
- package/locals.d.ts +17 -0
- package/package.json +50 -40
- package/playground-virtual-modules.d.ts +96 -0
- package/plugin/assets/languages/cli.svg +14 -0
- package/plugin/assets/languages/csharp.svg +1 -0
- package/plugin/assets/languages/php.svg +4 -0
- package/plugin/buildAlgoliaIndex.ts +40 -39
- package/plugin/components/MethodDescription.tsx +54 -0
- package/plugin/components/RequestBuilder/ParamEditor.tsx +55 -0
- package/plugin/components/RequestBuilder/SnippetStainlessIsland.tsx +107 -0
- package/plugin/components/RequestBuilder/index.tsx +37 -0
- package/plugin/components/RequestBuilder/props.ts +9 -0
- package/plugin/components/RequestBuilder/spec-helpers.ts +47 -0
- package/plugin/components/RequestBuilder/styles.css +67 -0
- package/plugin/components/SDKSelect.astro +18 -105
- package/plugin/components/SnippetCode.tsx +111 -66
- package/plugin/components/StainlessIslands.tsx +126 -0
- package/plugin/components/search/SearchAlgolia.astro +45 -35
- package/plugin/components/search/SearchIsland.tsx +47 -29
- package/plugin/generateAPIReferenceLink.ts +2 -2
- package/plugin/globalJs/ai-dropdown-options.ts +243 -0
- package/plugin/globalJs/code-snippets.ts +40 -11
- package/plugin/globalJs/copy.ts +95 -17
- package/plugin/globalJs/create-playground.shim.ts +3 -0
- package/plugin/globalJs/method-descriptions.ts +33 -0
- package/plugin/globalJs/navigation.ts +12 -33
- package/plugin/globalJs/playground-data.shim.ts +1 -0
- package/plugin/globalJs/playground-data.ts +14 -0
- package/plugin/helpers/generateDocsRoutes.ts +59 -0
- package/plugin/helpers/getPageLoadEvent.ts +1 -1
- package/plugin/helpers/multiSpec.ts +8 -0
- package/plugin/index.ts +299 -117
- package/plugin/languages.ts +8 -2
- package/plugin/loadPluginConfig.ts +254 -102
- package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +1 -1
- package/plugin/react/Routing.tsx +210 -140
- package/plugin/referencePlaceholderUtils.ts +18 -15
- package/plugin/replaceSidebarPlaceholderMiddleware.ts +40 -32
- package/plugin/routes/Docs.astro +70 -119
- package/plugin/routes/DocsStatic.astro +6 -5
- package/plugin/routes/Overview.astro +37 -27
- package/plugin/routes/markdown.ts +13 -12
- package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +49 -60
- package/plugin/specs/FileCache.ts +99 -0
- package/plugin/specs/fetchSpecSSR.ts +27 -0
- package/plugin/specs/generateSpec.ts +112 -0
- package/plugin/specs/index.ts +132 -0
- package/plugin/specs/inputResolver.ts +146 -0
- package/plugin/{cms → specs}/worker.ts +82 -5
- package/plugin/vendor/preview.worker.docs.js +22406 -17955
- package/plugin/vendor/templates/cli.md +1 -0
- package/plugin/vendor/templates/go.md +4 -2
- package/plugin/vendor/templates/java.md +3 -1
- package/plugin/vendor/templates/kotlin.md +3 -1
- package/plugin/vendor/templates/node.md +4 -2
- package/plugin/vendor/templates/python.md +4 -2
- package/plugin/vendor/templates/ruby.md +4 -2
- package/plugin/vendor/templates/terraform.md +1 -1
- package/plugin/vendor/templates/typescript.md +3 -1
- package/resolveSrcFile.ts +10 -0
- package/scripts/vendor_deps.ts +5 -5
- package/shared/getProsePages.ts +42 -0
- package/shared/getSharedLogger.ts +15 -0
- package/shared/terminalUtils.ts +3 -0
- package/shared/virtualModule.ts +54 -1
- package/src/content.config.ts +9 -0
- package/stl-docs/components/AIDropdown.tsx +63 -0
- package/stl-docs/components/AiChatIsland.tsx +14 -0
- package/stl-docs/components/{content-panel/ContentBreadcrumbs.tsx → ContentBreadcrumbs.tsx} +2 -2
- package/stl-docs/components/Head.astro +20 -0
- package/stl-docs/components/Header.astro +7 -9
- package/stl-docs/components/PageFrame.astro +18 -0
- package/stl-docs/components/PageTitle.astro +82 -0
- package/stl-docs/components/TableOfContents.astro +34 -0
- package/stl-docs/components/ThemeProvider.astro +36 -0
- package/stl-docs/components/ThemeSelect.astro +84 -144
- package/stl-docs/components/content-panel/ContentPanel.astro +16 -46
- package/stl-docs/components/headers/DefaultHeader.astro +1 -1
- package/stl-docs/components/headers/HeaderLinks.astro +1 -1
- package/stl-docs/components/headers/SplashMobileMenuToggle.astro +17 -1
- package/stl-docs/components/headers/StackedHeader.astro +29 -24
- package/stl-docs/components/icons/chat-gpt.tsx +17 -0
- package/stl-docs/components/icons/claude.tsx +10 -0
- package/stl-docs/components/icons/cursor.tsx +10 -0
- package/stl-docs/components/icons/gemini.tsx +19 -0
- package/stl-docs/components/icons/markdown.tsx +10 -0
- package/stl-docs/components/index.ts +1 -0
- package/stl-docs/components/mintlify-compat/Accordion.astro +7 -38
- package/stl-docs/components/mintlify-compat/AccordionGroup.astro +9 -23
- package/stl-docs/components/mintlify-compat/Columns.astro +40 -42
- package/stl-docs/components/mintlify-compat/Frame.astro +16 -18
- package/stl-docs/components/mintlify-compat/callouts/Callout.astro +10 -3
- package/stl-docs/components/mintlify-compat/callouts/Check.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Danger.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Info.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Note.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Tip.astro +7 -3
- package/stl-docs/components/mintlify-compat/callouts/Warning.astro +7 -3
- package/stl-docs/components/mintlify-compat/card.css +33 -35
- package/stl-docs/components/mintlify-compat/index.ts +2 -4
- package/stl-docs/components/nav-tabs/NavDropdown.astro +31 -75
- package/stl-docs/components/nav-tabs/NavTabs.astro +78 -80
- package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -8
- package/stl-docs/components/nav-tabs/buildNavLinks.ts +4 -3
- package/stl-docs/components/pagination/HomeLink.astro +10 -0
- package/stl-docs/components/pagination/Pagination.astro +175 -0
- package/stl-docs/components/pagination/PaginationLinkEmphasized.astro +22 -0
- package/stl-docs/components/pagination/PaginationLinkQuiet.astro +13 -0
- package/stl-docs/components/pagination/util.ts +71 -0
- package/stl-docs/components/scripts.ts +1 -0
- package/stl-docs/components/sidebars/BaseSidebar.astro +87 -0
- package/stl-docs/components/sidebars/SDKSelectSidebar.astro +8 -0
- package/stl-docs/components/sidebars/SidebarWithComponents.tsx +10 -0
- package/stl-docs/components/sidebars/convertAstroSidebarToStl.tsx +62 -0
- package/stl-docs/disableCalloutSyntax.ts +36 -0
- package/stl-docs/fonts.ts +186 -0
- package/stl-docs/index.ts +159 -43
- package/stl-docs/loadStlDocsConfig.ts +60 -9
- package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +61 -0
- package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +41 -0
- package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
- package/stl-docs/proseSearchIndexing.ts +606 -0
- package/stl-docs/tabsMiddleware.ts +14 -5
- package/styles/code.css +133 -136
- package/styles/links.css +11 -48
- package/styles/method-descriptions.css +36 -0
- package/styles/overrides.css +49 -57
- package/styles/page.css +100 -59
- package/styles/sdk_select.css +9 -7
- package/styles/search.css +57 -69
- package/styles/sidebar.css +26 -156
- package/styles/{variables.css → sl-variables.css} +3 -2
- package/styles/stldocs-variables.css +6 -0
- package/styles/toc.css +41 -34
- package/theme.css +13 -3
- package/tsconfig.json +2 -5
- package/virtual-module.d.ts +65 -7
- package/components/variables.css +0 -139
- package/plugin/cms/client.ts +0 -62
- package/plugin/cms/server.ts +0 -268
- package/plugin/globalJs/ai-dropdown.ts +0 -57
- package/stl-docs/components/APIReferenceAIDropdown.tsx +0 -86
- package/stl-docs/components/Sidebar.astro +0 -11
- package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -64
- package/stl-docs/components/mintlify-compat/Step.astro +0 -58
- package/stl-docs/components/mintlify-compat/Steps.astro +0 -17
- package/styles/fonts.css +0 -68
- /package/{plugin/assets → assets}/fonts/geist/OFL.txt +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin-ext.woff2 +0 -0
- /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin.woff2 +0 -0
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,132 +91,214 @@ 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;
|
|
156
|
+
|
|
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
|
+
}
|
|
139
164
|
|
|
140
165
|
const middlewareFile = path.join(projectDir, 'middleware.stainless.ts');
|
|
141
166
|
|
|
142
167
|
let vmMiddlewareExport = 'export const MIDDLEWARE = {};';
|
|
143
168
|
if (fs.existsSync(middlewareFile)) {
|
|
144
|
-
logger.
|
|
169
|
+
logger.debug(`Loading middleware from ${middlewareFile}`);
|
|
145
170
|
vmMiddlewareExport = `export { default as MIDDLEWARE } from '${middlewareFile}';`;
|
|
146
171
|
}
|
|
147
172
|
|
|
148
173
|
injectRoute({
|
|
149
|
-
pattern: `${pluginConfig.basePath}/[...slug].md`,
|
|
150
|
-
entrypoint: '
|
|
151
|
-
prerender: command === 'build',
|
|
174
|
+
pattern: `${pluginConfig.basePath}/[...slug]/index.md`,
|
|
175
|
+
entrypoint: resolveSrcFile('/plugin/routes/markdown.ts'),
|
|
176
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
152
177
|
});
|
|
153
178
|
|
|
154
|
-
const astroFile = command === 'build' ? '
|
|
179
|
+
const astroFile = command === 'build' ? 'DocsStatic' : 'Docs';
|
|
155
180
|
injectRoute({
|
|
156
181
|
pattern: `${pluginConfig.basePath}/[...slug]`,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
prerender: command === 'build',
|
|
182
|
+
entrypoint: resolveSrcFile(`/plugin/routes/${astroFile}.astro`),
|
|
183
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
160
184
|
});
|
|
161
185
|
|
|
162
186
|
injectRoute({
|
|
163
187
|
pattern: pluginConfig.basePath,
|
|
164
|
-
entrypoint: '
|
|
165
|
-
prerender: command === 'build',
|
|
188
|
+
entrypoint: resolveSrcFile('/plugin/routes/Overview.astro'),
|
|
189
|
+
prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
|
|
166
190
|
});
|
|
167
191
|
|
|
168
192
|
updateConfig({
|
|
169
193
|
vite: {
|
|
170
|
-
ssr: {
|
|
171
|
-
noExternal: ['@stainless-api/ui-primitives'],
|
|
172
|
-
},
|
|
173
|
-
optimizeDeps: { include: ['@stainless-api/ui-primitives'] },
|
|
174
194
|
plugins: [
|
|
195
|
+
makeAsyncVirtualModPlugin<typeof ReferenceSidebarsVirtualModule>(
|
|
196
|
+
'virtual:stl-starlight-reference-sidebars',
|
|
197
|
+
async () => {
|
|
198
|
+
// we know specLoader exists here
|
|
199
|
+
const { specComposite } = await specLoader!.specPromise;
|
|
200
|
+
|
|
201
|
+
const sidebars = [...sidebarConfigs.entries()]
|
|
202
|
+
// produce all { id, language } combos with the attached config
|
|
203
|
+
// flattens to one item per language * id combo
|
|
204
|
+
.flatMap(([id, config]) =>
|
|
205
|
+
specComposite.listAllLanguagesAndIncludeSpecs().map((res) => ({
|
|
206
|
+
id,
|
|
207
|
+
config,
|
|
208
|
+
language: res.language,
|
|
209
|
+
spec: res.spec.data.sdkJson,
|
|
210
|
+
})),
|
|
211
|
+
)
|
|
212
|
+
// produce a sidebar for each
|
|
213
|
+
// later we will .find() the sidebar that matches the (id, language)
|
|
214
|
+
.map(({ id, config, language, spec }) => {
|
|
215
|
+
const configItemsBuilder = new SidebarConfigItemsBuilder(
|
|
216
|
+
spec,
|
|
217
|
+
language,
|
|
218
|
+
config.options,
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
let userSidebarConfig = configItemsBuilder.generateItems();
|
|
222
|
+
if (config.transformFn) {
|
|
223
|
+
const transformedSidebarConfig = config.transformFn(userSidebarConfig, language);
|
|
224
|
+
if (transformedSidebarConfig) userSidebarConfig = transformedSidebarConfig;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
id,
|
|
229
|
+
language,
|
|
230
|
+
// this has to run multpile times because it depends on the
|
|
231
|
+
// userSidebarConfig (which is per-id) and the language
|
|
232
|
+
entries: toStarlightSidebar({
|
|
233
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
234
|
+
spec,
|
|
235
|
+
entries: userSidebarConfig,
|
|
236
|
+
currentLanguage: language,
|
|
237
|
+
}),
|
|
238
|
+
};
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return { sidebars };
|
|
242
|
+
},
|
|
243
|
+
),
|
|
244
|
+
...specLoader.vitePlugins,
|
|
175
245
|
{
|
|
176
246
|
name: 'stl-starlight-vite',
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
server.
|
|
247
|
+
buildStart() {
|
|
248
|
+
building = undefined;
|
|
249
|
+
},
|
|
250
|
+
async configureServer(server) {
|
|
251
|
+
if (playgroundsBase) {
|
|
252
|
+
buildPlaygrounds = (await server.ssrLoadModule(playgroundsBase + '/src/build.ts'))
|
|
253
|
+
.buildPlaygrounds;
|
|
183
254
|
}
|
|
184
255
|
|
|
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
|
-
});
|
|
256
|
+
// TODO: eventually - re-add support for watching local input changes (eg. reloading when OAS/config files change)
|
|
195
257
|
},
|
|
196
258
|
resolveId(id) {
|
|
197
259
|
if (id === virtualId) {
|
|
198
260
|
return resolvedId;
|
|
199
261
|
}
|
|
262
|
+
if (id === 'virtual:stl-playground/unstable-update-language') {
|
|
263
|
+
return resolveSrcFile('plugin/languages.ts');
|
|
264
|
+
}
|
|
265
|
+
if (id === 'virtual:stl-playground/create') {
|
|
266
|
+
return fileURLToPath(
|
|
267
|
+
new URL(
|
|
268
|
+
pluginConfig.experimentalPlaygrounds
|
|
269
|
+
? path.join(playgroundsBase!, '/src/create.tsx')
|
|
270
|
+
: './globalJs/create-playground.shim.ts',
|
|
271
|
+
import.meta.url,
|
|
272
|
+
),
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
if (id === 'virtual:stl-playground/data') {
|
|
276
|
+
return fileURLToPath(
|
|
277
|
+
new URL(
|
|
278
|
+
pluginConfig.experimentalPlaygrounds
|
|
279
|
+
? './globalJs/playground-data.ts'
|
|
280
|
+
: './globalJs/playground-data.shim.ts',
|
|
281
|
+
import.meta.url,
|
|
282
|
+
),
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
if (id.startsWith('virtual:stl-playground/')) {
|
|
286
|
+
const result = path.join(
|
|
287
|
+
this.environment.getTopLevelConfig().cacheDir,
|
|
288
|
+
'stl-playground',
|
|
289
|
+
id.slice('virtual:stl-playground/'.length),
|
|
290
|
+
);
|
|
291
|
+
const config = this.environment.getTopLevelConfig();
|
|
292
|
+
return startPlaygroundsBuild(path.join(config.cacheDir, 'stl-playground'))?.then(
|
|
293
|
+
() => result,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
200
296
|
},
|
|
201
297
|
load(id) {
|
|
202
298
|
if (id === resolvedId) {
|
|
203
299
|
return [
|
|
204
300
|
buildVirtualModuleString({
|
|
205
|
-
|
|
206
|
-
CMS_PORT,
|
|
301
|
+
RESOLVED_API_REFERENCE_PATH: path.posix.join(astroConfig.base, pluginConfig.basePath),
|
|
207
302
|
EXCLUDE_LANGUAGES: pluginConfig.excludeLanguages,
|
|
208
303
|
DEFAULT_LANGUAGE: pluginConfig.defaultLanguage,
|
|
209
304
|
BREADCRUMB_CONFIG: pluginConfig.breadcrumbs,
|
|
@@ -211,20 +306,86 @@ async function stlStarlightAstroIntegration(
|
|
|
211
306
|
HIGHLIGHT_THEMES: pluginConfig.highlighting.themes,
|
|
212
307
|
CONTENT_PANEL_LAYOUT: pluginConfig.contentPanel.layout,
|
|
213
308
|
EXPERIMENTAL_COLLAPSIBLE_SNIPPETS: pluginConfig.experimentalCollapsibleSnippets,
|
|
309
|
+
EXPERIMENTAL_COLLAPSIBLE_METHOD_DESCRIPTIONS:
|
|
310
|
+
pluginConfig.experimentalCollapsibleMethodDescriptions,
|
|
214
311
|
PROPERTY_SETTINGS: pluginConfig.propertySettings,
|
|
215
|
-
|
|
216
|
-
|
|
312
|
+
ENABLE_CONTEXT_MENU: pluginConfig.contextMenu,
|
|
313
|
+
EXPERIMENTAL_PLAYGROUNDS: !!pluginConfig.experimentalPlaygrounds,
|
|
314
|
+
EXPERIMENTAL_REQUEST_BUILDER: pluginConfig.experimentalRequestBuilder,
|
|
315
|
+
STAINLESS_PROJECT: pluginConfig.stainlessProject,
|
|
316
|
+
} satisfies Omit<typeof StlStarlightVirtualModule, 'MIDDLEWARE'>),
|
|
217
317
|
vmMiddlewareExport,
|
|
218
318
|
].join('\n');
|
|
219
319
|
}
|
|
220
320
|
},
|
|
221
321
|
},
|
|
322
|
+
prebundleWorkers({
|
|
323
|
+
include: [
|
|
324
|
+
'**/typescript/runner*',
|
|
325
|
+
'**/typescript/worker*',
|
|
326
|
+
'**/pyright.worker*',
|
|
327
|
+
'**/python/pyodide*',
|
|
328
|
+
],
|
|
329
|
+
configureEsBuild(_, opts) {
|
|
330
|
+
opts.external ??= [];
|
|
331
|
+
opts.external.push('url');
|
|
332
|
+
opts.loader ??= {};
|
|
333
|
+
opts.loader['.wasm'] = 'dataurl';
|
|
334
|
+
return opts;
|
|
335
|
+
},
|
|
336
|
+
}),
|
|
222
337
|
],
|
|
223
338
|
},
|
|
224
339
|
});
|
|
225
340
|
},
|
|
226
|
-
'astro:
|
|
227
|
-
|
|
341
|
+
'astro:build:start'({ logger }) {
|
|
342
|
+
collectedErrors = [];
|
|
343
|
+
reportError = (message: string) => {
|
|
344
|
+
logger.error(message);
|
|
345
|
+
collectedErrors!.push(message);
|
|
346
|
+
};
|
|
347
|
+
},
|
|
348
|
+
'astro:build:done': async ({ dir, logger }) => {
|
|
349
|
+
const dist = fileURLToPath(dir);
|
|
350
|
+
const stainlessDir = path.join(dist, '_stainless');
|
|
351
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
352
|
+
if (collectedErrors) {
|
|
353
|
+
for (const error of collectedErrors) {
|
|
354
|
+
logger.error(error);
|
|
355
|
+
}
|
|
356
|
+
collectedErrors = null;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const manifest = {
|
|
360
|
+
astroBase,
|
|
361
|
+
};
|
|
362
|
+
await writeFile(path.join(stainlessDir, 'stl-manifest.json'), JSON.stringify(manifest, null, 2));
|
|
363
|
+
|
|
364
|
+
const specComposite = await resolveSpecs();
|
|
365
|
+
|
|
366
|
+
await buildAlgoliaIndex({
|
|
367
|
+
specComposite,
|
|
368
|
+
logger,
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Generate a list of missing API routes to enable graceful handling of unimplemented SDK methods.
|
|
372
|
+
// When users switch languages in the docs, some API methods may not be implemented in the target SDK.
|
|
373
|
+
// Instead of showing a generic 404, we statically generate pages for these routes and mark them
|
|
374
|
+
// in this file so Cloudflare can serve them with a 404 status. These pages display helpful information
|
|
375
|
+
// about the missing method and provide links to SDKs where it is available.
|
|
376
|
+
|
|
377
|
+
// TODO: (multi-spec) support multiple specs
|
|
378
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
379
|
+
|
|
380
|
+
const missingRoutes = generateMissingRouteList({
|
|
381
|
+
spec,
|
|
382
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
383
|
+
});
|
|
384
|
+
await mkdir(stainlessDir, { recursive: true });
|
|
385
|
+
await writeFile(
|
|
386
|
+
path.join(stainlessDir, 'missing-routes.json'),
|
|
387
|
+
JSON.stringify(missingRoutes, null, 2),
|
|
388
|
+
);
|
|
228
389
|
},
|
|
229
390
|
},
|
|
230
391
|
};
|
|
@@ -241,17 +402,26 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
241
402
|
command,
|
|
242
403
|
config: starlightConfig,
|
|
243
404
|
astroConfig,
|
|
244
|
-
logger,
|
|
405
|
+
logger: localLogger,
|
|
245
406
|
}) => {
|
|
246
407
|
if (command !== 'build' && command !== 'dev') {
|
|
247
408
|
return;
|
|
248
409
|
}
|
|
249
410
|
|
|
250
|
-
const
|
|
411
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
412
|
+
|
|
413
|
+
const configParseResult = parseStarlightPluginConfig(someUserConfig, {
|
|
414
|
+
command,
|
|
415
|
+
base: astroConfig.base,
|
|
416
|
+
});
|
|
251
417
|
if (configParseResult.result === 'error') {
|
|
252
|
-
|
|
418
|
+
const errorLines = configParseResult.message.split('\n');
|
|
419
|
+
for (const line of errorLines) {
|
|
420
|
+
logger.error(line);
|
|
421
|
+
}
|
|
253
422
|
process.exit(1);
|
|
254
423
|
}
|
|
424
|
+
|
|
255
425
|
const config = configParseResult.config;
|
|
256
426
|
|
|
257
427
|
const isReactLoaded = astroConfig.integrations.find(({ name }) => name === '@astrojs/react');
|
|
@@ -260,42 +430,52 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
260
430
|
addIntegration(react());
|
|
261
431
|
}
|
|
262
432
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
|
|
433
|
+
// TODO: (multi-spec) re-add this? not strictly necessary to merge
|
|
434
|
+
// if ('apiKey' in config.specInputs) {
|
|
435
|
+
// if (!config.specInputs.apiKey) {
|
|
436
|
+
// logger.info(`Stainless credentials not loaded`);
|
|
437
|
+
// } else if (config.specInputs.apiKey.source === 'explicit-config') {
|
|
438
|
+
// logger.info(`Stainless credentials loaded from user config`);
|
|
439
|
+
// } else if (config.specInputs.apiKey.source === 'environment-variable') {
|
|
440
|
+
// logger.info('Stainless credentials loaded from `STAINLESS_API_KEY` environment variable');
|
|
441
|
+
// } else if (config.specInputs.apiKey.source === 'cli') {
|
|
442
|
+
// logger.info('Stainless credentials loaded from `stl` CLI');
|
|
443
|
+
// }
|
|
444
|
+
// })
|
|
274
445
|
|
|
275
446
|
if (starlightConfig.sidebar) {
|
|
276
447
|
// for pagination (https://starlight.astro.build/reference/configuration/#pagination) to work correctly
|
|
277
448
|
// update the placeholder link to be correct
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
449
|
+
for (const placeholder of getAPIReferencePlaceholderItemFromSidebarConfig(
|
|
450
|
+
starlightConfig.sidebar,
|
|
451
|
+
)) {
|
|
452
|
+
if (placeholder && typeof placeholder === 'object' && 'link' in placeholder) {
|
|
453
|
+
placeholder.link = config.basePath;
|
|
454
|
+
}
|
|
281
455
|
}
|
|
282
456
|
}
|
|
283
457
|
|
|
284
|
-
|
|
458
|
+
addIntegration(await stlStarlightAstroIntegration(config));
|
|
459
|
+
|
|
460
|
+
const expressiveCodeConfig =
|
|
285
461
|
typeof starlightConfig.expressiveCode === 'object' ? starlightConfig.expressiveCode : {};
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
},
|
|
291
|
-
});
|
|
462
|
+
|
|
463
|
+
const themes = expressiveCodeConfig.themes
|
|
464
|
+
? (expressiveCodeConfig.themes as BundledTheme[])
|
|
465
|
+
: (['github-light', 'github-dark'] as BundledTheme[]);
|
|
292
466
|
|
|
293
467
|
updateConfig({
|
|
294
468
|
sidebar: starlightConfig.sidebar,
|
|
469
|
+
...(expressiveCodeConfig && {
|
|
470
|
+
expressiveCode: {
|
|
471
|
+
...expressiveCodeConfig,
|
|
472
|
+
themes,
|
|
473
|
+
},
|
|
474
|
+
}),
|
|
295
475
|
});
|
|
296
476
|
|
|
297
477
|
addRouteMiddleware({
|
|
298
|
-
entrypoint: '
|
|
478
|
+
entrypoint: resolveSrcFile('/plugin/replaceSidebarPlaceholderMiddleware.ts'),
|
|
299
479
|
order: 'post',
|
|
300
480
|
});
|
|
301
481
|
},
|
|
@@ -304,5 +484,7 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
304
484
|
}
|
|
305
485
|
|
|
306
486
|
// Additional exports we want for Stainless <-> docs integration.
|
|
307
|
-
export { parseStainlessPath } from '@stainless-api/docs-ui/
|
|
308
|
-
export { renderMarkdown } from '@stainless-api/docs-ui/
|
|
487
|
+
export { parseStainlessPath } from '@stainless-api/docs-ui/routing';
|
|
488
|
+
export { renderMarkdown } from '@stainless-api/docs-ui/markdown';
|
|
489
|
+
|
|
490
|
+
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)) {
|