@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.
Files changed (158) hide show
  1. package/CHANGELOG.md +917 -0
  2. package/eslint-suppressions.json +27 -0
  3. package/locals.d.ts +17 -0
  4. package/package.json +50 -40
  5. package/playground-virtual-modules.d.ts +96 -0
  6. package/plugin/assets/languages/cli.svg +14 -0
  7. package/plugin/assets/languages/csharp.svg +1 -0
  8. package/plugin/assets/languages/php.svg +4 -0
  9. package/plugin/buildAlgoliaIndex.ts +40 -39
  10. package/plugin/components/MethodDescription.tsx +54 -0
  11. package/plugin/components/RequestBuilder/ParamEditor.tsx +55 -0
  12. package/plugin/components/RequestBuilder/SnippetStainlessIsland.tsx +107 -0
  13. package/plugin/components/RequestBuilder/index.tsx +37 -0
  14. package/plugin/components/RequestBuilder/props.ts +9 -0
  15. package/plugin/components/RequestBuilder/spec-helpers.ts +47 -0
  16. package/plugin/components/RequestBuilder/styles.css +67 -0
  17. package/plugin/components/SDKSelect.astro +18 -105
  18. package/plugin/components/SnippetCode.tsx +111 -66
  19. package/plugin/components/StainlessIslands.tsx +126 -0
  20. package/plugin/components/search/SearchAlgolia.astro +45 -35
  21. package/plugin/components/search/SearchIsland.tsx +47 -29
  22. package/plugin/generateAPIReferenceLink.ts +2 -2
  23. package/plugin/globalJs/ai-dropdown-options.ts +243 -0
  24. package/plugin/globalJs/code-snippets.ts +40 -11
  25. package/plugin/globalJs/copy.ts +95 -17
  26. package/plugin/globalJs/create-playground.shim.ts +3 -0
  27. package/plugin/globalJs/method-descriptions.ts +33 -0
  28. package/plugin/globalJs/navigation.ts +12 -33
  29. package/plugin/globalJs/playground-data.shim.ts +1 -0
  30. package/plugin/globalJs/playground-data.ts +14 -0
  31. package/plugin/helpers/generateDocsRoutes.ts +59 -0
  32. package/plugin/helpers/getPageLoadEvent.ts +1 -1
  33. package/plugin/helpers/multiSpec.ts +8 -0
  34. package/plugin/index.ts +299 -117
  35. package/plugin/languages.ts +8 -2
  36. package/plugin/loadPluginConfig.ts +254 -102
  37. package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +1 -1
  38. package/plugin/react/Routing.tsx +210 -140
  39. package/plugin/referencePlaceholderUtils.ts +18 -15
  40. package/plugin/replaceSidebarPlaceholderMiddleware.ts +40 -32
  41. package/plugin/routes/Docs.astro +70 -119
  42. package/plugin/routes/DocsStatic.astro +6 -5
  43. package/plugin/routes/Overview.astro +37 -27
  44. package/plugin/routes/markdown.ts +13 -12
  45. package/plugin/{cms → sidebar-utils}/sidebar-builder.ts +49 -60
  46. package/plugin/specs/FileCache.ts +99 -0
  47. package/plugin/specs/fetchSpecSSR.ts +27 -0
  48. package/plugin/specs/generateSpec.ts +112 -0
  49. package/plugin/specs/index.ts +132 -0
  50. package/plugin/specs/inputResolver.ts +146 -0
  51. package/plugin/{cms → specs}/worker.ts +82 -5
  52. package/plugin/vendor/preview.worker.docs.js +22406 -17955
  53. package/plugin/vendor/templates/cli.md +1 -0
  54. package/plugin/vendor/templates/go.md +4 -2
  55. package/plugin/vendor/templates/java.md +3 -1
  56. package/plugin/vendor/templates/kotlin.md +3 -1
  57. package/plugin/vendor/templates/node.md +4 -2
  58. package/plugin/vendor/templates/python.md +4 -2
  59. package/plugin/vendor/templates/ruby.md +4 -2
  60. package/plugin/vendor/templates/terraform.md +1 -1
  61. package/plugin/vendor/templates/typescript.md +3 -1
  62. package/resolveSrcFile.ts +10 -0
  63. package/scripts/vendor_deps.ts +5 -5
  64. package/shared/getProsePages.ts +42 -0
  65. package/shared/getSharedLogger.ts +15 -0
  66. package/shared/terminalUtils.ts +3 -0
  67. package/shared/virtualModule.ts +54 -1
  68. package/src/content.config.ts +9 -0
  69. package/stl-docs/components/AIDropdown.tsx +63 -0
  70. package/stl-docs/components/AiChatIsland.tsx +14 -0
  71. package/stl-docs/components/{content-panel/ContentBreadcrumbs.tsx → ContentBreadcrumbs.tsx} +2 -2
  72. package/stl-docs/components/Head.astro +20 -0
  73. package/stl-docs/components/Header.astro +7 -9
  74. package/stl-docs/components/PageFrame.astro +18 -0
  75. package/stl-docs/components/PageTitle.astro +82 -0
  76. package/stl-docs/components/TableOfContents.astro +34 -0
  77. package/stl-docs/components/ThemeProvider.astro +36 -0
  78. package/stl-docs/components/ThemeSelect.astro +84 -144
  79. package/stl-docs/components/content-panel/ContentPanel.astro +16 -46
  80. package/stl-docs/components/headers/DefaultHeader.astro +1 -1
  81. package/stl-docs/components/headers/HeaderLinks.astro +1 -1
  82. package/stl-docs/components/headers/SplashMobileMenuToggle.astro +17 -1
  83. package/stl-docs/components/headers/StackedHeader.astro +29 -24
  84. package/stl-docs/components/icons/chat-gpt.tsx +17 -0
  85. package/stl-docs/components/icons/claude.tsx +10 -0
  86. package/stl-docs/components/icons/cursor.tsx +10 -0
  87. package/stl-docs/components/icons/gemini.tsx +19 -0
  88. package/stl-docs/components/icons/markdown.tsx +10 -0
  89. package/stl-docs/components/index.ts +1 -0
  90. package/stl-docs/components/mintlify-compat/Accordion.astro +7 -38
  91. package/stl-docs/components/mintlify-compat/AccordionGroup.astro +9 -23
  92. package/stl-docs/components/mintlify-compat/Columns.astro +40 -42
  93. package/stl-docs/components/mintlify-compat/Frame.astro +16 -18
  94. package/stl-docs/components/mintlify-compat/callouts/Callout.astro +10 -3
  95. package/stl-docs/components/mintlify-compat/callouts/Check.astro +7 -3
  96. package/stl-docs/components/mintlify-compat/callouts/Danger.astro +7 -3
  97. package/stl-docs/components/mintlify-compat/callouts/Info.astro +7 -3
  98. package/stl-docs/components/mintlify-compat/callouts/Note.astro +7 -3
  99. package/stl-docs/components/mintlify-compat/callouts/Tip.astro +7 -3
  100. package/stl-docs/components/mintlify-compat/callouts/Warning.astro +7 -3
  101. package/stl-docs/components/mintlify-compat/card.css +33 -35
  102. package/stl-docs/components/mintlify-compat/index.ts +2 -4
  103. package/stl-docs/components/nav-tabs/NavDropdown.astro +31 -75
  104. package/stl-docs/components/nav-tabs/NavTabs.astro +78 -80
  105. package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +15 -8
  106. package/stl-docs/components/nav-tabs/buildNavLinks.ts +4 -3
  107. package/stl-docs/components/pagination/HomeLink.astro +10 -0
  108. package/stl-docs/components/pagination/Pagination.astro +175 -0
  109. package/stl-docs/components/pagination/PaginationLinkEmphasized.astro +22 -0
  110. package/stl-docs/components/pagination/PaginationLinkQuiet.astro +13 -0
  111. package/stl-docs/components/pagination/util.ts +71 -0
  112. package/stl-docs/components/scripts.ts +1 -0
  113. package/stl-docs/components/sidebars/BaseSidebar.astro +87 -0
  114. package/stl-docs/components/sidebars/SDKSelectSidebar.astro +8 -0
  115. package/stl-docs/components/sidebars/SidebarWithComponents.tsx +10 -0
  116. package/stl-docs/components/sidebars/convertAstroSidebarToStl.tsx +62 -0
  117. package/stl-docs/disableCalloutSyntax.ts +36 -0
  118. package/stl-docs/fonts.ts +186 -0
  119. package/stl-docs/index.ts +159 -43
  120. package/stl-docs/loadStlDocsConfig.ts +60 -9
  121. package/stl-docs/proseMarkdown/proseMarkdownIntegration.ts +61 -0
  122. package/stl-docs/proseMarkdown/proseMarkdownMiddleware.ts +41 -0
  123. package/stl-docs/proseMarkdown/toMarkdown.ts +158 -0
  124. package/stl-docs/proseSearchIndexing.ts +606 -0
  125. package/stl-docs/tabsMiddleware.ts +14 -5
  126. package/styles/code.css +133 -136
  127. package/styles/links.css +11 -48
  128. package/styles/method-descriptions.css +36 -0
  129. package/styles/overrides.css +49 -57
  130. package/styles/page.css +100 -59
  131. package/styles/sdk_select.css +9 -7
  132. package/styles/search.css +57 -69
  133. package/styles/sidebar.css +26 -156
  134. package/styles/{variables.css → sl-variables.css} +3 -2
  135. package/styles/stldocs-variables.css +6 -0
  136. package/styles/toc.css +41 -34
  137. package/theme.css +13 -3
  138. package/tsconfig.json +2 -5
  139. package/virtual-module.d.ts +65 -7
  140. package/components/variables.css +0 -139
  141. package/plugin/cms/client.ts +0 -62
  142. package/plugin/cms/server.ts +0 -268
  143. package/plugin/globalJs/ai-dropdown.ts +0 -57
  144. package/stl-docs/components/APIReferenceAIDropdown.tsx +0 -86
  145. package/stl-docs/components/Sidebar.astro +0 -11
  146. package/stl-docs/components/content-panel/ProseAIDropdown.tsx +0 -64
  147. package/stl-docs/components/mintlify-compat/Step.astro +0 -58
  148. package/stl-docs/components/mintlify-compat/Steps.astro +0 -17
  149. package/styles/fonts.css +0 -68
  150. /package/{plugin/assets → assets}/fonts/geist/OFL.txt +0 -0
  151. /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin-ext.woff2 +0 -0
  152. /package/{plugin/assets → assets}/fonts/geist/geist-italic-latin.woff2 +0 -0
  153. /package/{plugin/assets → assets}/fonts/geist/geist-latin-ext.woff2 +0 -0
  154. /package/{plugin/assets → assets}/fonts/geist/geist-latin.woff2 +0 -0
  155. /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin-ext.woff2 +0 -0
  156. /package/{plugin/assets → assets}/fonts/geist/geist-mono-italic-latin.woff2 +0 -0
  157. /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin-ext.woff2 +0 -0
  158. /package/{plugin/assets → assets}/fonts/geist/geist-mono-latin.woff2 +0 -0
