@stainless-api/docs 0.1.0-beta.0

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 (119) hide show
  1. package/.env.example +1 -0
  2. package/CHANGELOG.md +13 -0
  3. package/README.md +11 -0
  4. package/components/variables.css +139 -0
  5. package/eslint.config.js +10 -0
  6. package/package.json +74 -0
  7. package/plugin/assets/fonts/geist/OFL.txt +93 -0
  8. package/plugin/assets/fonts/geist/geist-italic-latin-ext.woff2 +0 -0
  9. package/plugin/assets/fonts/geist/geist-italic-latin.woff2 +0 -0
  10. package/plugin/assets/fonts/geist/geist-latin-ext.woff2 +0 -0
  11. package/plugin/assets/fonts/geist/geist-latin.woff2 +0 -0
  12. package/plugin/assets/fonts/geist/geist-mono-italic-latin-ext.woff2 +0 -0
  13. package/plugin/assets/fonts/geist/geist-mono-italic-latin.woff2 +0 -0
  14. package/plugin/assets/fonts/geist/geist-mono-latin-ext.woff2 +0 -0
  15. package/plugin/assets/fonts/geist/geist-mono-latin.woff2 +0 -0
  16. package/plugin/assets/languages/curl.svg +10 -0
  17. package/plugin/assets/languages/go.svg +4 -0
  18. package/plugin/assets/languages/java.svg +7 -0
  19. package/plugin/assets/languages/kotlin.svg +10 -0
  20. package/plugin/assets/languages/powershell.svg +3 -0
  21. package/plugin/assets/languages/python.svg +19 -0
  22. package/plugin/assets/languages/ruby.svg +125 -0
  23. package/plugin/assets/languages/terraform.svg +5 -0
  24. package/plugin/assets/languages/typescript.svg +11 -0
  25. package/plugin/assets/stainless-logo-dark.png +0 -0
  26. package/plugin/assets/stainless-logo.png +0 -0
  27. package/plugin/buildAlgoliaIndex.ts +72 -0
  28. package/plugin/cms/client.ts +62 -0
  29. package/plugin/cms/server.ts +268 -0
  30. package/plugin/cms/sidebar-builder.ts +420 -0
  31. package/plugin/cms/worker.ts +122 -0
  32. package/plugin/components/SDKSelect.astro +154 -0
  33. package/plugin/components/SnippetCode.tsx +212 -0
  34. package/plugin/components/search/Search.astro +6 -0
  35. package/plugin/components/search/SearchAlgolia.astro +87 -0
  36. package/plugin/components/search/SearchIsland.tsx +100 -0
  37. package/plugin/generateAPIReferenceLink.ts +71 -0
  38. package/plugin/globalJs/ai-dropdown.ts +57 -0
  39. package/plugin/globalJs/code-snippets.ts +87 -0
  40. package/plugin/globalJs/copy.ts +37 -0
  41. package/plugin/globalJs/navigation.ts +81 -0
  42. package/plugin/globalJs/tooltip.ts +32 -0
  43. package/plugin/helpers/getPageLoadEvent.ts +8 -0
  44. package/plugin/index.ts +308 -0
  45. package/plugin/languages.ts +67 -0
  46. package/plugin/loadPluginConfig.ts +273 -0
  47. package/plugin/middlewareBuilder/stainlessMiddleware.d.ts +5 -0
  48. package/plugin/middlewareBuilder/stlStarlightMiddleware.ts +5 -0
  49. package/plugin/react/Routing.tsx +435 -0
  50. package/plugin/referencePlaceholderUtils.ts +82 -0
  51. package/plugin/replaceSidebarPlaceholderMiddleware.ts +50 -0
  52. package/plugin/routes/Docs.astro +171 -0
  53. package/plugin/routes/DocsStatic.astro +14 -0
  54. package/plugin/routes/Overview.astro +67 -0
  55. package/plugin/routes/markdown.ts +58 -0
  56. package/plugin/vendor/preview.worker.docs.js +21657 -0
  57. package/plugin/vendor/templates/go.md +314 -0
  58. package/plugin/vendor/templates/java.md +87 -0
  59. package/plugin/vendor/templates/kotlin.md +87 -0
  60. package/plugin/vendor/templates/node.md +233 -0
  61. package/plugin/vendor/templates/python.md +249 -0
  62. package/plugin/vendor/templates/ruby.md +145 -0
  63. package/plugin/vendor/templates/terraform.md +60 -0
  64. package/plugin/vendor/templates/typescript.md +317 -0
  65. package/scripts/vendor_deps.ts +50 -0
  66. package/shared/virtualModule.ts +7 -0
  67. package/stl-docs/components/APIReferenceAIDropdown.tsx +86 -0
  68. package/stl-docs/components/ClientRouterHead.astro +41 -0
  69. package/stl-docs/components/Header.astro +91 -0
  70. package/stl-docs/components/Sidebar.astro +11 -0
  71. package/stl-docs/components/ThemeSelect.astro +225 -0
  72. package/stl-docs/components/content-panel/ContentBreadcrumbs.tsx +84 -0
  73. package/stl-docs/components/content-panel/ContentPanel.astro +72 -0
  74. package/stl-docs/components/content-panel/ProseAIDropdown.tsx +64 -0
  75. package/stl-docs/components/headers/DefaultHeader.astro +36 -0
  76. package/stl-docs/components/headers/HeaderLinks.astro +16 -0
  77. package/stl-docs/components/headers/SplashMobileMenuToggle.astro +49 -0
  78. package/stl-docs/components/headers/StackedHeader.astro +75 -0
  79. package/stl-docs/components/mintlify-compat/Accordion.astro +46 -0
  80. package/stl-docs/components/mintlify-compat/AccordionGroup.astro +25 -0
  81. package/stl-docs/components/mintlify-compat/Card.tsx +32 -0
  82. package/stl-docs/components/mintlify-compat/Columns.astro +66 -0
  83. package/stl-docs/components/mintlify-compat/Frame.astro +37 -0
  84. package/stl-docs/components/mintlify-compat/Step.astro +58 -0
  85. package/stl-docs/components/mintlify-compat/Steps.astro +17 -0
  86. package/stl-docs/components/mintlify-compat/Tab.astro +13 -0
  87. package/stl-docs/components/mintlify-compat/Tabs.astro +7 -0
  88. package/stl-docs/components/mintlify-compat/callouts/Callout.astro +7 -0
  89. package/stl-docs/components/mintlify-compat/callouts/Check.astro +7 -0
  90. package/stl-docs/components/mintlify-compat/callouts/Danger.astro +7 -0
  91. package/stl-docs/components/mintlify-compat/callouts/Info.astro +7 -0
  92. package/stl-docs/components/mintlify-compat/callouts/Note.astro +7 -0
  93. package/stl-docs/components/mintlify-compat/callouts/Tip.astro +7 -0
  94. package/stl-docs/components/mintlify-compat/callouts/Warning.astro +7 -0
  95. package/stl-docs/components/mintlify-compat/callouts/index.ts +9 -0
  96. package/stl-docs/components/mintlify-compat/card.css +44 -0
  97. package/stl-docs/components/mintlify-compat/index.ts +15 -0
  98. package/stl-docs/components/nav-tabs/NavDropdown.astro +106 -0
  99. package/stl-docs/components/nav-tabs/NavTabs.astro +165 -0
  100. package/stl-docs/components/nav-tabs/SecondaryNavTabs.astro +62 -0
  101. package/stl-docs/components/nav-tabs/buildNavLinks.ts +14 -0
  102. package/stl-docs/index.ts +174 -0
  103. package/stl-docs/loadStlDocsConfig.ts +160 -0
  104. package/stl-docs/redirects.ts +33 -0
  105. package/stl-docs/tabsMiddleware.ts +183 -0
  106. package/styles/code.css +189 -0
  107. package/styles/fonts.css +68 -0
  108. package/styles/links.css +51 -0
  109. package/styles/mintlify-compat.css +1 -0
  110. package/styles/overrides.css +79 -0
  111. package/styles/page.css +76 -0
  112. package/styles/sdk_select.css +11 -0
  113. package/styles/search.css +85 -0
  114. package/styles/sidebar.css +168 -0
  115. package/styles/toc.css +42 -0
  116. package/styles/variables.css +18 -0
  117. package/theme.css +15 -0
  118. package/tsconfig.json +18 -0
  119. package/virtual-module.d.ts +43 -0
