@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.
Files changed (34) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/eslint-suppressions.json +0 -5
  3. package/package.json +4 -4
  4. package/plugin/buildAlgoliaIndex.ts +12 -43
  5. package/plugin/components/SDKSelect.astro +3 -6
  6. package/plugin/globalJs/code-snippets.ts +25 -3
  7. package/plugin/globalJs/copy.ts +2 -1
  8. package/plugin/globalJs/navigation.ts +8 -9
  9. package/plugin/helpers/generateDocsRoutes.ts +32 -0
  10. package/plugin/helpers/multiSpec.ts +8 -0
  11. package/plugin/index.ts +53 -46
  12. package/plugin/loadPluginConfig.ts +131 -62
  13. package/plugin/react/Routing.tsx +6 -9
  14. package/plugin/routes/Docs.astro +5 -2
  15. package/plugin/routes/DocsStatic.astro +2 -4
  16. package/plugin/routes/Overview.astro +21 -7
  17. package/plugin/routes/markdown.ts +4 -4
  18. package/plugin/specs/FileCache.ts +99 -0
  19. package/plugin/specs/fetchSpecSSR.ts +16 -10
  20. package/plugin/specs/generateSpec.ts +88 -26
  21. package/plugin/specs/index.ts +88 -195
  22. package/plugin/specs/inputResolver.ts +146 -0
  23. package/plugin/vendor/preview.worker.docs.js +5408 -5201
  24. package/plugin/vendor/templates/cli.md +1 -0
  25. package/plugin/vendor/templates/go.md +3 -1
  26. package/plugin/vendor/templates/java.md +3 -1
  27. package/plugin/vendor/templates/kotlin.md +3 -1
  28. package/plugin/vendor/templates/node.md +4 -2
  29. package/plugin/vendor/templates/python.md +3 -1
  30. package/plugin/vendor/templates/ruby.md +4 -2
  31. package/plugin/vendor/templates/terraform.md +1 -1
  32. package/plugin/vendor/templates/typescript.md +3 -1
  33. package/virtual-module.d.ts +19 -3
  34. 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
@@ -1,9 +1,4 @@
1
1
  {
2
- "plugin/buildAlgoliaIndex.ts": {
3
- "@typescript-eslint/no-explicit-any": {
4
- "count": 2
5
- }
6
- },
7
2
  "plugin/components/SnippetCode.tsx": {
8
3
  "@typescript-eslint/no-explicit-any": {
9
4
  "count": 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stainless-api/docs",
3
- "version": "0.1.0-beta.93",
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.23",
60
- "@stainless-api/docs-ui": "0.1.0-beta.70",
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.4"
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
- stainlessProject,
25
- branch,
26
- apiKey,
22
+ specComposite,
27
23
  logger,
28
24
  }: {
29
- stainlessProject: string;
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
- await buildIndex(appId, indexName, algoliaWriteKey, sdkJson, renderMarkdown);
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, EXCLUDE_LANGUAGES } from 'virtual:stl-starlight-virtual-module';
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 { getSDKJSONInSSR } from '../specs/fetchSpecSSR';
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 spec = await getSDKJSONInSSR();
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
- .querySelectorAll(`[data-snippet-response-tab-id="${panelId}"]`)
24
- .forEach((p) => p.classList.add('stldocs-snippet-response-tab-item-active'));
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
  });
@@ -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 = document.getElementById('stldocs-snippet-select')?.dataset.currentValue;
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
- const rootElement = document.getElementById('stldocs-snippet-select');
26
- if (!rootElement) return;
27
-
28
- initDropdown({
29
- root: rootElement,
30
- onSelect: (value) => {
31
- const originalLanguage = rootElement?.dataset.currentValue;
32
- navigate(updateSelectedLanguage(RESOLVED_API_REFERENCE_PATH, originalLanguage, value));
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 getSpec() {
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 { spec, auth } = await getSpec();
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 langs = getDocsLanguages(spec, pluginConfig.excludeLanguages);
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
- const { spec } = await getSpec();
202
- const languages = getDocsLanguages(spec, pluginConfig.excludeLanguages);
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
- languages.map((language) => ({
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), // TODO, is this right?
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.vitePlugin,
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.specInputs.project,
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
- const { spec } = await getSpec();
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, command);
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
- 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') {
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';