@@ -1,9 +1,18 @@
1
1
  import path from 'path';
2
+ import { homedir } from 'os';
3
+ import { existsSync, readFileSync } from 'fs';
2
4
 
3
5
  import type { CreateShikiHighlighterOptions } from '@astrojs/markdown-remark';
4
- import type { DocsLanguage } from '@stainless-api/docs-ui/src/routing';
5
- import type { PropertySettingsType } from '@stainless-api/docs-ui/src/contexts';
6
- import type { InputFilePaths } from '../plugin/cms/server';
6
+ import type { DocsLanguage } from '@stainless-api/docs-ui/routing';
7
+ import type { PropertySettingsType } from '@stainless-api/docs-ui/contexts';
8
+ import { bold } from '../shared/terminalUtils';
9
+ import { resolveSpec, SpecInputResolver } from './specs/inputResolver';
10
+ import { specCache, SpecCacheResult } from './specs/generateSpec';
11
+
12
+ export type LanguageGenerateQuery = {
13
+ mode: 'exclude' | 'only';
14
+ list: DocsLanguage[];
15
+ };
7
16
 
8
17
  export type AstroCommand = 'dev' | 'build' | 'preview' | 'sync';
9
18
 
@@ -18,7 +27,7 @@ export type VersionUserConfig = {
18
27
  type BreadcrumbUserConfig = {
19
28
  /**
20
29
  * Include the current page in the breadcrumb list.
21
- * Defaults to `false`.
30
+ * Default: `false`
22
31
  */
23
32
  includeCurrentPage?: boolean;
24
33
  };
@@ -26,7 +35,12 @@ type BreadcrumbUserConfig = {
26
35
  export type StainlessStarlightUserConfig = {
27
36
  /**
28
37
  * Optional api key for Stainless API.
29
- * If not provided, it will look for the STAINLESS_API_KEY environment variable.
38
+ * If not provided, we will handle Stainless auth via the `stl` CLI or look for the STAINLESS_API_KEY environment variable.
39
+ * Precedence:
40
+ * 1. Explicity `apiKey` option provided
41
+ * 2. `STAINLESS_API_KEY` environment variable
42
+ * 3. Login status from the `stl` CLI
43
+ * 4. Error (no auth found)
30
44
  */
31
45
  apiKey?: string;
32
46
 
@@ -35,6 +49,19 @@ export type StainlessStarlightUserConfig = {
35
49
  */
36
50
  stainlessProject: string;
37
51
 
52
+ /**
53
+ * Powerful configuration options for customized use cases
54
+ */
55
+ advanced?: {
56
+ /**
57
+ *
58
+ * More advanced replacement for versions, basePath, and excludeLanguages.
59
+ */
60
+ overrideSpecs?: {
61
+ specs: SpecInputResolver[];
62
+ };
63
+ };
64
+
38
65
  /**
39
66
  * Optional list of versions to render in the API reference.
40
67
  */
@@ -42,8 +69,8 @@ export type StainlessStarlightUserConfig = {
42
69
 
43
70
  /**
44
71
  * Optional mount point for API reference docs.
45
- * Defaults to `/api`.
46
72
  * Example: `/my-api` → docs available at `/my-api/…`.
73
+ * @default `/api`
47
74
  */
48
75
  basePath?: string;
49
76
 
@@ -55,8 +82,8 @@ export type StainlessStarlightUserConfig = {
55
82
 
56
83
  /**
57
84
  * Optional language to treat as the default when the user hasn't selected one.
58
- * Defaults to `"http"` when none is provided.
59
- * Example: `"python"`
85
+ * Example: `'python'`
86
+ * @default 'http'
60
87
  */
61
88
  defaultLanguage?: DocsLanguage;
62
89
 
@@ -90,7 +117,7 @@ export type StainlessStarlightUserConfig = {
90
117
  contentPanel?: {
91
118
  /**
92
119
  * Optional layout for the content panel.
93
- * Defaults to `"double-pane"`.
120
+ * @default 'double-pane'
94
121
  */
95
122
  layout?: ContentLayout;
96
123
  };
@@ -100,71 +127,235 @@ export type StainlessStarlightUserConfig = {
100
127
  */
101
128
  propertySettings?: PropertySettingsType;
102
129
 
103
- /**
104
- * Options to control the documentation site's search functionality
105
- */
106
- search?: {
107
- /**
108
- * When set to `true`, the enableAISearch` setting turns on support for
109
- * LLM-based conversations with the API documentation
110
- */
111
- enableAISearch?: boolean;
112
- };
113
-
114
130
  /**
115
131
  * Enable experimental collapsible code snippets. Snippets will be collapsed by default for
116
132
  * single-pane and mobile layouts.
117
- * Defaults to `false`.
133
+ *
134
+ * @default false
118
135
  */
119
136
  experimentalCollapsibleSnippets?: boolean;
120
- };
121
137
 
122
- export type ExternalSpecServerUserConfig = Omit<StainlessStarlightUserConfig, 'stainlessProject'> & {
123
- externalSpecServerUrl: string;
138
+ /**
139
+ * Enable experimental collapsible method descriptions. Method descriptions will be
140
+ * collapsed if their content exceeds a certain length.
141
+ *
142
+ * @default false
143
+ */
144
+ experimentalCollapsibleMethodDescriptions?: boolean;
145
+
146
+ /**
147
+ * Whether to show the context menu with options like "Copy as Markdown" and "Open in ChatGPT".
148
+ *
149
+ * @default true
150
+ */
151
+
152
+ contextMenu?: boolean;
153
+
154
+ /**
155
+ * When set to `import playgrounds from '@stainless-api/playgrounds'`, code snippets will have a "Play" button,
156
+ * allowing users to edit and run code snippets in their browser.
157
+ */
158
+ experimentalPlaygrounds?: { playgroundsBase: string };
159
+
160
+ /** When set to true, enables the experimental request builder interface for testing API endpoints. */
161
+ experimentalRequestBuilder?: boolean;
162
+
163
+ /** Whether to prerender the api reference pages.
164
+ *
165
+ * @default true
166
+ */
167
+ experimentalPrerender?: boolean;
124
168
  };
125
169
 
126
- export type SomeStainlessStarlightUserConfig = StainlessStarlightUserConfig | ExternalSpecServerUserConfig;
170
+ // TODO: eventually? re-add support for external spec servers
171
+ // export type ExternalSpecServerUserConfig = Omit<StainlessStarlightUserConfig, 'stainlessProject'> & {
172
+ // externalSpecServerUrl: string;
173
+ // };
174
+
175
+ export type SomeStainlessStarlightUserConfig = StainlessStarlightUserConfig;
127
176
 
128
177
  function resolvePath(inputPath: string) {
129
178
  return path.resolve(process.cwd(), inputPath);
130
179
  }
131
180
 
132
- function getLocalFilePaths(command: AstroCommand): InputFilePaths | null {
181
+ function getLocalFilePaths(command: AstroCommand) {
133
182
  if (command !== 'dev') {
134
183
  return null;
135
184
  }
136
- if (!process.env.OPENAPI_PATH || !process.env.STAINLESS_SPEC_PATH) {
185
+
186
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
187
+ const oasPath = process.env.OPENAPI_PATH;
188
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
189
+ const configPath = process.env.STAINLESS_CONFIG_PATH;
190
+
191
+ if (!oasPath || !configPath) {
137
192
  return null;
138
193
  }
194
+
139
195
  return {
140
- oasPath: resolvePath(process.env.OPENAPI_PATH),
141
- configPath: resolvePath(process.env.STAINLESS_SPEC_PATH),
196
+ oasPath: resolvePath(oasPath),
197
+ configPath: resolvePath(configPath),
142
198
  };
143
199
  }
144
200
 
145
- export type SpecRetrieverConfig =
146
- | {
147
- kind: 'external_spec_server';
148
- specServerUrl: string;
149
- stainlessProject: null;
201
+ export type ApiKeySource = 'explicit-config' | 'environment-variable' | 'cli';
202
+
203
+ export type LoadedApiKey = {
204
+ value: string;
205
+ source: ApiKeySource;
206
+ };
207
+
208
+ function parseAuthJson(authJsonStr: string) {
209
+ let json: unknown;
210
+ try {
211
+ json = JSON.parse(authJsonStr);
212
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
213
+ } catch (_error) {
214
+ return null;
215
+ }
216
+
217
+ if (typeof json !== 'object' || json === null) {
218
+ return null;
219
+ }
220
+ if (!('access_token' in json)) {
221
+ return null;
222
+ }
223
+ const accessToken = json['access_token'];
224
+ if (typeof accessToken !== 'string') {
225
+ return null;
226
+ }
227
+ return accessToken;
228
+ }
229
+
230
+ function loadApiKey(configValue: string | undefined): LoadedApiKey | null {
231
+ if (typeof configValue === 'string') {
232
+ return { value: configValue, source: 'explicit-config' };
233
+ }
234
+ if (process.env.STAINLESS_API_KEY) {
235
+ return { value: process.env.STAINLESS_API_KEY, source: 'environment-variable' };
236
+ }
237
+
238
+ const homeDirPath = homedir();
239
+
240
+ const authJsonPath = path.join(homeDirPath, '.config', 'stainless', 'auth.json');
241
+
242
+ if (!existsSync(authJsonPath)) {
243
+ return null;
244
+ }
245
+
246
+ const authJsonStr = readFileSync(authJsonPath, 'utf-8');
247
+ const accessToken = parseAuthJson(authJsonStr);
248
+ if (!accessToken) {
249
+ return null;
250
+ }
251
+
252
+ return { value: accessToken, source: 'cli' };
253
+ }
254
+
255
+ export function forceLoadStainlessCredentials(): LoadedApiKey {
256
+ const v = loadApiKey(undefined);
257
+ if (!v) {
258
+ throw new Error(`Failed to load Stainless credentials.`);
259
+ }
260
+ return v;
261
+ }
262
+
263
+ type AstroOptions = {
264
+ command: AstroCommand;
265
+ base: string;
266
+ };
267
+
268
+ export type ResolvedAPIConfigEntry = {
269
+ loadSpecs: () => Promise<SpecCacheResult[]>;
270
+ };
271
+
272
+ function makeSimpleAPIConfig(
273
+ partial: SomeStainlessStarlightUserConfig,
274
+ astroOptions: AstroOptions,
275
+ ): ResolvedAPIConfigEntry {
276
+ if (!('stainlessProject' in partial)) {
277
+ throw new Error('You must provide a stainlessProject when using Stainless Starlight');
278
+ }
279
+
280
+ const excludedLanguages = partial.excludeLanguages ?? [];
281
+
282
+ const apiKey = loadApiKey(partial.apiKey);
283
+
284
+ function getResolver() {
285
+ const localFilePaths = getLocalFilePaths(astroOptions.command);
286
+ if (localFilePaths) {
287
+ return resolveSpec.fromFiles({
288
+ oasPath: localFilePaths.oasPath,
289
+ configPath: localFilePaths.configPath,
290
+ languageOverrides: {
291
+ mode: 'exclude',
292
+ list: excludedLanguages,
293
+ },
294
+ stainlessProject: partial.stainlessProject,
295
+ });
150
296
  }
151
- | {
152
- kind: 'local_spec_server_with_files';
153
- stainlessProject: string;
154
- devPaths: InputFilePaths;
155
- apiKey: string | null;
156
- version: VersionUserConfig;
297
+
298
+ if (!apiKey) {
299
+ throw new Error(
300
+ [
301
+ bold(
302
+ 'No Stainless credentials found. Please choose one of the following options to authenticate with Stainless:',
303
+ ),
304
+ '- Run `stl auth login` to authenticate via the Stainless CLI',
305
+ '- Provide a Stainless API key via the `STAINLESS_API_KEY` environment variable (eg. in a .env file)',
306
+ '- Set the `apiKey` option in the Stainless Docs config',
307
+ ].join('\n'),
308
+ );
157
309
  }
158
- | {
159
- kind: 'local_spec_server_with_remote_files';
160
- stainlessProject: string;
161
- apiKey: string;
162
- version: VersionUserConfig;
310
+ return resolveSpec.fromStainlessApi({
311
+ stainlessProject: partial.stainlessProject,
312
+ branch: partial.versions?.[0]?.branch ?? 'main',
313
+ apiKey: apiKey,
314
+ languageOverrides: {
315
+ mode: 'exclude',
316
+ list: excludedLanguages,
317
+ },
318
+ });
319
+ }
320
+
321
+ const resolver = getResolver();
322
+
323
+ return {
324
+ loadSpecs: async function loadSpecs() {
325
+ const inputs = await resolver.resolve({ apiKey });
326
+
327
+ const result = await specCache.get(inputs);
328
+
329
+ return [result];
330
+ },
331
+ };
332
+ }
333
+
334
+ function loadAPIConfig(
335
+ partial: SomeStainlessStarlightUserConfig,
336
+ astroOptions: AstroOptions,
337
+ ): ResolvedAPIConfigEntry {
338
+ if (partial.advanced?.overrideSpecs) {
339
+ const overrides = partial.advanced.overrideSpecs;
340
+ const apiKey = loadApiKey(partial.apiKey);
341
+ return {
342
+ loadSpecs: async function loadSpecs() {
343
+ const specsPromises = overrides.specs.map(async (spec) => {
344
+ const inputs = await spec.resolve({ apiKey });
345
+ return await specCache.get(inputs);
346
+ });
347
+
348
+ return await Promise.all(specsPromises);
349
+ },
163
350
  };
351
+ }
352
+ return makeSimpleAPIConfig(partial, astroOptions);
353
+ }
164
354
 
165
- function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: AstroCommand) {
355
+ function normalizeConfig(partial: SomeStainlessStarlightUserConfig, astroOptions: AstroOptions) {
166
356
  const configWithDefaults = {
167
357
  basePath: partial.basePath ?? '/api',
358
+ astroBase: astroOptions.base,
168
359
  excludeLanguages: partial.excludeLanguages ?? [],
169
360
  defaultLanguage: partial.defaultLanguage ?? 'http',
170
361
  breadcrumbs: {
@@ -181,85 +372,46 @@ function normalizeConfig(partial: SomeStainlessStarlightUserConfig, command: Ast
181
372
  layout: partial.contentPanel?.layout ?? 'double-pane',
182
373
  },
183
374
  experimentalCollapsibleSnippets: partial.experimentalCollapsibleSnippets ?? false,
375
+ experimentalCollapsibleMethodDescriptions: partial.experimentalCollapsibleMethodDescriptions ?? false,
184
376
  propertySettings: {
185
377
  types: partial.propertySettings?.types ?? 'rich',
186
378
  collapseDescription: partial.propertySettings?.collapseDescription ?? true,
379
+ showTitle: partial.propertySettings?.showTitle ?? false,
187
380
  expandDepth: partial.propertySettings?.expandDepth ?? 0,
188
381
  includeModelProperties: partial.propertySettings?.includeModelProperties ?? true,
189
382
  },
190
- search: {
191
- enableAISearch: partial.search?.enableAISearch ?? false,
192
- },
383
+ contextMenu: partial.contextMenu ?? true,
384
+ experimentalPlaygrounds: partial.experimentalPlaygrounds ?? undefined,
385
+ experimentalRequestBuilder: partial.experimentalRequestBuilder ?? false,
386
+ experimentalPrerender: partial.experimentalPrerender ?? true,
387
+ stainlessProject: partial.stainlessProject,
193
388
  };
194
389
 
195
- function getSpecRetrieverConfig(): SpecRetrieverConfig {
196
- if ('externalSpecServerUrl' in partial) {
197
- return {
198
- kind: 'external_spec_server',
199
- specServerUrl: partial.externalSpecServerUrl,
200
- stainlessProject: null,
201
- };
202
- }
203
-
204
- if (!('stainlessProject' in partial)) {
205
- throw new Error('You must provide a stainlessProject when using Stainless Starlight');
206
- }
207
-
208
- const apiKey = partial.apiKey ?? process.env.STAINLESS_API_KEY ?? null;
209
-
210
- const version = {
211
- stainlessProject: partial.stainlessProject,
212
- branch: partial.versions?.[0]?.branch ?? 'main',
213
- version: partial.versions?.[0]?.version ?? 'v1',
214
- };
215
-
216
- const localFilePaths = getLocalFilePaths(command);
217
- if (localFilePaths) {
218
- return {
219
- kind: 'local_spec_server_with_files',
220
- devPaths: localFilePaths,
221
- stainlessProject: partial.stainlessProject,
222
- apiKey,
223
- version,
224
- };
225
- }
226
-
227
- if (!apiKey) {
228
- throw new Error(
229
- 'Please provide a Stainless API key via the STAINLESS_API_KEY environment variable or the apiKey option in the Stainless Starlight config.',
230
- );
231
- }
232
-
233
- return {
234
- kind: 'local_spec_server_with_remote_files',
235
- apiKey,
236
- stainlessProject: partial.stainlessProject,
237
- version,
238
- };
239
- }
240
-
241
- const specRetrieverConfig = getSpecRetrieverConfig();
390
+ const api = loadAPIConfig(partial, astroOptions);
242
391
 
243
392
  return {
244
393
  ...configWithDefaults,
245
- specRetrieverConfig,
394
+ api,
246
395
  };
247
396
  }
248
397
 
249
398
  export type NormalizedStainlessStarlightConfig = ReturnType<typeof normalizeConfig>;
250
399
 
251
400
  /*
252
- The goal of the code in this file is to take a user's config and normalize it.
401
+ The goal of the code in this file is to take a user's config and normalize it.
253
402
  Specifically: we want a single complete config format used throughout the internals of the plugin.
254
403
 
255
404
  We've tried to avoid any config values being optional/undefined. To accomplish this:
256
- - Any optional config values should have their defaults set here: eg. basePath defaults to /api
257
- - If a field is only used in certain contexts, we make each context a discriminated union (see SpecRetrieverConfig)
405
+ - Any optional config values should have their defaults set here: eg. basePath defaults to /api
406
+ - If a field is only used in certain contexts, we make each context a discriminated union (see SDKJSONInputs)
258
407
  - We prefer empty arrays over undefined/null
259
408
  */
260
- export function parseStarlightPluginConfig(partial: SomeStainlessStarlightUserConfig, command: AstroCommand) {
409
+ export function parseStarlightPluginConfig(
410
+ partial: SomeStainlessStarlightUserConfig,
411
+ astroOptions: AstroOptions,
412
+ ) {
261
413
  try {
262
- const config = normalizeConfig(partial, command);
414
+ const config = normalizeConfig(partial, astroOptions);
263
415
  return {
264
416
  result: 'success' as const,
265
417
  config,
@@ -1,4 +1,4 @@
1
- import type { TransformRequestSnippetFn } from '@stainless-api/docs-ui/src/components/sdk';
1
+ import type { TransformRequestSnippetFn } from '@stainless-api/docs-ui/components/sdk';
2
2
 
3
3
  export type StlStarlightMiddleware = {
4
4
  transformRequestSnippet?: TransformRequestSnippetFn;