@@ -0,0 +1,81 @@
1
+ import { parseRoute, scrollToPath } from '@stainless-api/docs-ui/src/routing';
2
+ import { BASE_PATH } from 'virtual:stl-starlight-virtual-module';
3
+ import { updateSelectedLanguage } from '../languages';
4
+ import { navigate } from 'astro:transitions/client';
5
+ import { getPageLoadEvent } from '../helpers/getPageLoadEvent.ts';
6
+
7
+ import { initDropdown } from '@stainless-api/docs-ui/src/components/scripts/dropdown';
8
+ import { initDropdownButton } from '@stainless-api/ui-primitives/scripts';
9
+ import { copyCurrentPageAsMarkdown, onSelectAIOption } from './ai-dropdown.ts';
10
+
11
+ history.scrollRestoration = 'auto';
12
+
13
+ function getStainlessPathForLocation() {
14
+ return document.location.hash
15
+ ? decodeURI(document.location.hash)
16
+ : parseRoute(BASE_PATH, document.location.href)?.stainlessPath;
17
+ }
18
+
19
+ window.addEventListener('popstate', (ev: PopStateEvent) => {
20
+ const path = getStainlessPathForLocation();
21
+ if (!path) return;
22
+ ev.preventDefault();
23
+ setTimeout(() => scrollToPath(path.slice(1)), 10);
24
+ });
25
+
26
+ document.addEventListener(getPageLoadEvent(), () => {
27
+ initDropdown({
28
+ dropdownId: 'stldocs-snippet-select',
29
+ onSelect: (value) => {
30
+ const originalLanguage = document.getElementById('stldocs-snippet-select')?.dataset.currentValue;
31
+ navigate(updateSelectedLanguage(BASE_PATH, originalLanguage, value));
32
+ },
33
+ });
34
+
35
+ const path = getStainlessPathForLocation();
36
+ if (path) setTimeout(() => scrollToPath(path.slice(1)), 10);
37
+ });
38
+
39
+ document.addEventListener(getPageLoadEvent(), () => {
40
+ console.log('Initializing AI Dropdown');
41
+ initDropdownButton({
42
+ dropdownId: 'ai-dropdown-button',
43
+ onSelect: onSelectAIOption,
44
+ onPrimaryAction: (el) => {
45
+ copyCurrentPageAsMarkdown();
46
+ const innerText = el.querySelector('[data-part="primary-action-text"]');
47
+ if (!innerText) return;
48
+
49
+ const originalInnerHtml = innerText.innerHTML;
50
+ innerText.innerHTML = 'Copied!';
51
+ el.classList.add('disabled');
52
+ setTimeout(() => {
53
+ innerText.innerHTML = originalInnerHtml;
54
+ el.classList.remove('disabled');
55
+ }, 1000);
56
+ },
57
+ });
58
+ });
59
+
60
+ document.addEventListener('click', (event) => {
61
+ const toggle = (event.target as HTMLElement).closest(
62
+ '[data-stldocs-property-toggle-expanded] > .stldocs-expand-toggle-content',
63
+ )?.parentElement;
64
+
65
+ if (!toggle) return;
66
+
67
+ const state = toggle.dataset.stldocsPropertyToggleExpanded === 'true';
68
+ toggle.dataset.stldocsPropertyToggleExpanded = state ? 'false' : 'true';
69
+
70
+ const targetGroup = toggle.dataset.stldocsPropertyToggleTarget;
71
+ if (!targetGroup) return;
72
+
73
+ const target = document.querySelector(`[data-stldocs-property-group=${targetGroup}]`);
74
+ if (!target) return;
75
+
76
+ target.querySelectorAll('details').forEach((details) => {
77
+ const el = details as HTMLDetailsElement;
78
+ const initial = el.dataset.stldocsExpanderInitialState;
79
+ el.open = initial === 'true' ? true : !state;
80
+ });
81
+ });
@@ -0,0 +1,32 @@
1
+ window.addEventListener('DOMContentLoaded', () => {
2
+ document.querySelectorAll('.stldocs-tooltip').forEach((tooltip) => {
3
+ const target = tooltip.querySelector<HTMLDivElement>('.stldocs-tooltip-host');
4
+
5
+ const content = tooltip.querySelector<HTMLDivElement>('.stldocs-tooltip-content');
6
+
7
+ if (!target || !content) return;
8
+
9
+ target.addEventListener('mouseenter', () => {
10
+ const targetRect = target.getBoundingClientRect();
11
+ const contentRect = content.getBoundingClientRect();
12
+
13
+ let top = targetRect.bottom + window.scrollY;
14
+ let left = targetRect.left + window.scrollX;
15
+
16
+ if (targetRect.bottom + contentRect.height > window.innerHeight) {
17
+ top = targetRect.top + window.scrollY - contentRect.height;
18
+ }
19
+
20
+ if (targetRect.left + contentRect.width > window.innerWidth) {
21
+ left = targetRect.right + window.scrollX - contentRect.width;
22
+ }
23
+
24
+ if (left < window.scrollX) {
25
+ left = window.scrollX;
26
+ }
27
+
28
+ content.style.top = `${top}px`;
29
+ content.style.left = `${left}px`;
30
+ });
31
+ });
32
+ });
@@ -0,0 +1,8 @@
1
+ // import { ENABLE_CLIENT_ROUTER } from 'virtual:stl-stl-starlight-virtual-module';
2
+
3
+ export function getPageLoadEvent() {
4
+ // if (ENABLE_CLIENT_ROUTER) {
5
+ // return 'astro:page-load';
6
+ // }
7
+ return 'DOMContentLoaded';
8
+ }
@@ -0,0 +1,308 @@
1
+ import react from '@astrojs/react';
2
+ import type { StarlightPlugin } from '@astrojs/starlight/types';
3
+ import type { AstroIntegration } from 'astro';
4
+ import { config } from 'dotenv';
5
+ import getPort from 'get-port';
6
+ import { startDevServer } from './cms/server';
7
+ import { buildAlgoliaIndex } from './buildAlgoliaIndex';
8
+ import {
9
+ getAPIReferencePlaceholderItemFromSidebarConfig,
10
+ makePlaceholderItems,
11
+ } from './referencePlaceholderUtils';
12
+ import type {
13
+ GeneratedSidebarConfig,
14
+ ReferenceSidebarConfigGenerateOptions,
15
+ ReferenceSidebarConfigItem,
16
+ } from './cms/sidebar-builder';
17
+ import {
18
+ parseStarlightPluginConfig,
19
+ type NormalizedStainlessStarlightConfig,
20
+ type SomeStainlessStarlightUserConfig,
21
+ type SpecRetrieverConfig,
22
+ } from './loadPluginConfig';
23
+ import { buildVirtualModuleString } from '../shared/virtualModule';
24
+ import path from 'path';
25
+ import fs from 'fs';
26
+
27
+ export { generateAPILink } from './generateAPIReferenceLink';
28
+ export type { ReferenceSidebarConfigItem };
29
+
30
+ config();
31
+
32
+ let sidebarIdCounter = 0;
33
+
34
+ const sidebarConfigs = new Map<number, GeneratedSidebarConfig>();
35
+
36
+ type PlaceholderEntries = {
37
+ label: string;
38
+ link: string;
39
+ attrs?: any; // tbd what type this should be. I sort of don't want to say what it _really_ is, bc I don't want people messing with it
40
+ }[];
41
+
42
+ /**
43
+ * This returns placeholder entries that indicate where the API reference items should be inserted.
44
+ * The placeholder entries are replaced with the actual API reference items by the Stainless Starlight plugin.
45
+ *
46
+ * You may place the placeholders wherever you want your API reference items to be inserted.
47
+ *
48
+ * **IMPORTANT:** DO NOT MODIFY THESE ENTRIES. Doing so will prevent items from being inserted correctly.
49
+ */
50
+
51
+ type SidebarTransformFn = GeneratedSidebarConfig['transformFn'];
52
+
53
+ export function generateAPIReferenceItems(
54
+ options: ReferenceSidebarConfigGenerateOptions,
55
+ fn?: SidebarTransformFn,
56
+ ): PlaceholderEntries;
57
+ export function generateAPIReferenceItems(fn?: SidebarTransformFn): PlaceholderEntries;
58
+ export function generateAPIReferenceItems(
59
+ arg1: SidebarTransformFn | ReferenceSidebarConfigGenerateOptions,
60
+ arg2?: SidebarTransformFn,
61
+ ): PlaceholderEntries {
62
+ sidebarIdCounter++;
63
+ const id = sidebarIdCounter;
64
+
65
+ let fn: SidebarTransformFn | undefined;
66
+ if (typeof arg1 === 'function') {
67
+ fn = arg1;
68
+ } else if (typeof arg2 === 'function') {
69
+ fn = arg2;
70
+ }
71
+
72
+ let options: ReferenceSidebarConfigGenerateOptions | undefined;
73
+ if (typeof arg1 === 'object') {
74
+ options = arg1;
75
+ }
76
+
77
+ sidebarConfigs.set(id, { transformFn: fn, options });
78
+ return makePlaceholderItems(id);
79
+ }
80
+
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
+ async function stlStarlightAstroIntegration(
110
+ pluginConfig: NormalizedStainlessStarlightConfig,
111
+ ): Promise<AstroIntegration> {
112
+ const virtualId = `virtual:stl-starlight-virtual-module`;
113
+ // The '\0' prefix tells Vite “this is a virtual module” and prevents it from being resolved again.
114
+ const resolvedId = `\0${virtualId}`;
115
+
116
+ const CMS_PORT = await getPort();
117
+
118
+ const { apiKey, version, devPaths } = tmpGetCMSServerConfig(pluginConfig.specRetrieverConfig);
119
+
120
+ const cmsServer = await startDevServer({
121
+ port: CMS_PORT,
122
+ apiKey,
123
+ version,
124
+ devPaths,
125
+ getGeneratedSidebarConfig: (id: number) => {
126
+ const config = sidebarConfigs.get(id);
127
+ if (!config) {
128
+ return null;
129
+ }
130
+ return config;
131
+ },
132
+ });
133
+
134
+ return {
135
+ name: 'stl-starlight-astro',
136
+ hooks: {
137
+ 'astro:config:setup': async ({ injectRoute, updateConfig, logger, command, config: astroConfig }) => {
138
+ const projectDir = astroConfig.root.pathname;
139
+
140
+ const middlewareFile = path.join(projectDir, 'middleware.stainless.ts');
141
+
142
+ let vmMiddlewareExport = 'export const MIDDLEWARE = {};';
143
+ if (fs.existsSync(middlewareFile)) {
144
+ logger.info(`Loading middleware from ${middlewareFile}`);
145
+ vmMiddlewareExport = `export { default as MIDDLEWARE } from '${middlewareFile}';`;
146
+ }
147
+
148
+ injectRoute({
149
+ pattern: `${pluginConfig.basePath}/[...slug].md`,
150
+ entrypoint: '@stainless-api/docs/MarkdownRoute',
151
+ prerender: command === 'build',
152
+ });
153
+
154
+ const astroFile = command === 'build' ? 'DocsStaticRoute' : 'DocsRoute';
155
+ injectRoute({
156
+ pattern: `${pluginConfig.basePath}/[...slug]`,
157
+ // in prod I think this points to @stainless-starlight/components/docs.astro
158
+ entrypoint: `@stainless-api/docs/${astroFile}`,
159
+ prerender: command === 'build',
160
+ });
161
+
162
+ injectRoute({
163
+ pattern: pluginConfig.basePath,
164
+ entrypoint: '@stainless-api/docs/OverviewRoute',
165
+ prerender: command === 'build',
166
+ });
167
+
168
+ updateConfig({
169
+ vite: {
170
+ ssr: {
171
+ noExternal: ['@stainless-api/ui-primitives'],
172
+ },
173
+ optimizeDeps: { include: ['@stainless-api/ui-primitives'] },
174
+ plugins: [
175
+ {
176
+ name: 'stl-starlight-vite',
177
+ configureServer(server) {
178
+ for (const filePath of Object.values(devPaths)) {
179
+ if (!filePath) {
180
+ continue;
181
+ }
182
+ server.watcher.add(filePath);
183
+ }
184
+
185
+ server.watcher.on('change', async (changed) => {
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
+ });
195
+ },
196
+ resolveId(id) {
197
+ if (id === virtualId) {
198
+ return resolvedId;
199
+ }
200
+ },
201
+ load(id) {
202
+ if (id === resolvedId) {
203
+ return [
204
+ buildVirtualModuleString({
205
+ BASE_PATH: pluginConfig.basePath,
206
+ CMS_PORT,
207
+ EXCLUDE_LANGUAGES: pluginConfig.excludeLanguages,
208
+ DEFAULT_LANGUAGE: pluginConfig.defaultLanguage,
209
+ BREADCRUMB_CONFIG: pluginConfig.breadcrumbs,
210
+ EXPAND_RESOURCES: pluginConfig.expandResources,
211
+ HIGHLIGHT_THEMES: pluginConfig.highlighting.themes,
212
+ CONTENT_PANEL_LAYOUT: pluginConfig.contentPanel.layout,
213
+ EXPERIMENTAL_COLLAPSIBLE_SNIPPETS: pluginConfig.experimentalCollapsibleSnippets,
214
+ PROPERTY_SETTINGS: pluginConfig.propertySettings,
215
+ SEARCH: pluginConfig.search,
216
+ }),
217
+ vmMiddlewareExport,
218
+ ].join('\n');
219
+ }
220
+ },
221
+ },
222
+ ],
223
+ },
224
+ });
225
+ },
226
+ 'astro:server:done': async () => {
227
+ await cmsServer.destroy();
228
+ },
229
+ },
230
+ };
231
+ }
232
+
233
+ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserConfig): StarlightPlugin {
234
+ return {
235
+ name: 'stl-starlight',
236
+ hooks: {
237
+ 'config:setup': async ({
238
+ addIntegration,
239
+ updateConfig,
240
+ addRouteMiddleware,
241
+ command,
242
+ config: starlightConfig,
243
+ astroConfig,
244
+ logger,
245
+ }) => {
246
+ if (command !== 'build' && command !== 'dev') {
247
+ return;
248
+ }
249
+
250
+ const configParseResult = parseStarlightPluginConfig(someUserConfig, command);
251
+ if (configParseResult.result === 'error') {
252
+ logger.error(configParseResult.message);
253
+ process.exit(1);
254
+ }
255
+ const config = configParseResult.config;
256
+
257
+ const isReactLoaded = astroConfig.integrations.find(({ name }) => name === '@astrojs/react');
258
+
259
+ if (!isReactLoaded) {
260
+ addIntegration(react());
261
+ }
262
+
263
+ if (
264
+ command === 'build' &&
265
+ config.specRetrieverConfig.kind === 'local_spec_server_with_remote_files'
266
+ ) {
267
+ await buildAlgoliaIndex({
268
+ version: config.specRetrieverConfig.version,
269
+ apiKey: config.specRetrieverConfig.apiKey,
270
+ });
271
+ }
272
+
273
+ addIntegration(await stlStarlightAstroIntegration(config));
274
+
275
+ if (starlightConfig.sidebar) {
276
+ // for pagination (https://starlight.astro.build/reference/configuration/#pagination) to work correctly
277
+ // update the placeholder link to be correct
278
+ const item = getAPIReferencePlaceholderItemFromSidebarConfig(starlightConfig.sidebar);
279
+ if (item && typeof item === 'object' && 'link' in item) {
280
+ item.link = config.basePath;
281
+ }
282
+ }
283
+
284
+ const currentExpressiveCode =
285
+ typeof starlightConfig.expressiveCode === 'object' ? starlightConfig.expressiveCode : {};
286
+ updateConfig({
287
+ expressiveCode: {
288
+ ...currentExpressiveCode,
289
+ themes: [...(currentExpressiveCode.themes || []), 'github-light', 'github-dark'],
290
+ },
291
+ });
292
+
293
+ updateConfig({
294
+ sidebar: starlightConfig.sidebar,
295
+ });
296
+
297
+ addRouteMiddleware({
298
+ entrypoint: '@stainless-api/docs/replaceSidebarPlaceholderMiddleware',
299
+ order: 'post',
300
+ });
301
+ },
302
+ },
303
+ };
304
+ }
305
+
306
+ // Additional exports we want for Stainless <-> docs integration.
307
+ export { parseStainlessPath } from '@stainless-api/docs-ui/src/routing';
308
+ export { renderMarkdown } from '@stainless-api/docs-ui/src/markdown';
@@ -0,0 +1,67 @@
1
+ import type { DocsLanguage } from '@stainless-api/docs-ui/src/routing';
2
+ import KotlinIcon from './assets/languages/kotlin.svg';
3
+ import RubyIcon from './assets/languages/ruby.svg';
4
+ import TerraformIcon from './assets/languages/terraform.svg';
5
+ import TypescriptIcon from './assets/languages/typescript.svg';
6
+ import PythonIcon from './assets/languages/python.svg';
7
+ import JavaIcon from './assets/languages/java.svg';
8
+ import GoIcon from './assets/languages/go.svg';
9
+ import CurlIcon from './assets/languages/curl.svg';
10
+
11
+ export const Languages: Record<
12
+ DocsLanguage,
13
+ {
14
+ name: string;
15
+ icon: ((_props: astroHTML.JSX.SVGAttributes) => any) & ImageMetadata;
16
+ alt: string;
17
+ }
18
+ > = {
19
+ node: { name: 'TypeScript', icon: TypescriptIcon, alt: 'Node.js logo' },
20
+ typescript: {
21
+ name: 'TypeScript',
22
+ icon: TypescriptIcon,
23
+ alt: 'TypeScript logo',
24
+ },
25
+ python: { name: 'Python', icon: PythonIcon, alt: 'Python logo' },
26
+ go: { name: 'Go', icon: GoIcon, alt: 'Go logo' },
27
+ java: { name: 'Java', icon: JavaIcon, alt: 'Java logo' },
28
+ kotlin: { name: 'Kotlin', icon: KotlinIcon, alt: 'Kotlin logo' },
29
+ http: { name: 'HTTP', icon: CurlIcon, alt: 'HTTP logo' },
30
+ terraform: { name: 'Terraform', icon: TerraformIcon, alt: 'Terraform logo' },
31
+ ruby: { name: 'Ruby', icon: RubyIcon, alt: 'Ruby logo' },
32
+ };
33
+
34
+ export function generatePrefix(basePath: string, language: string) {
35
+ return language === 'http' ? basePath : [basePath, language].join('/');
36
+ }
37
+
38
+ export function applyLanguageToLinks(basePath?: string, defaultLanguage?: string) {
39
+ const language = localStorage.getItem('stldocs-selected-language') ?? defaultLanguage;
40
+
41
+ if (!basePath || !language || language === 'http') return;
42
+
43
+ const links = document.querySelectorAll(
44
+ `[data-stldocs-overview],[data-stldocs-method],a.nav-link[href^='${basePath}']`,
45
+ );
46
+
47
+ for (var link of links) {
48
+ const href = link.getAttribute('href');
49
+ const prefix = generatePrefix(basePath, language);
50
+ if (href?.startsWith(basePath) && !href?.startsWith(prefix)) {
51
+ const rest = href.slice(basePath.length);
52
+ link.setAttribute('href', prefix + rest);
53
+ }
54
+ }
55
+ }
56
+
57
+ export function updateSelectedLanguage(
58
+ basePath: string,
59
+ previousLanguage: string | undefined,
60
+ newValue: string,
61
+ ) {
62
+ const previous = generatePrefix(basePath, previousLanguage ?? 'http');
63
+ const current = generatePrefix(basePath, newValue ?? 'http');
64
+ const rest = window.location.pathname.slice(previous.length);
65
+ localStorage.setItem('stldocs-selected-language', newValue);
66
+ return current + rest;
67
+ }