@stainless-api/docs 0.1.0-beta.135 → 0.1.0-beta.136

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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @stainless-api/docs
2
2
 
3
+ ## 0.1.0-beta.136
4
+
5
+ ### Minor Changes
6
+
7
+ - 5a6e598: [og image] migrate Takumi to v1
8
+
9
+ ### Patch Changes
10
+
11
+ - 8b7aaff: Adds markdown representation for overview
12
+ - 23bd8f7: Update preview worker
13
+
3
14
  ## 0.1.0-beta.135
4
15
 
5
16
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stainless-api/docs",
3
- "version": "0.1.0-beta.135",
3
+ "version": "0.1.0-beta.136",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -38,14 +38,14 @@
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@astrojs/starlight": ">=0.38.0",
41
- "@takumi-rs/image-response": ">=0.66.6",
41
+ "takumi-js": ">=1.0.5",
42
42
  "astro": ">=6.0.0",
43
43
  "react": ">=19.0.0",
44
44
  "react-dom": ">=19.0.0",
45
45
  "vite": ">=7.3.1"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
- "@takumi-rs/image-response": {
48
+ "takumi-js": {
49
49
  "optional": true
50
50
  }
51
51
  },
@@ -57,8 +57,8 @@
57
57
  "@streamparser/json-whatwg": "^0.0.22",
58
58
  "cheerio": "^1.2.0",
59
59
  "clsx": "^2.1.1",
60
- "dotenv": "17.4.1",
61
- "lucide-react": "^0.577.0",
60
+ "dotenv": "17.4.2",
61
+ "lucide-react": "^1.8.0",
62
62
  "motion": "^12.38.0",
63
63
  "node-html-parser": "^7.1.0",
64
64
  "rehype-parse": "^9.0.1",
@@ -78,12 +78,12 @@
78
78
  },
79
79
  "devDependencies": {
80
80
  "@astrojs/check": "^0.9.8",
81
- "@takumi-rs/image-response": "^0.73.1",
81
+ "takumi-js": "^1.0.11",
82
82
  "@types/node": "24.12.2",
83
83
  "@types/react": "19.2.14",
84
84
  "@types/react-dom": "^19.2.3",
85
85
  "@types/react-syntax-highlighter": "^15.5.13",
86
- "astro": "^6.1.5",
86
+ "astro": "^6.1.7",
87
87
  "react": "^19.2.5",
88
88
  "react-dom": "^19.2.5",
89
89
  "typescript": "6.0.2",
package/plugin/index.ts CHANGED
@@ -135,6 +135,12 @@ function stlStarlightAstroIntegration(pluginConfig: NormalizedStainlessStarlight
135
135
  prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
136
136
  });
137
137
 
138
+ injectRoute({
139
+ pattern: `${pluginConfig.basePath}/index.md`,
140
+ entrypoint: resolveSrcFile('/plugin/routes/markdown.ts'),
141
+ prerender: pluginConfig.experimentalPrerender ? command === 'build' : false,
142
+ });
143
+
138
144
  const astroFile = command === 'build' ? 'DocsStatic' : 'Docs';
