@stainless-api/docs-ui 0.1.0-beta.2 → 0.1.0-beta.20

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 (57) hide show
  1. package/dist/index.js +1312 -1871
  2. package/dist/mcp.cjs +983441 -0
  3. package/dist/routing.js +4 -4
  4. package/dist/styles/main.css +743 -747
  5. package/dist/styles/primitives.css +444 -426
  6. package/dist/styles/resets.css +33 -41
  7. package/dist/styles/search.css +265 -248
  8. package/dist/styles/sidebar.css +58 -60
  9. package/dist/styles/snippets.css +86 -88
  10. package/dist/styles/variables.css +85 -89
  11. package/package.json +19 -10
  12. package/src/components/breadcrumbs.tsx +1 -1
  13. package/src/components/chat.tsx +18 -15
  14. package/src/components/method.tsx +12 -11
  15. package/src/components/overview.tsx +32 -19
  16. package/src/components/primitives.tsx +36 -19
  17. package/src/components/properties.tsx +4 -2
  18. package/src/components/scripts/dropdown.ts +1 -1
  19. package/src/components/sdk.tsx +28 -22
  20. package/src/components/sidebar.tsx +3 -3
  21. package/src/components/snippets.tsx +29 -11
  22. package/src/contexts/component-generics.tsx +10 -15
  23. package/src/contexts/docs.tsx +15 -4
  24. package/src/contexts/index.tsx +8 -5
  25. package/src/contexts/markdown.tsx +7 -6
  26. package/src/contexts/search.tsx +4 -5
  27. package/src/hooks/use-strict-context.tsx +16 -0
  28. package/src/languages/go.tsx +3 -3
  29. package/src/languages/http.tsx +31 -23
  30. package/src/languages/index.ts +7 -7
  31. package/src/languages/java.tsx +4 -4
  32. package/src/languages/python.tsx +12 -9
  33. package/src/languages/ruby.tsx +20 -13
  34. package/src/languages/typescript.tsx +18 -12
  35. package/src/markdown/index.ts +17 -12
  36. package/src/markdown/utils.ts +6 -3
  37. package/src/routing.ts +9 -9
  38. package/src/search/form.tsx +11 -8
  39. package/src/search/indexer.ts +17 -15
  40. package/src/search/mcp.ts +108 -16
  41. package/src/search/printer.tsx +1 -1
  42. package/src/search/providers/algolia.ts +5 -5
  43. package/src/search/providers/fuse.ts +4 -4
  44. package/src/search/providers/pagefind.ts +1 -1
  45. package/src/search/providers/walker.ts +5 -3
  46. package/src/search/results.tsx +9 -7
  47. package/src/search/types.ts +2 -2
  48. package/src/style.ts +1 -1
  49. package/src/styles/main.css +743 -747
  50. package/src/styles/primitives.css +444 -426
  51. package/src/styles/resets.css +33 -41
  52. package/src/styles/search.css +265 -248
  53. package/src/styles/sidebar.css +58 -60
  54. package/src/styles/snippets.css +86 -88
  55. package/src/styles/variables.css +85 -89
  56. package/src/utils.ts +14 -15
  57. package/dist/mcp.js +0 -16003
@@ -1,14 +1,14 @@
1
1
  import * as React from 'react';
2
2
  import { useLanguage } from './docs';
3
3
 
