@stainless-api/docs 0.1.0-beta.93 → 0.1.0-beta.95
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 +25 -0
- package/eslint-suppressions.json +0 -5
- package/package.json +4 -4
- package/plugin/buildAlgoliaIndex.ts +12 -43
- package/plugin/components/SDKSelect.astro +3 -6
- package/plugin/globalJs/code-snippets.ts +25 -3
- package/plugin/globalJs/copy.ts +2 -1
- package/plugin/globalJs/navigation.ts +8 -9
- package/plugin/helpers/generateDocsRoutes.ts +32 -0
- package/plugin/helpers/multiSpec.ts +8 -0
- package/plugin/index.ts +53 -46
- package/plugin/loadPluginConfig.ts +131 -62
- package/plugin/react/Routing.tsx +6 -9
- package/plugin/routes/Docs.astro +5 -2
- package/plugin/routes/DocsStatic.astro +2 -4
- package/plugin/routes/Overview.astro +21 -7
- package/plugin/routes/markdown.ts +4 -4
- package/plugin/specs/FileCache.ts +99 -0
- package/plugin/specs/fetchSpecSSR.ts +16 -10
- package/plugin/specs/generateSpec.ts +88 -26
- package/plugin/specs/index.ts +88 -195
- package/plugin/specs/inputResolver.ts +146 -0
- package/plugin/vendor/preview.worker.docs.js +5408 -5201
- package/plugin/vendor/templates/cli.md +1 -0
- package/plugin/vendor/templates/go.md +3 -1
- 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 +3 -1
- 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/virtual-module.d.ts +19 -3
- package/plugin/helpers/getDocsLanguages.ts +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @stainless-api/docs
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.95
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6b86a8b: Support multiple snippet examples
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [6b86a8b]
|
|
12
|
+
- @stainless-api/docs-ui@0.1.0-beta.72
|
|
13
|
+
- @stainless-api/docs-search@0.1.0-beta.25
|
|
14
|
+
|
|
15
|
+
## 0.1.0-beta.94
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- beff534: Adds support for multiple sdkjsons
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [cd578b7]
|
|
24
|
+
- Updated dependencies [beff534]
|
|
25
|
+
- @stainless-api/docs-ui@0.1.0-beta.71
|
|
26
|
+
- @stainless-api/docs-search@0.1.0-beta.24
|
|
27
|
+
|
|
3
28
|
## 0.1.0-beta.93
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/eslint-suppressions.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stainless-api/docs",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.95",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"vite-plugin-prebundle-workers": "^0.2.0",
|
|
57
57
|
"web-worker": "^1.5.0",
|
|
58
58
|
"yaml": "^2.8.2",
|
|
59
|
-
"@stainless-api/docs-search": "0.1.0-beta.
|
|
60
|
-
"@stainless-api/docs-ui": "0.1.0-beta.
|
|
59
|
+
"@stainless-api/docs-search": "0.1.0-beta.25",
|
|
60
|
+
"@stainless-api/docs-ui": "0.1.0-beta.72",
|
|
61
61
|
"@stainless-api/ui-primitives": "0.1.0-beta.47"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"vite": "^6.4.1",
|
|
74
74
|
"zod": "^4.3.5",
|
|
75
75
|
"@stainless/eslint-config": "0.1.0-beta.1",
|
|
76
|
-
"@stainless/sdk-json": "^0.1.0-beta.
|
|
76
|
+
"@stainless/sdk-json": "^0.1.0-beta.5"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"vendor-deps": "tsx scripts/vendor_deps.ts",
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import Markdoc from '@markdoc/markdoc';
|
|
2
|
-
import Stainless from '@stainless-api/sdk';
|
|
3
|
-
import { createSDKJSON, parseInputs, transformOAS } from './specs/worker';
|
|
4
|
-
import type * as SDKJSON from '@stainless/sdk-json';
|
|
5
|
-
import { Languages } from '@stainless-api/docs-ui/routing';
|
|
6
2
|
import { buildIndex } from '@stainless-api/docs-search/providers/algolia';
|
|
7
3
|
import type { AstroIntegrationLogger } from 'astro';
|
|
4
|
+
import { generateIndex } from '@stainless-api/docs-search/indexer';
|
|
5
|
+
import { SpecComposite } from './specs';
|
|
8
6
|
|
|
9
7
|
const markdocConfig = {
|
|
10
8
|
nodes: {
|
|
@@ -21,14 +19,10 @@ function renderMarkdown(content?: string) {
|
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
export async function buildAlgoliaIndex({
|
|
24
|
-
|
|
25
|
-
branch,
|
|
26
|
-
apiKey,
|
|
22
|
+
specComposite,
|
|
27
23
|
logger,
|
|
28
24
|
}: {
|
|
29
|
-
|
|
30
|
-
branch: string;
|
|
31
|
-
apiKey: string;
|
|
25
|
+
specComposite: SpecComposite;
|
|
32
26
|
logger?: AstroIntegrationLogger;
|
|
33
27
|
}) {
|
|
34
28
|
function warnLog(message: string) {
|
|
@@ -47,38 +41,6 @@ export async function buildAlgoliaIndex({
|
|
|
47
41
|
}
|
|
48
42
|
}
|
|
49
43
|
|
|
50
|
-
// TODO: this is all redundant with the spec code and should be DRYed
|
|
51
|
-
const client = new Stainless({ apiKey });
|
|
52
|
-
const configs = await client.projects.configs.retrieve({
|
|
53
|
-
project: stainlessProject,
|
|
54
|
-
branch,
|
|
55
|
-
include: 'openapi',
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const configYML = Object.values(configs)[0] as { content: any };
|
|
59
|
-
const oasJson = Object.values(configs)[1] as { content: any };
|
|
60
|
-
const configStr = configYML['content'];
|
|
61
|
-
const oasStr = oasJson['content'];
|
|
62
|
-
const { oas, config } = await parseInputs({
|
|
63
|
-
oas: oasStr,
|
|
64
|
-
config: configStr,
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
const transformedOAS = await transformOAS({ oas, config });
|
|
68
|
-
|
|
69
|
-
const languages =
|
|
70
|
-
config.docs?.languages ??
|
|
71
|
-
(Object.entries(config.targets)
|
|
72
|
-
.filter(([name, target]) => Languages.includes(name) && !target.skip)
|
|
73
|
-
.map(([name]) => name) as SDKJSON.SpecLanguage[]);
|
|
74
|
-
|
|
75
|
-
const sdkJson = await createSDKJSON({
|
|
76
|
-
oas: transformedOAS,
|
|
77
|
-
config,
|
|
78
|
-
languages,
|
|
79
|
-
projectName: stainlessProject,
|
|
80
|
-
});
|
|
81
|
-
|
|
82
44
|
const {
|
|
83
45
|
PUBLIC_ALGOLIA_APP_ID: appId,
|
|
84
46
|
PUBLIC_ALGOLIA_INDEX: indexName,
|
|
@@ -94,6 +56,13 @@ export async function buildAlgoliaIndex({
|
|
|
94
56
|
warnLog(`Skipping Algolia indexing due to missing environment variables: ${missing.join(', ')}`);
|
|
95
57
|
return;
|
|
96
58
|
}
|
|
97
|
-
|
|
59
|
+
|
|
60
|
+
const indexEntries = specComposite
|
|
61
|
+
.listUniqueSpecs()
|
|
62
|
+
.flatMap((spec) =>
|
|
63
|
+
Array.from(generateIndex(spec.data.sdkJson, renderMarkdown, true, spec.data.languages)),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
await buildIndex(appId, indexName, algoliaWriteKey, indexEntries, renderMarkdown);
|
|
98
67
|
infoLog('Indexing complete.');
|
|
99
68
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { parseRoute } from '@stainless-api/docs-ui/routing';
|
|
3
|
-
import { DEFAULT_LANGUAGE
|
|
3
|
+
import { DEFAULT_LANGUAGE } from 'virtual:stl-starlight-virtual-module';
|
|
4
4
|
import { Languages } from '../languages';
|
|
5
5
|
import { SDKSelectReactComponent } from '../react/Routing';
|
|
6
|
-
import {
|
|
7
|
-
import { getDocsLanguages } from '../helpers/getDocsLanguages';
|
|
6
|
+
import { getDocsLanguages } from '../helpers/multiSpec';
|
|
8
7
|
import { API_REFERENCE_BASE_PATH } from 'virtual:stl-docs-virtual-module';
|
|
9
8
|
|
|
10
9
|
const slug = `/${Astro.locals.starlightRoute.id}`;
|
|
@@ -20,9 +19,7 @@ const data = {
|
|
|
20
19
|
defaultLanguage,
|
|
21
20
|
};
|
|
22
21
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const options = getDocsLanguages(spec, EXCLUDE_LANGUAGES).map((value) => ({
|
|
22
|
+
const options = getDocsLanguages().map((value) => ({
|
|
26
23
|
value,
|
|
27
24
|
label: Languages[value].name,
|
|
28
25
|
selected: data.language === value,
|
|
@@ -19,9 +19,10 @@ document.addEventListener(getPageLoadEvent(), () => {
|
|
|
19
19
|
document
|
|
20
20
|
.querySelectorAll(`[data-snippet-response-pane-id="${panelId}"]`)
|
|
21
21
|
.forEach((p) => p.classList.add('stldocs-snippet-response-pane-active'));
|
|
22
|
-
document
|
|
23
|
-
.
|
|
24
|
-
.
|
|
22
|
+
document.querySelectorAll(`[data-snippet-response-tab-id="${panelId}"]`).forEach((p) => {
|
|
23
|
+
p.classList.add('stldocs-snippet-response-tab-item-active');
|
|
24
|
+
p.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
|
|
25
|
+
});
|
|
25
26
|
});
|
|
26
27
|
});
|
|
27
28
|
|
|
@@ -91,4 +92,25 @@ document.addEventListener(getPageLoadEvent(), () => {
|
|
|
91
92
|
btn.textContent = 'Show more';
|
|
92
93
|
}
|
|
93
94
|
});
|
|
95
|
+
|
|
96
|
+
document.querySelectorAll('[data-stldocs-multi-snippet-container]').forEach((container) => {
|
|
97
|
+
const radios = container.querySelectorAll<HTMLInputElement>('input[type="radio"]');
|
|
98
|
+
const panes = container.querySelectorAll<HTMLDivElement>('[data-stldocs-multi-snippet-id]');
|
|
99
|
+
|
|
100
|
+
radios.forEach((radio) => {
|
|
101
|
+
radio.addEventListener('change', (e) => {
|
|
102
|
+
if (!(e.target instanceof HTMLInputElement)) return;
|
|
103
|
+
if (e.target.checked) {
|
|
104
|
+
const selectedIndex = e.target.value;
|
|
105
|
+
panes.forEach((pane) => {
|
|
106
|
+
pane.classList.toggle(
|
|
107
|
+
'stldocs-snippet-multi-pane-active',
|
|
108
|
+
pane.dataset.stldocsMultiSnippetId === selectedIndex,
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
e.target.parentElement?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
94
116
|
});
|
package/plugin/globalJs/copy.ts
CHANGED
|
@@ -92,7 +92,8 @@ function loadPlayground(playButton: HTMLElement) {
|
|
|
92
92
|
doc: (language === 'python' ? 'from rich import print\n' : '') + code.trimEnd(),
|
|
93
93
|
container,
|
|
94
94
|
onLanguageSelect: (value) => {
|
|
95
|
-
const originalLanguage =
|
|
95
|
+
const originalLanguage = container.querySelector<HTMLElement>('[data-stldocs-snippet-select]')
|
|
96
|
+
?.dataset.currentValue;
|
|
96
97
|
const path: string = updateSelectedLanguage(RESOLVED_API_REFERENCE_PATH, originalLanguage, value);
|
|
97
98
|
navigate(path.replace(/(\?.+)?($|#)/, (_, str, end) => (str ? str + '&play' : '?play') + end));
|
|
98
99
|
},
|
|
@@ -22,15 +22,14 @@ window.addEventListener('popstate', (ev: PopStateEvent) => {
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
document.addEventListener(getPageLoadEvent(), () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
},
|
|
25
|
+
document.querySelectorAll<HTMLElement>('[data-stldocs-snippet-select]').forEach((rootElement) => {
|
|
26
|
+
initDropdown({
|
|
27
|
+
root: rootElement,
|
|
28
|
+
onSelect: (value) => {
|
|
29
|
+
const originalLanguage = rootElement.dataset.currentValue;
|
|
30
|
+
navigate(updateSelectedLanguage(RESOLVED_API_REFERENCE_PATH, originalLanguage, value));
|
|
31
|
+
},
|
|
32
|
+
});
|
|
34
33
|
});
|
|
35
34
|
|
|
36
35
|
const path = getStainlessPathForLocation();
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type * as SDKJSON from '@stainless/sdk-json';
|
|
2
2
|
import { DocsLanguage, generateRouteList } from '@stainless-api/docs-ui/routing';
|
|
3
3
|
import { EXCLUDE_LANGUAGES } from 'virtual:stl-starlight-virtual-module';
|
|
4
|
+
import { api } from 'virtual:stainless-apis-manifest';
|
|
5
|
+
import { getSDKJSONInSSR } from '../specs/fetchSpecSSR';
|
|
4
6
|
|
|
5
7
|
export function generateDocsRoutes(spec: SDKJSON.Spec, excludeLanguages: DocsLanguage[] = EXCLUDE_LANGUAGES) {
|
|
6
8
|
const paths = generateRouteList({
|
|
@@ -25,3 +27,33 @@ export function generateDocsRoutes(spec: SDKJSON.Spec, excludeLanguages: DocsLan
|
|
|
25
27
|
};
|
|
26
28
|
});
|
|
27
29
|
}
|
|
30
|
+
|
|
31
|
+
export async function generateAllDocsRoutes() {
|
|
32
|
+
const uniquePaths = new Set<string>();
|
|
33
|
+
|
|
34
|
+
const allRoutes = (
|
|
35
|
+
await Promise.all(
|
|
36
|
+
api.languages.map(async (entry) => {
|
|
37
|
+
const spec = await getSDKJSONInSSR(entry.language);
|
|
38
|
+
|
|
39
|
+
// this is super annoying, but preview worker _always_ generates HTTP routes
|
|
40
|
+
// so, we exclude them unless the we're explicitly told to include them
|
|
41
|
+
const excludeLanguages = [...EXCLUDE_LANGUAGES];
|
|
42
|
+
if (entry.language !== 'http') {
|
|
43
|
+
excludeLanguages.push('http');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const routes = generateDocsRoutes(spec, excludeLanguages);
|
|
47
|
+
return routes.filter((route) => {
|
|
48
|
+
if (uniquePaths.has(route.params.slug)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
uniquePaths.add(route.params.slug);
|
|
52
|
+
return true;
|
|
53
|
+
});
|
|
54
|
+
}),
|
|
55
|
+
)
|
|
56
|
+
).flat();
|
|
57
|
+
|
|
58
|
+
return allRoutes;
|
|
59
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { api } from 'virtual:stainless-apis-manifest';
|
|
2
|
+
import { EXCLUDE_LANGUAGES } from 'virtual:stl-starlight-virtual-module';
|
|
3
|
+
|
|
4
|
+
export function getDocsLanguages() {
|
|
5
|
+
return api.languages
|
|
6
|
+
.map((language) => language.language)
|
|
7
|
+
.filter((language) => !EXCLUDE_LANGUAGES.includes(language));
|
|
8
|
+
}
|
package/plugin/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
|
3
3
|
import type { AstroIntegration } from 'astro';
|
|
4
4
|
import type { BundledTheme } from 'shiki';
|
|
5
5
|
import { config } from 'dotenv';
|
|
6
|
-
import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
6
|
+
// import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
7
7
|
import {
|
|
8
8
|
getAPIReferencePlaceholderItemFromSidebarConfig,
|
|
9
9
|
makePlaceholderItems,
|
|
@@ -32,8 +32,8 @@ import prebundleWorkers from 'vite-plugin-prebundle-workers';
|
|
|
32
32
|
import { SpecLoader, startSpecLoader } from './specs';
|
|
33
33
|
|
|
34
34
|
import type * as ReferenceSidebarsVirtualModule from 'virtual:stl-starlight-reference-sidebars';
|
|
35
|
-
import { getDocsLanguages } from './helpers/getDocsLanguages';
|
|
36
35
|
import { generateMissingRouteList } from '@stainless-api/docs-ui/routing';
|
|
36
|
+
import { buildAlgoliaIndex } from './buildAlgoliaIndex';
|
|
37
37
|
|
|
38
38
|
export { generateAPILink } from './generateAPIReferenceLink';
|
|
39
39
|
export type { ReferenceSidebarConfigItem };
|
|
@@ -102,13 +102,10 @@ async function stlStarlightAstroIntegration(
|
|
|
102
102
|
let astroBase = '/';
|
|
103
103
|
|
|
104
104
|
let specLoader: SpecLoader | undefined;
|
|
105
|
-
async function
|
|
105
|
+
async function resolveSpecs() {
|
|
106
106
|
if (!specLoader) throw new Error('Expected spec loader to exist');
|
|
107
107
|
const result = await specLoader.specPromise;
|
|
108
|
-
return
|
|
109
|
-
spec: result.spec.data,
|
|
110
|
-
auth: result.spec.auth,
|
|
111
|
-
};
|
|
108
|
+
return result.specComposite;
|
|
112
109
|
}
|
|
113
110
|
|
|
114
111
|
let building: Promise<void> | undefined;
|
|
@@ -119,9 +116,16 @@ async function stlStarlightAstroIntegration(
|
|
|
119
116
|
if (!pluginConfig.experimentalPlaygrounds) return;
|
|
120
117
|
if (building) return building;
|
|
121
118
|
return (building = (async () => {
|
|
122
|
-
const
|
|
119
|
+
const specComposite = await resolveSpecs();
|
|
120
|
+
|
|
121
|
+
if (specComposite.listUniqueSpecs().length > 1) {
|
|
122
|
+
throw new Error('Multiple specs found. This is not supported for Playgrounds.');
|
|
123
|
+
}
|
|
123
124
|
|
|
124
|
-
const
|
|
125
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
126
|
+
const auth = specComposite.listUniqueSpecs()[0]!.data.auth;
|
|
127
|
+
|
|
128
|
+
const langs = specComposite.getLanguages();
|
|
125
129
|
|
|
126
130
|
await buildPlaygrounds!({
|
|
127
131
|
spec,
|
|
@@ -150,14 +154,9 @@ async function stlStarlightAstroIntegration(
|
|
|
150
154
|
const projectDir = astroConfig.root.pathname;
|
|
151
155
|
astroBase = astroConfig.base;
|
|
152
156
|
|
|
157
|
+
logger.warn('Starting spec loader!!!');
|
|
158
|
+
|
|
153
159
|
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
160
|
|
|
162
161
|
reportError = (message: string) => logger.error(message);
|
|
163
162
|
|
|
@@ -198,22 +197,23 @@ async function stlStarlightAstroIntegration(
|
|
|
198
197
|
makeAsyncVirtualModPlugin<typeof ReferenceSidebarsVirtualModule>(
|
|
199
198
|
'virtual:stl-starlight-reference-sidebars',
|
|
200
199
|
async () => {
|
|
201
|
-
|
|
202
|
-
const
|
|
200
|
+
// we know specLoader exists here
|
|
201
|
+
const { specComposite } = await specLoader!.specPromise;
|
|
203
202
|
|
|
204
203
|
const sidebars = [...sidebarConfigs.entries()]
|
|
205
204
|
// produce all { id, language } combos with the attached config
|
|
206
205
|
// flattens to one item per language * id combo
|
|
207
206
|
.flatMap(([id, config]) =>
|
|
208
|
-
|
|
207
|
+
specComposite.listAllLanguagesAndIncludeSpecs().map((res) => ({
|
|
209
208
|
id,
|
|
210
209
|
config,
|
|
211
|
-
language,
|
|
210
|
+
language: res.language,
|
|
211
|
+
spec: res.spec.data.sdkJson,
|
|
212
212
|
})),
|
|
213
213
|
)
|
|
214
214
|
// produce a sidebar for each
|
|
215
215
|
// later we will .find() the sidebar that matches the (id, language)
|
|
216
|
-
.map(({ id, config, language }) => {
|
|
216
|
+
.map(({ id, config, language, spec }) => {
|
|
217
217
|
const configItemsBuilder = new SidebarConfigItemsBuilder(
|
|
218
218
|
spec,
|
|
219
219
|
language,
|
|
@@ -232,7 +232,7 @@ async function stlStarlightAstroIntegration(
|
|
|
232
232
|
// this has to run multpile times because it depends on the
|
|
233
233
|
// userSidebarConfig (which is per-id) and the language
|
|
234
234
|
entries: toStarlightSidebar({
|
|
235
|
-
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
235
|
+
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
236
236
|
spec,
|
|
237
237
|
entries: userSidebarConfig,
|
|
238
238
|
currentLanguage: language,
|
|
@@ -243,7 +243,7 @@ async function stlStarlightAstroIntegration(
|
|
|
243
243
|
return { sidebars };
|
|
244
244
|
},
|
|
245
245
|
),
|
|
246
|
-
specLoader.
|
|
246
|
+
...specLoader.vitePlugins,
|
|
247
247
|
{
|
|
248
248
|
name: 'stl-starlight-vite',
|
|
249
249
|
buildStart() {
|
|
@@ -314,7 +314,7 @@ async function stlStarlightAstroIntegration(
|
|
|
314
314
|
ENABLE_CONTEXT_MENU: pluginConfig.contextMenu,
|
|
315
315
|
EXPERIMENTAL_PLAYGROUNDS: !!pluginConfig.experimentalPlaygrounds,
|
|
316
316
|
EXPERIMENTAL_REQUEST_BUILDER: pluginConfig.experimentalRequestBuilder,
|
|
317
|
-
STAINLESS_PROJECT: pluginConfig.
|
|
317
|
+
STAINLESS_PROJECT: pluginConfig.stainlessProject,
|
|
318
318
|
} satisfies Omit<typeof StlStarlightVirtualModule, 'MIDDLEWARE'>),
|
|
319
319
|
vmMiddlewareExport,
|
|
320
320
|
].join('\n');
|
|
@@ -363,12 +363,22 @@ async function stlStarlightAstroIntegration(
|
|
|
363
363
|
};
|
|
364
364
|
await writeFile(path.join(stainlessDir, 'stl-manifest.json'), JSON.stringify(manifest, null, 2));
|
|
365
365
|
|
|
366
|
+
const specComposite = await resolveSpecs();
|
|
367
|
+
|
|
368
|
+
await buildAlgoliaIndex({
|
|
369
|
+
specComposite,
|
|
370
|
+
logger,
|
|
371
|
+
});
|
|
372
|
+
|
|
366
373
|
// Generate a list of missing API routes to enable graceful handling of unimplemented SDK methods.
|
|
367
374
|
// When users switch languages in the docs, some API methods may not be implemented in the target SDK.
|
|
368
375
|
// Instead of showing a generic 404, we statically generate pages for these routes and mark them
|
|
369
376
|
// in this file so Cloudflare can serve them with a 404 status. These pages display helpful information
|
|
370
377
|
// about the missing method and provide links to SDKs where it is available.
|
|
371
|
-
|
|
378
|
+
|
|
379
|
+
// TODO: (multi-spec) support multiple specs
|
|
380
|
+
const spec = specComposite.listUniqueSpecs()[0]!.data.sdkJson;
|
|
381
|
+
|
|
372
382
|
const missingRoutes = generateMissingRouteList({
|
|
373
383
|
spec,
|
|
374
384
|
basePath: path.posix.join(astroBase, pluginConfig.basePath),
|
|
@@ -402,7 +412,10 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
402
412
|
|
|
403
413
|
const logger = getSharedLogger({ fallback: localLogger });
|
|
404
414
|
|
|
405
|
-
const configParseResult = parseStarlightPluginConfig(someUserConfig,
|
|
415
|
+
const configParseResult = parseStarlightPluginConfig(someUserConfig, {
|
|
416
|
+
command,
|
|
417
|
+
base: astroConfig.base,
|
|
418
|
+
});
|
|
406
419
|
if (configParseResult.result === 'error') {
|
|
407
420
|
const errorLines = configParseResult.message.split('\n');
|
|
408
421
|
for (const line of errorLines) {
|
|
@@ -419,26 +432,18 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
419
432
|
addIntegration(react());
|
|
420
433
|
}
|
|
421
434
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
if (command === 'build' && config.specInputs.kind === 'stainless_api_inputs') {
|
|
435
|
-
await buildAlgoliaIndex({
|
|
436
|
-
stainlessProject: config.specInputs.project,
|
|
437
|
-
branch: config.specInputs.branch,
|
|
438
|
-
apiKey: config.specInputs.apiKey.value,
|
|
439
|
-
logger,
|
|
440
|
-
});
|
|
441
|
-
}
|
|
435
|
+
// TODO: (multi-spec) re-add this? not strictly necessary to merge
|
|
436
|
+
// if ('apiKey' in config.specInputs) {
|
|
437
|
+
// if (!config.specInputs.apiKey) {
|
|
438
|
+
// logger.info(`Stainless credentials not loaded`);
|
|
439
|
+
// } else if (config.specInputs.apiKey.source === 'explicit-config') {
|
|
440
|
+
// logger.info(`Stainless credentials loaded from user config`);
|
|
441
|
+
// } else if (config.specInputs.apiKey.source === 'environment-variable') {
|
|
442
|
+
// logger.info('Stainless credentials loaded from `STAINLESS_API_KEY` environment variable');
|
|
443
|
+
// } else if (config.specInputs.apiKey.source === 'cli') {
|
|
444
|
+
// logger.info('Stainless credentials loaded from `stl` CLI');
|
|
445
|
+
// }
|
|
446
|
+
// })
|
|
442
447
|
|
|
443
448
|
if (starlightConfig.sidebar) {
|
|
444
449
|
// for pagination (https://starlight.astro.build/reference/configuration/#pagination) to work correctly
|
|
@@ -483,3 +488,5 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
483
488
|
// Additional exports we want for Stainless <-> docs integration.
|
|
484
489
|
export { parseStainlessPath } from '@stainless-api/docs-ui/routing';
|
|
485
490
|
export { renderMarkdown } from '@stainless-api/docs-ui/markdown';
|
|
491
|
+
|
|
492
|
+
export { resolveSpec } from './specs/inputResolver';
|