@stainless-api/docs 0.1.0-beta.124 → 0.1.0-beta.126

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,25 @@
1
1
  # @stainless-api/docs
2
2
 
3
+ ## 0.1.0-beta.126
4
+
5
+ ### Patch Changes
6
+
7
+ - 992a07a: Update vendored preview worker
8
+ - 1d1fa35: Use astro remark instead of `marked` to process api reference markdown
9
+ - Updated dependencies [374c0e4]
10
+ - @stainless-api/ui-primitives@0.1.0-beta.51
11
+ - @stainless-api/docs-ui@0.1.0-beta.90
12
+ - @stainless-api/docs-search@0.1.0-beta.43
13
+
14
+ ## 0.1.0-beta.125
15
+
16
+ ### Patch Changes
17
+
18
+ - 975ba51: cap prose indexing batches to 30MB
19
+ - Updated dependencies [005419c]
20
+ - @stainless-api/docs-ui@0.1.0-beta.89
21
+ - @stainless-api/docs-search@0.1.0-beta.42
22
+
3
23
  ## 0.1.0-beta.124
4
24
 
5
25
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stainless-api/docs",
3
- "version": "0.1.0-beta.124",
3
+ "version": "0.1.0-beta.126",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -41,15 +41,15 @@
41
41
  "vite": ">=7.3.1"
42
42
  },
43
43
  "dependencies": {
44
- "@astrojs/markdown-remark": "^7.0.1",
45
- "@astrojs/react": "^5.0.1",
44
+ "@astrojs/markdown-remark": "^7.1.0",
45
+ "@astrojs/react": "^5.0.2",
46
+ "@markdoc/markdoc": "^0.5.6",
46
47
  "@stainless-api/sdk": "0.5.0",
47
48
  "astro-expressive-code": "^0.41.7",
48
49
  "cheerio": "^1.2.0",
49
50
  "clsx": "^2.1.1",
50
51
  "dotenv": "17.3.1",
51
52
  "lucide-react": "^0.577.0",
52
- "marked": "^17.0.5",
53
53
  "node-html-parser": "^7.1.0",
54
54
  "rehype-parse": "^9.0.1",
55
55
  "rehype-remark": "^10.0.1",
@@ -60,14 +60,13 @@
60
60
  "unified": "^11.0.5",
61
61
  "vite-plugin-prebundle-workers": "^0.2.0",
62
62
  "web-worker": "^1.5.0",
63
- "yaml": "^2.8.2",
64
- "@stainless-api/docs-search": "0.1.0-beta.41",
65
- "@stainless-api/docs-ui": "0.1.0-beta.88",
66
- "@stainless-api/ui-primitives": "0.1.0-beta.50"
63
+ "yaml": "^2.8.3",
64
+ "@stainless-api/docs-search": "0.1.0-beta.43",
65
+ "@stainless-api/docs-ui": "0.1.0-beta.90",
66
+ "@stainless-api/ui-primitives": "0.1.0-beta.51"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@astrojs/check": "^0.9.8",
70
- "@markdoc/markdoc": "^0.5.6",
71
70
  "@types/node": "24.12.0",
72
71
  "@types/react": "19.2.14",
73
72
  "@types/react-dom": "^19.2.3",
@@ -76,6 +75,7 @@
76
75
  "tsx": "^4.21.0",
77
76
  "typescript": "5.9.3",
78
77
  "vite": "^7.3.1",
78
+ "vitest": "^4.1.2",
79
79
  "zod": "^4.3.6",
80
80
  "@stainless/eslint-config": "0.1.0-beta.1",
81
81
  "@stainless/sdk-json": "^0.1.0-beta.9"
@@ -84,6 +84,7 @@
84
84
  "vendor-deps": "tsx scripts/vendor_deps.ts",
85
85
  "lint": "eslint --flag unstable_native_nodejs_ts_config . --max-warnings 0",
86
86
  "sync": "astro sync",
87
- "check:types": "astro check"
87
+ "check:types": "astro check",
88
+ "test": "vitest run"
88
89
  }
89
90
  }