4
- const HighlightLanguageMappings = {
4
+ const HighlightLanguageMappings: Record<string, string> = {
5
5
  node: 'typescript',
6
6
  http: 'bash',
7
7
  };
8
8
 
9
9
  export type MarkdownContext = {
10
- highlight?: (content: string, language?: string) => string | Promise<string>;
11
- render?: (content: string) => string;
10
+ highlight: (content: string, language: string) => string | Promise<string>;
11
+ render: (content: string) => string;
12
12
  };
13
13
 
14
14
  export const MarkdownContext = React.createContext<MarkdownContext>({
@@ -23,15 +23,16 @@ export function useRenderMarkdown(content?: string) {
23
23
  return React.useMemo(() => (content ? render(content) : undefined), [content, render]);
24
24
  }
25
25
 
26
- export function useHighlight(content?: string, language?: string) {
26
+ export function useHighlight(content: string, language?: string) {
27
27
  const { highlight } = React.useContext(MarkdownContext);
28
- const lang = language ?? useLanguage();
28
+ const defaultLanguage = useLanguage();
29
+ const lang = language ?? defaultLanguage;
29
30
 
30
31
  return React.useMemo(() => {
31
32
  const highlightLanguage = HighlightLanguageMappings[lang] ?? lang;
32
33
  const rendered = highlight(content, highlightLanguage);
33
34
  return typeof rendered === 'string' ? rendered : React.use(rendered);
34
- }, [content, language, highlight]);
35
+ }, [content, highlight, lang]);
35
36
  }
36
37
 
37
38
  export type MarkdownProviderProps = MarkdownContext & {
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { createStrictContext } from '../hooks/use-strict-context';
2
3
  import { search } from '../search/providers/algolia';
3
4
  import { SearchParams, SearchSettings } from '../search/types';
4
5
 
@@ -8,11 +9,9 @@ export type SearchContextType = {
8
9
  pageFind?: string;
9
10
  };
10
11
 
11
- const SearchContext = React.createContext<SearchContextType>(null);
12
+ const [Provider, useSearchContext] = createStrictContext<SearchContextType>('SearchContext');
12
13
 
13
- export function useSearchContext() {
14
- return React.useContext(SearchContext);
15
- }
14
+ export { useSearchContext };
16
15
 
17
16
  export function useSearch() {
18
17
  const { settings } = useSearchContext();
@@ -24,5 +23,5 @@ export type SearchProviderProps = SearchContextType & {
24
23
  };
25
24
 
26
25
  export function SearchProvider({ children, ...props }: SearchProviderProps) {
27
- return <SearchContext value={props}>{children}</SearchContext>;
26
+ return <Provider value={props}>{children}</Provider>;
28
27
  }
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+
3
+ export function createStrictContext<T>(displayName: string) {
4
+ const Context = React.createContext<T | null>(null);
5
+ Context.displayName = displayName;
6
+
7
+ function useStrictContext(): T {
8
+ const context = React.useContext(Context);
9
+ if (context === null) {
10
+ throw new Error(`use${displayName} must be used within a ${displayName}Provider`);
11
+ }
12
+ return context;
13
+ }
14
+
15
+ return [Context.Provider, useStrictContext] as const;
16
+ }
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type * as AST from '~/lib/json-spec-v2/GoAST';
2
+ import { GoAST as AST } from '@stainless/sdk-json';
3
3
 
4
4
  import { useComponents } from '../contexts/use-components';
5
5
  import { useLanguageComponents } from '../contexts';
@@ -43,7 +43,7 @@ export function Type({ type }: TypeProps) {
43
43
 
44
44
  return (
45
45
  <span className={style.Type}>
46
- <SDKReference stainlessPath={type.$ref}>{type.typeName}</SDKReference>
46
+ {type.$ref ? <SDKReference stainlessPath={type.$ref}>{type.typeName}</SDKReference> : type.typeName}
47
47
  {params && params.length > 0 ? (
48
48
  <>
49
49
  <span className={style.TypeBracket}>{'['}</span>
@@ -179,7 +179,7 @@ export function MethodSignature({ decl }: MethodSignatureProps) {
179
179
 
180
180
  export type PropertyProps = {
181
181
  decl: AST.GoDeclaration;
182
- children?: PropertyFn;
182
+ children: PropertyFn;
183
183
  };
184
184
 
185
185
  export function Property({ decl, children }: PropertyProps) {
@@ -1,4 +1,4 @@
1
- import type * as AST from '~/lib/json-spec-v2/HttpAST';
1
+ import { HttpAST as AST } from '@stainless/sdk-json';
2
2
  import { useDeclaration, useLanguage, useLanguageComponents, useSpec } from '../contexts';
3
3
  import { useComponents } from '../contexts/use-components';
4
4
  import style from '../style';
@@ -11,7 +11,7 @@ const ComplexTypes: Partial<Record<AST.HttpType['kind'], string>> = {
11
11
  HttpTypeIntersection: 'intersection',
12
12
  };
13
13
 
14
- const constStyle = {
14
+ const constStyle: Record<string, string> = {
15
15
  string: style.LiteralString,
16
16
  number: style.LiteralNumeric,
17
17
  boolean: style.LiteralBoolean,
@@ -34,17 +34,23 @@ function Identifier({ name }: { name: string }) {
34
34
  function TypePreview({ path }: { path: string }) {
35
35
  const spec = useSpec();
36
36
  const language = useLanguage();
37
- const decl = useDeclaration(path);
37
+ const decl = useDeclaration(path, false);
38
38
  const { Join } = useComponents();
39
39
 
40
- if (!(decl && 'children' in decl && decl.children.length > 0) || decl['type']?.['kind'] === 'HttpTypeUnion')
40
+ if (
41
+ !(decl && 'children' in decl && decl.children && decl.children.length > 0) ||
42
+ ('type' in decl && decl['type'] && 'kind' in decl['type'] && decl['type']['kind'] === 'HttpTypeUnion')
43
+ )
41
44
  return;
42
45
 
43
- const items = decl.children.map((prop, key) => (
44
- <span key={key} className={style.TypePropertyName}>
45
- <span className={style.TextIdentifier}>{spec?.decls?.[language]?.[prop]?.['key']}</span>
46
- </span>
47
- ));
46
+ const items = decl.children.map((prop, key) => {
47
+ const decl = spec?.decls?.[language]?.[prop];
48
+ return (
49
+ <span key={key} className={style.TypePropertyName}>
50
+ <span className={style.TextIdentifier}>{decl && 'key' in decl ? decl?.['key'] : null}</span>
51
+ </span>
52
+ );
53
+ });
48
54
 
49
55
  return (
50
56
  <span className={style.TypePreview} data-stldocs-type-preview="properties">
@@ -138,7 +144,7 @@ export function Type({ type }: TypeProps) {
138
144
  if (
139
145
  name === 'Record' &&
140
146
  type.typeParameters?.length === 2 &&
141
- type.typeParameters?.at(0).kind === 'HttpTypeString'
147
+ type.typeParameters?.at(0)!.kind === 'HttpTypeString'
142
148
  )
143
149
  return (
144
150
  <>
@@ -148,7 +154,7 @@ export function Type({ type }: TypeProps) {
148
154
 
149
155
  return (
150
156
  <span className={style.Type}>
151
- <SDKReference stainlessPath={type.$ref}>{name}</SDKReference>
157
+ <SDKReference stainlessPath={type.$ref!}>{name}</SDKReference>
152
158
  {params && params.length > 0 && (
153
159
  <>
154
160
  <span className={style.TypeBracket}>{'<'}</span>
@@ -158,14 +164,14 @@ export function Type({ type }: TypeProps) {
158
164
  <span className={style.TypeBracket}>{'>'}</span>
159
165
  </>
160
166
  )}
161
- <TypePreview path={type.$ref} />
167
+ <TypePreview path={type.$ref!} />
162
168
  </span>
163
169
  );
164
170
  }
165
171
 
166
- case 'HttpTypeObject':
172
+ case 'HttpTypeObject': {
167
173
  const items = type.members.map(({ ident }) => (
168
- <span className={style.TypePropertyName}>
174
+ <span className={style.TypePropertyName} key={ident}>
169
175
  <Identifier name={ident} />
170
176
  </span>
171
177
  ));
@@ -185,6 +191,7 @@ export function Type({ type }: TypeProps) {
185
191
  </span>
186
192
  </span>
187
193
  );
194
+ }
188
195
  }
189
196
  }
190
197
 
@@ -193,28 +200,29 @@ export type MethodSignatureProps = {
193
200
  };
194
201
 
195
202
  export function MethodSignature({ decl }: MethodSignatureProps) {
203
+ void decl;
196
204
  return null;
197
205
  }
198
206
 
199
207
  export function MethodInfo({ decl, children }: MethodSignatureProps & { children: React.ReactNode }) {
200
208
  const Docs = useComponents();
201
209
 
202
- const params = Object.entries(decl.paramsChildren)
203
- .filter(([_, value]) => value.length)
210
+ const params = Object.entries(decl.paramsChildren!)
211
+ .filter(([, value]) => value.length)
204
212
  .map(([location, value]) => (
205
213
  <React.Fragment key={location}>
206
214
  <div className={style.MethodParameters} data-stldocs-property-group={location.at(0)}>
207
215
  <h5>
208
- {location.at(0).toUpperCase()}
216
+ {location.at(0)!.toUpperCase()}
209
217
  {location.slice(1)} Parameters
210
- <PropertyToggle target={location.at(0)} />
218
+ <PropertyToggle target={location.at(0)!} />
211
219
  </h5>
212
220
  <Docs.SDKChildren paths={value} />
213
221
  </div>
214
222
  </React.Fragment>
215
223
  ));
216
224
 
217
- if (decl.bodyParamsChildren?.['application/json']?.length > 0)
225
+ if ((decl.bodyParamsChildren?.['application/json']?.length ?? 0) > 0)
218
226
  params.push(
219
227
  <div className={style.MethodInfoSection}>
220
228
  <h5>
@@ -222,7 +230,7 @@ export function MethodInfo({ decl, children }: MethodSignatureProps & { children
222
230
  <PropertyToggle target="body" />
223
231
  </h5>
224
232
  <div className={style.MethodParameters} data-stldocs-property-group="body">
225
- <Docs.SDKChildren paths={decl.bodyParamsChildren?.['application/json']} />
233
+ <Docs.SDKChildren paths={decl.bodyParamsChildren?.['application/json'] ?? []} />
226
234
  </div>
227
235
  </div>,
228
236
  );
@@ -231,14 +239,14 @@ export function MethodInfo({ decl, children }: MethodSignatureProps & { children
231
239
  <div className={style.MethodInfo}>
232
240
  {children && <div className={style.MethodContent}>{children}</div>}
233
241
  {params.length > 0 && params}
234
- {decl.responseChildren.length > 0 && (
242
+ {(decl.responseChildren?.length ?? 0) > 0 && (
235
243
  <div className={style.MethodInfoSection}>
236
244
  <h5>
237
245
  Returns
238
246
  <PropertyToggle target="returns" />
239
247
  </h5>
240
248
  <div className={style.MethodReturns} data-stldocs-property-group="returns">
241
- <Docs.SDKChildren paths={decl.responseChildren} />
249
+ <Docs.SDKChildren paths={decl.responseChildren ?? []} />
242
250
  </div>
243
251
  </div>
244
252
  )}
@@ -256,7 +264,7 @@ function renderVariantInfo(type: AST.HttpType) {
256
264
 
257
265
  export type PropertyProps = {
258
266
  decl: AST.HttpDeclaration;
259
- children?: PropertyFn;
267
+ children: PropertyFn;
260
268
  };
261
269
 
262
270
  export function Property({ decl, children }: PropertyProps) {
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
- import type { DeclarationNode, Type } from '~/lib/json-spec-v2/types';
2
+ import type { DeclarationNode, Type } from '@stainless/sdk-json';
3
3
 
4
4
  import * as typescript from './typescript';
5
5
  import * as java from './java';
@@ -17,10 +17,10 @@ export const kotlin = java;
17
17
  export type PropertyFn = (params: PropertyProps) => ReactNode;
18
18
 
19
19
  export interface LanguageComponentDefinition {
20
- Declaration(props: { decl: DeclarationNode });
21
- Property(props: { decl: DeclarationNode; children: PropertyFn });
22
- TypeName(props: { type: Type; optional?: boolean });
23
- Type(props: { type: Type; optional?: boolean });
24
- MethodSignature(props: { decl: DeclarationNode });
25
- MethodInfo?(props: { decl: DeclarationNode; children?: ReactNode });
20
+ Declaration(props: { decl: DeclarationNode }): ReactNode;
21
+ Property(props: { decl: DeclarationNode; children: PropertyFn }): ReactNode;
22
+ TypeName(props: { type: Type; optional?: boolean }): ReactNode;
23
+ Type(props: { type: Type; optional?: boolean }): ReactNode;
24
+ MethodSignature(props: { decl: DeclarationNode }): ReactNode;
25
+ MethodInfo?(props: { decl: DeclarationNode; children?: ReactNode }): ReactNode;
26
26
  }
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type * as AST from '~/lib/json-spec-v2/JavaAST';
2
+ import { JavaAST as AST } from '@stainless/sdk-json';
3
3
 
4
4
  import { useLanguage, useLanguageComponents } from '../contexts';
5
5
  import { useComponents } from '../contexts/use-components';
@@ -13,7 +13,7 @@ function showFullType(type: AST.JavaType) {
13
13
  );
14
14
  }
15
15
 
16
- const constStyle = {
16
+ const constStyle: Record<string, string> = {
17
17
  string: style.LiteralString,
18
18
  number: style.LiteralNumeric,
19
19
  boolean: style.LiteralBoolean,
@@ -46,7 +46,7 @@ export function Type({ type, optional }: TypeProps) {
46
46
 
47
47
  return (
48
48
  <span className={style.Type}>
49
- <SDKReference stainlessPath={type.$ref}>{name}</SDKReference>
49
+ <SDKReference stainlessPath={type.$ref!}>{name}</SDKReference>
50
50
  {params && params.length > 0 ? (
51
51
  <>
52
52
  <span className={style.TypeBracket}>{'<'}</span>
@@ -186,7 +186,7 @@ export function MethodSignature({ decl }: MethodSignatureProps) {
186
186
 
187
187
  export type PropertyProps = {
188
188
  decl: AST.JavaDeclaration;
189
- children?: PropertyFn;
189
+ children: PropertyFn;
190
190
  };
191
191
 
192
192
  export function Property({ decl, children }: PropertyProps) {
@@ -1,19 +1,21 @@
1
1
  import * as React from 'react';
2
- import type * as AST from '~/lib/json-spec-v2/PythonAST';
2
+ import { PythonAST as AST } from '@stainless/sdk-json';
3
3
  import { useLanguageComponents } from '../contexts';
4
4
  import { useComponents } from '../contexts/use-components';
5
5
  import style from '../style';
6
6
  import { PropertyFn } from '.';
7
7
 
8
- const constStyle = {
8
+ const constStyle: Record<string, string> = {
9
9
  string: style.LiteralString,
10
10
  number: style.LiteralNumeric,
11
11
  boolean: style.LiteralBoolean,
12
12
  };
13
13
 
14
- function showFullType(type: AST.PythonType) {
14
+ function showFullType(type: AST.PythonType): boolean {
15
15
  if (type.kind !== 'PythonTypeReference') return false;
16
- return type.typeName === 'Optional' ? showFullType(type.typeParameters[0]) : type.typeParameters.length > 0;
16
+ return type.typeName === 'Optional'
17
+ ? showFullType(type.typeParameters![0]!)
18
+ : type.typeParameters!.length > 0;
17
19
  }
18
20
 
19
21
  type TypeProps = {
@@ -26,7 +28,7 @@ export function TypeName({ type }: TypeProps) {
26
28
  if (type.kind === 'PythonTypeReference') {
27
29
  switch (type.typeName) {
28
30
  case 'Optional':
29
- return <Lang.TypeName type={type.typeParameters[0]} />;
31
+ return <Lang.TypeName type={type.typeParameters![0]!} />;
30
32
  case 'List':
31
33
  case 'Iterable':
32
34
  case 'Literal':
@@ -64,7 +66,7 @@ export function Type({ type }: TypeProps) {
64
66
  case 'PythonTypeLiteral':
65
67
  return (
66
68
  <span className={style.Type}>
67
- <span className={constStyle[typeof type.literal.value]}>{JSON.stringify(type.literal.value)}</span>
69
+ <span className={constStyle[typeof type.literal.value]!}>{JSON.stringify(type.literal.value)}</span>
68
70
  </span>
69
71
  );
70
72
 
@@ -97,7 +99,7 @@ export function Type({ type }: TypeProps) {
97
99
  return (
98
100
  <span className={style.Type}>
99
101
  <span className={type.typeName === 'Optional' ? style.TypeArray : ''}>
100
- <SDKReference stainlessPath={type.$ref}>{type.typeName}</SDKReference>
102
+ <SDKReference stainlessPath={type.$ref!}>{type.typeName}</SDKReference>
101
103
  </span>
102
104
  {params && params.length > 0 && (
103
105
  <>
@@ -166,7 +168,7 @@ export function MethodSignature({ decl }: MethodSignatureProps) {
166
168
 
167
169
  export type PropertyProps = {
168
170
  decl: AST.PythonDeclaration;
169
- children?: PropertyFn;
171
+ children: PropertyFn;
170
172
  };
171
173
 
172
174
  export function Property({ decl, children }: PropertyProps) {
@@ -205,7 +207,7 @@ export function Declaration({ decl }: DeclarationProps) {
205
207
  if (!decl) return;
206
208
 
207
209
  switch (decl.kind) {
208
- case 'PythonDeclProperty':
210
+ case 'PythonDeclProperty': {
209
211
  const nullable =
210
212
  decl.type.kind === 'PythonTypeReference' &&
211
213
  decl.type.typeName === 'Optional' &&
@@ -229,6 +231,7 @@ export function Declaration({ decl }: DeclarationProps) {
229
231
  )}
230
232
  </>
231
233
  );
234
+ }
232
235
 
233
236
  case 'PythonDeclClass':
234
237
  return (
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type * as AST from '~/lib/json-spec-v2/RubyAST';
2
+ import { RubyAST as AST } from '@stainless/sdk-json';
3
3
  import { useDeclaration, useLanguage, useLanguageComponents, useSpec } from '../contexts';
4
4
  import { useComponents } from '../contexts/use-components';
5
5
  import style from '../style';
@@ -36,17 +36,23 @@ const VALID_IDENTIFIER = /^[_A-Za-z][_A-Za-z0-9]*$/;
36
36
  function TypePreview({ path }: { path: string }) {
37
37
  const spec = useSpec();
38
38
  const language = useLanguage();
39
- const decl = useDeclaration(path);
39
+ const decl = useDeclaration(path, false);
40
40
  const { Join } = useComponents();
41
41
 
42
- if (!(decl && 'children' in decl && decl.children.length > 0) || decl['type']?.['kind'] === 'RubyTypeUnion')
42
+ if (
43
+ !(decl && 'children' in decl && decl.children && decl.children.length > 0) ||
44
+ ('type' in decl && decl['type'] && 'kind' in decl['type'] && decl['type']?.['kind'] === 'RubyTypeUnion')
45
+ )
43
46
  return;
44
47
 
45
- const items = decl.children.map((prop, key) => (
46
- <span key={key} className={style.TypePropertyName}>
47
- <span className={style.TextIdentifier}>{spec?.decls?.[language]?.[prop]?.['ident']}</span>
48
- </span>
49
- ));
48
+ const items = decl.children.map((prop, key) => {
49
+ const p = spec?.decls?.[language]?.[prop];
50
+ return (
51
+ <span key={key} className={style.TypePropertyName}>
52
+ <span className={style.TextIdentifier}>{p && 'ident' in p ? p['ident'] : null}</span>
53
+ </span>
54
+ );
55
+ });
50
56
 
51
57
  return (
52
58
  <span className={style.TypePreview} data-stldocs-type-preview="properties">
@@ -110,6 +116,7 @@ export function Type({ type }: TypeProps) {
110
116
  </span>
111
117
  );
112
118
  }
119
+ break;
113
120
 
114
121
  case 'RubyTypeArray':
115
122
  return (
@@ -139,8 +146,8 @@ export function Type({ type }: TypeProps) {
139
146
  if (!type.typeParameters || type.typeParameters.length === 0)
140
147
  return (
141
148
  <span className={style.Type}>
142
- <SDKReference stainlessPath={type.$ref}>{name}</SDKReference>
143
- <TypePreview path={type.$ref} />
149
+ <SDKReference stainlessPath={type.$ref!}>{name}</SDKReference>
150
+ <TypePreview path={type.$ref!} />
144
151
  </span>
145
152
  );
146
153
 
@@ -148,13 +155,13 @@ export function Type({ type }: TypeProps) {
148
155
 
149
156
  return (
150
157
  <span className={style.Type}>
151
- <SDKReference stainlessPath={type.$ref}>{name}</SDKReference>
158
+ <SDKReference stainlessPath={type.$ref!}>{name}</SDKReference>
152
159
  <span className={style.TypeBracket}>{'<'}</span>
153
160
  <Join items={typeParameters}>
154
161
  <span className={style.TextOperator}>, </span>
155
162
  </Join>
156
163
  <span className={style.TypeBracket}>{'>'}</span>
157
- <TypePreview path={type.$ref} />
164
+ <TypePreview path={type.$ref!} />
158
165
  </span>
159
166
  );
160
167
  }
@@ -248,7 +255,7 @@ export function MethodSignature({ decl }: MethodSignatureProps) {
248
255
 
249
256
  export type PropertyProps = {
250
257
  decl: AST.RubyDeclaration;
251
- children?: PropertyFn;
258
+ children: PropertyFn;
252
259
  };
253
260
 
254
261
  export function Property({ decl, children }: PropertyProps) {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type * as TSAST from '~/lib/json-spec-v2/TSAST';
2
+ import { TSAST } from '@stainless/sdk-json';
3
3
  import { useDeclaration, useLanguage, useLanguageComponents, useSpec } from '../contexts';
4
4
  import { useComponents } from '../contexts/use-components';
5
5
  import style from '../style';
@@ -13,7 +13,7 @@ const ComplexTypes: Record<string, string> = {
13
13
  TSTypeArray: 'array',
14
14
  };
15
15
 
16
- const constStyle = {
16
+ const constStyle: Record<string, string> = {
17
17
  string: style.LiteralString,
18
18
  number: style.LiteralNumeric,
19
19
  boolean: style.LiteralBoolean,
@@ -66,17 +66,23 @@ function TypeParams({ params }: { params?: TSAST.TSTypeParameter[] }) {
66
66
  function TypePreview({ path }: { path: string }) {
67
67
  const spec = useSpec();
68
68
  const language = useLanguage();
69
- const decl = useDeclaration(path);
69
+ const decl = useDeclaration(path, false);
70
70
  const { Join } = useComponents();
71
71
 
72
- if (!(decl && 'children' in decl && decl.children.length > 0) || decl['type']?.['kind'] === 'TSTypeUnion')
72
+ if (
73
+ !(decl && 'children' in decl && decl.children && decl.children.length > 0) ||
74
+ (decl && 'type' in decl && 'kind' in decl['type'] && decl['type']['kind'] === 'TSTypeUnion')
75
+ )
73
76
  return;
74
77
 
75
- const items = decl.children.map((prop, key) => (
76
- <span key={key} className={style.TypePropertyName}>
77
- <span className={style.TextIdentifier}>{spec?.decls?.[language]?.[prop]?.['key']}</span>
78
- </span>
79
- ));
78
+ const items = decl.children.map((prop, key) => {
79
+ const p = spec?.decls?.[language]?.[prop];
80
+ return (
81
+ <span key={key} className={style.TypePropertyName}>
82
+ <span className={style.TextIdentifier}>{p && 'key' in p ? p['key'] : null}</span>
83
+ </span>
84
+ );
85
+ });
80
86
 
81
87
  return (
82
88
  <span className={style.TypePreview} data-stldocs-type-preview="properties">
@@ -146,7 +152,7 @@ export function Type({ type }: TypeProps) {
146
152
 
147
153
  return (
148
154
  <span className={style.Type}>
149
- <SDKReference stainlessPath={type.$ref}>{name}</SDKReference>
155
+ <SDKReference stainlessPath={type.$ref!}>{name}</SDKReference>
150
156
  {params && params.length > 0 && (
151
157
  <>
152
158
  <span className={style.TypeBracket}>{'<'}</span>
@@ -156,7 +162,7 @@ export function Type({ type }: TypeProps) {
156
162
  <span className={style.TypeBracket}>{'>'}</span>
157
163
  </>
158
164
  )}
159
- <TypePreview path={type.$ref} />
165
+ <TypePreview path={type.$ref!} />
160
166
  </span>
161
167
  );
162
168
  }
@@ -274,7 +280,7 @@ export function MethodSignature({ decl }: MethodSignatureProps) {
274
280
 
275
281
  export type PropertyProps = {
276
282
  decl: TSAST.TSDeclaration;
277
- children?: PropertyFn;
283
+ children: PropertyFn;
278
284
  };
279
285
 
280
286
  export function Property({ decl, children }: PropertyProps) {
@@ -2,7 +2,7 @@ import Markdoc from '@markdoc/markdoc';
2
2
  import * as md from './md';
3
3
  import { EnvironmentType, getDecl, getSnippet, stripMarkup } from './utils';
4
4
  import * as printer from '../search/printer';
5
- import type * as SDKJSON from '~/lib/json-spec-v2/types';
5
+ import type * as SDKJSON from '@stainless/sdk-json';
6
6
  import type { Node } from '@markdoc/markdoc';
7
7
 
8
8
  export function declaration(env: EnvironmentType, decl: SDKJSON.DeclarationNode) {
@@ -15,20 +15,20 @@ function renderChildren(env: EnvironmentType, children: SDKJSON.ID[], nesting: s
15
15
  }
16
16
 
17
17
  function renderDecl(env: EnvironmentType, path: string, nesting: string[] = []) {
18
- const decl = getDecl(env, path);
18
+ const decl = getDecl(env, path)!;
19
19
  const item = md.item(declaration(env, decl));
20
20
 
21
- const hasChildren = 'children' in decl && decl.children.length > 0;
22
- const showModelProps = !decl['modelPath'] || env.options.includeModelProperties;
21
+ const hasChildren = 'children' in decl && decl.children && decl.children.length > 0;
22
+ const showModelProps = !('modelPath' in decl && decl['modelPath']) || env.options.includeModelProperties;
23
23
 
24
24
  if ('docstring' in decl && decl.docstring) item.children.push(...md.parse(decl.docstring));
25
25
  if (hasChildren && showModelProps && !nesting.includes(path))
26
- item.push(renderChildren(env, decl.children, [...nesting, path]));
26
+ item.push(renderChildren(env, decl.children ?? [], [...nesting, path]));
27
27
 
28
28
  return item;
29
29
  }
30
30
 
31
- function renderMethod(env: EnvironmentType, method: SDKJSON.Method) {
31
+ function renderMethod(env: EnvironmentType, method: SDKJSON.Method): Node[] {
32
32
  const decl = getDecl(env, method.stainlessPath);
33
33
 
34
34
  if (!decl)
@@ -41,11 +41,11 @@ function renderMethod(env: EnvironmentType, method: SDKJSON.Method) {
41
41
  ];
42
42
 
43
43
  const signature = printer.methodSignature(env.language, decl);
44
- const [httpMethod, endpoint] = method.endpoint.split(' ');
44
+ const [httpMethod, endpoint] = method.endpoint.split(' ') as [string, string];
45
45
 
46
46
  const output = [
47
47
  md.heading(2, method.title),
48
- env.language === 'http' ? null : md.paragraph(md.code(stripMarkup(signature))),
48
+ ...(env.language === 'http' ? [] : [md.paragraph(md.code(stripMarkup(signature)))]),
49
49
  md.paragraph(md.strong(md.text(httpMethod)), md.text(' '), md.code(endpoint)),
50
50
  ];
51
51
 
@@ -54,7 +54,7 @@ function renderMethod(env: EnvironmentType, method: SDKJSON.Method) {
54
54
  if ('paramsChildren' in decl && Array.isArray(decl.paramsChildren) && decl.paramsChildren.length > 0)
55
55
  output.push(md.heading(3, 'Parameters'), renderChildren(env, decl.paramsChildren));
56
56
 
57
- if ('responseChildren' in decl && decl.responseChildren.length > 0)
57
+ if ('responseChildren' in decl && decl.responseChildren && decl.responseChildren.length > 0)
58
58
  output.push(md.heading(3, 'Returns'), renderChildren(env, decl.responseChildren));
59
59
 
60
60
  const snippet = getSnippet(env, method.stainlessPath);
@@ -67,7 +67,7 @@ function renderModel(env: EnvironmentType, model: SDKJSON.Model) {
67
67
  return [md.heading(3, model.title), md.list(renderDecl(env, `${model.stainlessPath} > (schema)`))];
68
68
  }
69
69
 
70
- function renderResource(env: EnvironmentType, resource: SDKJSON.Resource) {
70
+ function renderResource(env: EnvironmentType, resource: SDKJSON.Resource): Node[] {
71
71
  const methods = Object.values(resource.methods)
72
72
  .filter((method) => getDecl(env, method.stainlessPath))
73
73
  .flatMap((method) => renderMethod(env, method));
@@ -82,11 +82,16 @@ function renderResource(env: EnvironmentType, resource: SDKJSON.Resource) {
82
82
 
83
83
  if (!env.options.renderNestedResources) return doc;
84
84
 
85
- const children = Object.values(resource.subresources).map((resource) => renderResource(env, resource));
85
+ const children = Object.values(resource.subresources ?? {}).flatMap((resource) =>
86
+ renderResource(env, resource),
87
+ );
86
88
  return [...doc, ...children];
87
89
  }
88
90
 
89
- export function render(env: EnvironmentType, node: SDKJSON.Resource | SDKJSON.Method | SDKJSON.Model) {
91
+ export function render(
92
+ env: EnvironmentType,
93
+ node: SDKJSON.Resource | SDKJSON.Method | SDKJSON.Model,
94
+ ): Node[] {
90
95
  switch (node.kind) {
91
96
  case 'resource':
92
97
  return renderResource(env, node);