139
145
  injectRoute({
140
146
  pattern: `${pluginConfig.basePath}/[...slug]`,
@@ -29,7 +29,7 @@ const metadata: SpecMetadata = langsWithSpecs.map(({ language, spec }) => [
29
29
 
30
30
  // PageTitle override will skip rendering the default Starlight title
31
31
  Astro.locals._stlStarlightPage = {
32
- hasMarkdownRoute: false,
32
+ hasMarkdownRoute: true,
33
33
  };
34
34
  ---
35
35
 
@@ -1,14 +1,23 @@
1
1
  import type { APIRoute, GetStaticPaths } from 'astro';
2
+ import type { Node } from '@markdoc/markdoc';
2
3
  import { getReadmeContent } from '../react/Routing';
3
- import { getResourceFromSpec } from '@stainless-api/docs-ui/utils';
4
+ import { getResourceFromSpec, isResourceEmpty } from '@stainless-api/docs-ui/utils';
4
5
 
5
6
  import { renderMarkdown } from '@stainless-api/docs-ui/markdown';
7
+ import * as md from '@stainless-api/docs-ui/markdown/md';
6
8
 
7
- import { parseStainlessPath, type DocsLanguage } from '@stainless-api/docs-ui/routing';
9
+ import { parseStainlessPath, generateRoute, type DocsLanguage } from '@stainless-api/docs-ui/routing';
8
10
  import type { EnvironmentType } from '@stainless-api/docs-ui/markdown/utils';
9
- import { PROPERTY_SETTINGS, MIDDLEWARE } from 'virtual:stl-starlight-virtual-module';
11
+ import {
12
+ PROPERTY_SETTINGS,
13
+ MIDDLEWARE,
14
+ RESOLVED_API_REFERENCE_PATH,
15
+ } from 'virtual:stl-starlight-virtual-module';
10
16
  import { generateAllDocsRoutes } from '../helpers/generateDocsRoutes';
11
17
  import { getSDKJSONInSSR } from '../specs/fetchSpecSSR';
18
+ import Markdoc from '@markdoc/markdoc';
19
+ import type * as SDKJSON from '@stainless/sdk-json';
20
+ import { API_REFERENCE_BASE_PATH } from 'virtual:stl-docs-virtual-module';
12
21
 
13
22
  type RouteProps = {
14
23
  stainlessPath: string;
@@ -21,20 +30,41 @@ export const getStaticPaths = (async () => {
21
30
  return paths;
22
31
  }) satisfies GetStaticPaths;
23
32
 
24
- export const GET: APIRoute<RouteProps> = async ({ props }) => {
25
- const spec = await getSDKJSONInSSR(props.language);
33
+ function renderLink(stainlessPath: string, title: string) {
34
+ const href = generateRoute(RESOLVED_API_REFERENCE_PATH, 'http', stainlessPath);
35
+ return href ? md.link(`${href}/index.md`, title) : md.text(title);
36
+ }
26
37
 
27
- if (props.kind === 'readme') {
28
- const readmeContent = await getReadmeContent(spec, props.language);
29
- return new Response(readmeContent, {
30
- headers: { 'Content-Type': 'text/plain' },
31
- });
38
+ function renderOverviewResource(resource: SDKJSON.Resource, topLevel: boolean): Node[] {
39
+ const link = renderLink(resource.stainlessPath, resource.title);
40
+
41
+ const methodItems = Object.values(resource.methods).map((method) =>
42
+ md.item(md.paragraph(renderLink(method.stainlessPath, method.title))),
43
+ );
44
+
45
+ const subItems = Object.values(resource.subresources ?? {})
46
+ .filter((sub) => !isResourceEmpty(sub))
47
+ .flatMap((sub) => renderOverviewResource(sub, false));
48
+
49
+ const nestedItems = [...methodItems, ...subItems];
50
+ const list = nestedItems.length > 0 ? [md.list(...nestedItems)] : [];
51
+
52
+ return topLevel ? [md.heading(2, [link]), ...list] : [md.item(md.paragraph(link), ...list)];
53
+ }
54
+
55
+ function renderOverview({ spec }: EnvironmentType): string {
56
+ const output: Node[] = [md.heading(1, 'API Reference')];
57
+
58
+ for (const resource of Object.values(spec.resources)) {
59
+ if (!isResourceEmpty(resource)) output.push(...renderOverviewResource(resource, true));
32
60
  }
33
61
 
34
- const parsed = parseStainlessPath(props.stainlessPath);
35
- const resource = getResourceFromSpec(props.stainlessPath, spec);
62
+ const doc = new Markdoc.Ast.Node('document', {}, output);
63
+ return Markdoc.format(doc);
64
+ }
36
65
 
37
- if (!resource) throw new Error('Invalid route');
66
+ export const GET: APIRoute<RouteProps> = async ({ props, routePattern }) => {
67
+ const spec = await getSDKJSONInSSR(props.language ?? 'http');
38
68
 
39
69
  const env: EnvironmentType = {
40
70
  spec,
@@ -48,6 +78,25 @@ export const GET: APIRoute<RouteProps> = async ({ props }) => {
48
78
  },
49
79
  };
50
80
 
81
+ if (routePattern === `${API_REFERENCE_BASE_PATH}/index.md`) {
82
+ const content = renderOverview({ ...env, language: 'http' });
83
+ return new Response(content, {
84
+ headers: { 'Content-Type': 'text/plain' },
85
+ });
86
+ }
87
+
88
+ if (props.kind === 'readme') {
89
+ const readmeContent = await getReadmeContent(spec, props.language);
90
+ return new Response(readmeContent, {
91
+ headers: { 'Content-Type': 'text/plain' },
92
+ });
93
+ }
94
+
95
+ const parsed = parseStainlessPath(props.stainlessPath);
96
+ const resource = getResourceFromSpec(props.stainlessPath, spec);
97
+
98
+ if (!resource) throw new Error('Invalid route');
99
+
51
100
  const target = props.kind === 'http_method' && parsed?.method ? resource.methods[parsed.method]! : resource;
52
101
  const output = renderMarkdown(env, target);
53
102