@@ -0,0 +1,100 @@
1
+ import {
2
+ createHighlighter,
3
+ type HighlighterGeneric,
4
+ type ThemeInput,
5
+ type BundledTheme,
6
+ type BundledLanguage,
7
+ } from 'shiki';
8
+ import { HIGHLIGHT_THEMES } from 'virtual:stl-starlight-virtual-module';
9
+ import { SupportedLanguageSyntaxes } from '@stainless-api/docs-ui/routing';
10
+ import type { CreateShikiHighlighterOptions } from '@astrojs/markdown-remark';
11
+
12
+ const STAINLESS_DOCS_JSON_THEME = {
13
+ name: 'stainless-docs-json',
14
+ colors: {
15
+ 'editor.background': 'var(--stl-color-background)',
16
+ 'editor.foreground': 'var(--stl-color-foreground)',
17
+ },
18
+
19
+ tokenColors: [
20
+ {
21
+ scope: ['comment', 'punctuation.definition.comment'],
22
+ settings: { foreground: 'var(--stl-color-foreground-muted)' },
23
+ },
24
+ // numbers, booleans, null
25
+ {
26
+ scope: ['constant.numeric', 'constant.language'],
27
+ settings: { foreground: 'var(--stl-color-orange-foreground)' },
28
+ },
29
+ // strings
30
+ {
31
+ scope: ['string', 'string.quoted', 'string.template'],
32
+ settings: { foreground: 'var(--stl-color-green-foreground)' },
33
+ },
34
+ // Keys, brackets
35
+ {
36
+ scope: ['support.type', 'meta'],
37
+ settings: { foreground: 'var(--stl-color-foreground)' },
38
+ },
39
+ // brackets
40
+ {
41
+ scope: ['meta'],
42
+ settings: { foreground: 'var(--stl-color-foreground-muted)' },
43
+ },
44
+ // built-in types
45
+ {
46
+ scope: ['support.type.builtin'],
47
+ settings: { foreground: 'var(--stl-color-purple-foreground)' },
48
+ },
49
+ ],
50
+ } satisfies ThemeInput;
51
+
52
+ // singleton
53
+ let astroShikiHighlighter:
54
+ | HighlighterGeneric<BundledLanguage, BundledTheme>
55
+ | Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>
56
+ | null = null;
57
+ export async function getAstroHighlighter() {
58
+ if (astroShikiHighlighter) {
59
+ return astroShikiHighlighter;
60
+ }
61
+
62
+ astroShikiHighlighter = createHighlighter({
63
+ themes: [
64
+ HIGHLIGHT_THEMES?.dark ?? 'github-dark',
65
+ HIGHLIGHT_THEMES?.light ?? 'github-light',
66
+ STAINLESS_DOCS_JSON_THEME,
67
+ ],
68
+ langs: SupportedLanguageSyntaxes,
69
+ });
70
+
71
+ return astroShikiHighlighter;
72
+ }
73
+
74
+ function runHighlight({
75
+ highlighter,
76
+ content,
77
+ language,
78
+ themes,
79
+ }: {
80
+ highlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
81
+ content: string;
82
+ language?: string;
83
+ themes?: CreateShikiHighlighterOptions['themes'] | Record<string, 'stainless-docs-json'>;
84
+ }) {
85
+ return highlighter.codeToHtml(content, {
86
+ lang: language ?? 'javascript',
87
+ themes:
88
+ // Default to user-provided themes except in case of json
89
+ themes ??
90
+ (language === 'JSON'
91
+ ? { light: 'stainless-docs-json', dark: 'stainless-docs-json' }
92
+ : HIGHLIGHT_THEMES) ??
93
+ {},
94
+ });
95
+ }
96
+
97
+ export async function highlight(content: string, language?: string) {
98
+ const highlighter = await getAstroHighlighter();
99
+ return runHighlight({ highlighter, content, language });
100
+ }
@@ -0,0 +1,39 @@
1
+ import { createMarkdownProcessor, type MarkdownProcessor } from '@astrojs/markdown-remark';
2
+ import remarkGfmAlerts from 'remark-github-alerts';
3
+ import { HIGHLIGHT_THEMES } from 'virtual:stl-starlight-virtual-module';
4
+
5
+ // singleton
6
+ let astroMarkdownProcessor: MarkdownProcessor;
7
+ async function getAstroMarkdown() {
8
+ if (!astroMarkdownProcessor) {
9
+ astroMarkdownProcessor = await createMarkdownProcessor({
10
+ gfm: true,
11
+ remarkPlugins: [remarkGfmAlerts],
12
+ shikiConfig: { themes: HIGHLIGHT_THEMES },
13
+ });
14
+ }
15
+
16
+ return astroMarkdownProcessor;
17
+ }
18
+
19
+ export async function astroMarkdownRender(content: string) {
20
+ const md = await getAstroMarkdown();
21
+ const output = await md.render(content);
22
+
23
+ // Map GFM callouts to the closest Starlight equivalent
24
+ // TODO: this sucks; we should be rendering via ui-primitives callouts instead of ugly theme-incompatible starlight ones
25
+ output.code = output.code
26
+ .replaceAll('markdown-alert-caution', 'markdown-alert-danger')
27
+ .replaceAll('markdown-alert-warning', 'markdown-alert-caution')
28
+ .replaceAll('markdown-alert-important', 'markdown-alert-caution')
29
+ .replaceAll('markdown-alert-title', 'starlight-aside__title')
30
+ .replaceAll('markdown-alert-', 'starlight-aside--')
31
+ .replaceAll('markdown-alert', 'starlight-aside');
32
+
33
+ return output;
34
+ }
35
+
36
+ export async function astroMarkdownRenderText(content: string) {
37
+ const result = await astroMarkdownRender(content);
38
+ return result.code;
39
+ }
@@ -1,18 +1,13 @@
1
1
  import * as React from 'react';
2
- import { marked, Tokens } from 'marked';
3
2
  import { getDocsLanguages } from '../helpers/multiSpec';
4
3
 
5
- import {
6
- createMarkdownProcessor,
7
- CreateShikiHighlighterOptions,
8
- type MarkdownProcessor,
9
- } from '@astrojs/markdown-remark';
10
- import remarkGfmAlerts from 'remark-github-alerts';
4
+ import { astroMarkdownRenderText } from '../markdown';
5
+ import { highlight } from '../markdown/highlighter';
11
6
 
12
7
  import type { MarkdownHeading } from 'astro';
13
8
  import type { StarlightRouteData } from '@astrojs/starlight/route-data';
14
9
  import type * as SDKJSON from '@stainless/sdk-json';
15
- import { LanguageNames, SupportedLanguageSyntaxes, type DocsLanguage } from '@stainless-api/docs-ui/routing';
10
+ import { LanguageNames, type DocsLanguage } from '@stainless-api/docs-ui/routing';
16
11
 
17
12
  import {
18
13
  generateRoute,
@@ -46,7 +41,6 @@ import { Dropdown } from '@stainless-api/docs/components';
46
41
  import {
47
42
  RESOLVED_API_REFERENCE_PATH,
48
43
  EXPAND_RESOURCES,
49
- HIGHLIGHT_THEMES,
50
44
  BREADCRUMB_CONFIG,
51
45
  PROPERTY_SETTINGS,
52
46
  ENABLE_CONTEXT_MENU,
@@ -54,7 +48,6 @@ import {
54
48
  MIDDLEWARE,
55
49
  } from 'virtual:stl-starlight-virtual-module';
56
50
  import style from '@stainless-api/docs-ui/style';
57
- import { BundledTheme, createHighlighter, HighlighterGeneric, type BundledLanguage } from 'shiki';
58
51
  import {
59
52
  SnippetCode,
60
53
  SnippetContainer,
@@ -138,58 +131,6 @@ export function buildPageNavigation(resource: SDKJSON.Resource, depth: number =
138
131
  return [...output, ...subs];
139
132
  }
140
133
 
141
- async function renderMarkdown(content: string) {
142
- const highlighter = await astroHighlight();
143
-
144
- const renderer = {
145
- code({ text, lang }: Tokens.Code) {
146
- return shikiHighlight({
147
- highlighter,
148
- content: text,
149
- language: lang,
150
- });
151
- },
152
- };
153
-
154
- marked.use({ renderer });
155
- return marked.parse(content, {
156
- gfm: true,
157
- }) as string;
158
- }
159
-
160
- function shikiHighlight({
161
- highlighter,
162
- content,
163
- language,
164
- themes,
165
- }: {
166
- highlighter: HighlighterGeneric<BundledLanguage, BundledTheme>;
167
- content: string;
168
- language?: string;
169
- themes?: CreateShikiHighlighterOptions['themes'] | Record<string, 'stainless-docs-json'>;
170
- }) {
171
- let _themes = themes;
172
- if (!themes && language === 'json') {
173
- _themes = {
174
- light: 'stainless-docs-json',
175
- dark: 'stainless-docs-json',
176
- };
177
- }
178
-
179
- if (!_themes) {
180
- _themes = HIGHLIGHT_THEMES;
181
- }
182
- return highlighter.codeToHtml(content, {
183
- lang: language ?? 'javascript',
184
- themes: _themes || {},
185
- });
186
- }
187
-
188
- async function highlight(content: string, language?: string) {
189
- const highlighter = await astroHighlight();
190
- return shikiHighlight({ highlighter, content, language });
191
- }
192
-
193
134
  export function SDKSelectReactComponent({
194
135
  selected,
195
136
  languages,
@@ -295,7 +236,7 @@ export function RenderSpecOverview({ spec, language }: { spec: SDKJSON.Spec; lan
295
236
  <DocsProvider spec={spec} language={language ?? 'node'}>
296
237
  <ComponentProvider components={componentOverrides}>
297
238
  <NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH}>
298
- <MarkdownProvider render={renderMarkdown} highlight={highlight}>
239
+ <MarkdownProvider render={astroMarkdownRenderText} highlight={highlight}>
299
240
  <div className={style.Overview}>
300
241
  {resources
301
242
  .filter(({ resource }) => !resource.name.startsWith('$'))
@@ -351,7 +292,7 @@ export function RenderSpec({
351
292
  >
352
293
  <ComponentProvider components={componentOverrides}>
353
294
  <NavigationProvider basePath={RESOLVED_API_REFERENCE_PATH} selectedPath={path}>
354
- <MarkdownProvider render={renderMarkdown} highlight={highlight}>
295
+ <MarkdownProvider render={astroMarkdownRenderText} highlight={highlight}>
355
296
  {
356
297
  <div className="stldocs-root stl-ui-not-prose">
357
298
  <div className="stl-page-nav-container">
@@ -412,96 +353,3 @@ export async function getReadmeContent(spec: SDKJSON.Spec, language: DocsLanguag
412
353
 
413
354
  return spec.readme[language];
414
355
  }
415
-
416
- let astroShikiHighlighter:
417
- | HighlighterGeneric<BundledLanguage, BundledTheme>
418
- | Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>
419
- | null = null;
420
-
421
- async function astroHighlight() {
422
- if (astroShikiHighlighter) {
423
- return astroShikiHighlighter;
424
- }
425
-
426
- astroShikiHighlighter = createHighlighter({
427
- themes: [
428
- HIGHLIGHT_THEMES?.dark ?? 'github-dark',
429
- HIGHLIGHT_THEMES?.light ?? 'github-light',
430
- {
431
- name: 'stainless-docs-json',
432
- colors: {
433
- 'editor.background': 'var(--stl-color-background)',
434
- 'editor.foreground': 'var(--stl-color-foreground)',
435
- },
436
-
437
- tokenColors: [
438
- {
439
- scope: ['comment', 'punctuation.definition.comment'],
440
- settings: { foreground: 'var(--stl-color-foreground-muted)' },
441
- },
442
- // numbers, booleans, null
443
- {
444
- scope: ['constant.numeric', 'constant.language'],
445
- settings: { foreground: 'var(--stl-color-orange-foreground)' },
446
- },
447
- // strings
448
- {
449
- scope: ['string', 'string.quoted', 'string.template'],
450
- settings: { foreground: 'var(--stl-color-green-foreground)' },
451
- },
452
- // Keys, brackets
453
- {
454
- scope: ['support.type', 'meta'],
455
- settings: { foreground: 'var(--stl-color-foreground)' },
456
- },
457
- // brackets
458
- {
459
- scope: ['meta'],
460
- settings: { foreground: 'var(--stl-color-foreground-muted)' },
461
- },
462
- // built-in types
463
- {
464
- scope: ['support.type.builtin'],
465
- settings: { foreground: 'var(--stl-color-purple-foreground)' },
466
- },
467
- ],
468
- },
469
- ],
470
- langs: SupportedLanguageSyntaxes,
471
- });
472
-
473
- return astroShikiHighlighter;
474
- }
475
-
476
- // Astro's markdown processor is a singleton
477
- // Need to cache it instead of instantiating per request
478
- let astroMarkdownProcessor: MarkdownProcessor;
479
- async function astroMarkdown() {
480
- if (!astroMarkdownProcessor) {
481
- astroMarkdownProcessor = await createMarkdownProcessor({
482
- gfm: true,
483
- remarkPlugins: [remarkGfmAlerts],
484
- shikiConfig: {
485
- themes: HIGHLIGHT_THEMES,
486
- },
487
- });
488
- }
489
-
490
- return astroMarkdownProcessor;
491
- }
492
-
493
- export async function astroMarkdownRender(content: string) {
494
- const md = await astroMarkdown();
495
- const output = await md.render(content);
496
-
497
- // Map GFM callouts to the closest Starlight equivalent
498
- output.code = output.code
499
- .replaceAll('markdown-alert-caution', 'markdown-alert-danger')
500
- .replaceAll('markdown-alert-warning', 'markdown-alert-caution')
501
- .replaceAll('markdown-alert-important', 'markdown-alert-caution')
502
- .replaceAll('markdown-alert-title', 'starlight-aside__title')
503
- .replaceAll('markdown-alert-', 'starlight-aside--')
504
- .replaceAll('markdown-alert', 'starlight-aside');
505
-
506
- return output;
507
- }
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
3
- import { getReadmeContent, buildPageNavigation, RenderSpec, astroMarkdownRender } from '../react/Routing';
3
+ import { getReadmeContent, buildPageNavigation, RenderSpec } from '../react/Routing';
4
+ import { astroMarkdownRender } from '../markdown';
4
5
  import { getResourceFromSpec } from '@stainless-api/docs-ui/utils';
5
6
  import { parseRoute, parseStainlessPath } from '@stainless-api/docs-ui/routing';
6
7
  import {