@stainless-api/docs-ui 0.1.0-beta.29 → 0.1.0-beta.30

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 (194) hide show
  1. package/dist/{breadcrumbs-D5viAm7a.d.ts → breadcrumbs-wJ7A9MGt.d.ts} +2 -2
  2. package/dist/{component-generics-BnrVqdQj.d.ts → component-generics--y1IC_M-.d.ts} +2 -1
  3. package/dist/{component-generics-Df4EDvxk.js → component-generics-D3ybuN5r.js} +5 -1
  4. package/dist/components/breadcrumbs.d.ts +1 -1
  5. package/dist/components/breadcrumbs.js +13 -14
  6. package/dist/components/chat.d.ts +3 -3
  7. package/dist/components/chat.js +64 -50
  8. package/dist/components/icons.d.ts +10 -10
  9. package/dist/components/icons.js +1 -1
  10. package/dist/components/index.d.ts +11 -12
  11. package/dist/components/index.js +14 -15
  12. package/dist/components/method.d.ts +1 -1
  13. package/dist/components/method.js +13 -14
  14. package/dist/components/overview.d.ts +1 -1
  15. package/dist/components/overview.js +13 -14
  16. package/dist/components/primitives.d.ts +1 -1
  17. package/dist/components/primitives.js +13 -14
  18. package/dist/components/properties.d.ts +1 -1
  19. package/dist/components/properties.js +13 -14
  20. package/dist/components/sdk.d.ts +2 -2
  21. package/dist/components/sdk.js +13 -14
  22. package/dist/components/sidebar.d.ts +1 -1
  23. package/dist/components/sidebar.js +13 -14
  24. package/dist/components/snippets.d.ts +3 -3
  25. package/dist/components/snippets.js +13 -14
  26. package/dist/contexts/component-generics.d.ts +1 -1
  27. package/dist/contexts/component-generics.js +1 -1
  28. package/dist/contexts/component-types.d.ts +11 -12
  29. package/dist/contexts/component-types.js +0 -1
  30. package/dist/contexts/component.d.ts +14 -14
  31. package/dist/contexts/component.js +13 -14
  32. package/dist/contexts/docs.d.ts +1 -1
  33. package/dist/contexts/docs.js +1 -1
  34. package/dist/contexts/index.d.ts +18 -19
  35. package/dist/contexts/index.js +13 -14
  36. package/dist/contexts/markdown.d.ts +1 -1
  37. package/dist/contexts/markdown.js +2 -2
  38. package/dist/contexts/navigation.d.ts +2 -2
  39. package/dist/contexts/navigation.js +1 -1
  40. package/dist/contexts/search.d.ts +3 -3
  41. package/dist/contexts/search.js +13 -14
  42. package/dist/contexts/use-components.d.ts +10 -11
  43. package/dist/contexts/use-components.js +2 -2
  44. package/dist/contexts-CMNI3ctP.js +3799 -0
  45. package/dist/{docs-DhNaW0DE.d.ts → docs-BvahWQ28.d.ts} +2 -1
  46. package/dist/{docs-Cj25B-Sh.js → docs-CopwX9a7.js} +5 -1
  47. package/dist/icons-yb-Jhkmg.js +753 -0
  48. package/dist/{index-d8_VR8Z5.d.ts → index-BmPNhnpe.d.ts} +6 -6
  49. package/dist/{index-BXO3gZup.d.ts → index-D5NMSAld.d.ts} +26 -25
  50. package/dist/index-rVFBdVz8.d.ts +15 -0
  51. package/dist/index.d.ts +20 -21
  52. package/dist/index.js +15 -7700
  53. package/dist/languages/go.d.ts +11 -12
  54. package/dist/languages/go.js +13 -14
  55. package/dist/languages/http.d.ts +11 -12
  56. package/dist/languages/http.js +13 -14
  57. package/dist/languages/index.d.ts +11 -12
  58. package/dist/languages/index.js +13 -14
  59. package/dist/languages/java.d.ts +11 -12
  60. package/dist/languages/java.js +13 -14
  61. package/dist/languages/python.d.ts +11 -12
  62. package/dist/languages/python.js +13 -14
  63. package/dist/languages/ruby.d.ts +11 -12
  64. package/dist/languages/ruby.js +13 -14
  65. package/dist/languages/typescript.d.ts +11 -12
  66. package/dist/languages/typescript.js +13 -14
  67. package/dist/markdown/index.d.ts +3 -3
  68. package/dist/markdown/index.js +13 -14
  69. package/dist/markdown/md.js +1 -1
  70. package/dist/markdown/utils.d.ts +3 -3
  71. package/dist/markdown/utils.js +1 -1
  72. package/dist/{markdown-DunIdqFE.js → markdown-BmpyokB7.js} +9 -5
  73. package/dist/{markdown-DN8KaRR2.d.ts → markdown-w5UpIiGc.d.ts} +2 -1
  74. package/dist/{method-c3XDArUn.d.ts → method-CLpRObBV.d.ts} +7 -6
  75. package/dist/{navigation-BSn6PX-7.d.ts → navigation-Blr3LaES.d.ts} +3 -2
  76. package/dist/{navigation-CuCg3le8.js → navigation-CGr5_w6z.js} +5 -1
  77. package/dist/{overview-D21weqVJ.d.ts → overview-DBnqhjAg.d.ts} +6 -6
  78. package/dist/{primitives-iB9fIrMF.d.ts → primitives-BFubD3w8.d.ts} +9 -8
  79. package/dist/{properties-Ba6F_GGj.d.ts → properties-DeQRa6VK.d.ts} +4 -4
  80. package/dist/{routing-C8oZYLsf.js → routing-8itEXLx6.js} +1 -1
  81. package/dist/{routing-BE6Vrs-z.d.ts → routing-DNN8R6bZ.d.ts} +1 -1
  82. package/dist/routing.d.ts +1 -1
  83. package/dist/routing.js +3 -180
  84. package/dist/{sdk-D2x2l6JH.d.ts → sdk-BVQyp5Dw.d.ts} +14 -13
  85. package/dist/search/index.d.ts +6 -6
  86. package/dist/search/index.js +233 -110
  87. package/dist/search/providers/algolia.d.ts +2 -2
  88. package/dist/search/providers/algolia.js +13 -14
  89. package/dist/search/providers/fuse.d.ts +2 -2
  90. package/dist/search/providers/fuse.js +13 -14
  91. package/dist/search/providers/pagefind.d.ts +2 -2
  92. package/dist/search/providers/pagefind.js +1 -1
  93. package/dist/search/providers/walker.d.ts +2 -2
  94. package/dist/search/providers/walker.js +13 -14
  95. package/dist/search/types.d.ts +2 -2
  96. package/dist/search/types.js +1 -1
  97. package/dist/{search-KMqOU2tz.d.ts → search-CPp6HpUy.d.ts} +3 -2
  98. package/dist/{sidebar-B1X4gmY2.d.ts → sidebar-BoPLeaxp.d.ts} +5 -4
  99. package/dist/{snippets-BApdMOXp.d.ts → snippets-DLHH_Voi.d.ts} +7 -6
  100. package/dist/{style-BWu-Pqcm.d.ts → style-BEMLtSIK.d.ts} +0 -10
  101. package/dist/{style-CkbsakoF.js → style-CPgcT0Fw.js} +1 -11
  102. package/dist/style.d.ts +1 -1
  103. package/dist/style.js +1 -1
  104. package/dist/styles/main.css +51 -20
  105. package/dist/styles/main.js +0 -0
  106. package/dist/styles/primitives.css +1 -0
  107. package/dist/styles/primitives.js +0 -0
  108. package/dist/styles/resets.css +1 -0
  109. package/dist/styles/resets.js +0 -0
  110. package/dist/styles/search.css +1 -0
  111. package/dist/styles/search.js +0 -0
  112. package/dist/styles/sidebar.css +1 -0
  113. package/dist/styles/sidebar.js +0 -0
  114. package/dist/styles/snippets.css +1 -0
  115. package/dist/styles/snippets.js +0 -0
  116. package/dist/styles/variables.css +2 -0
  117. package/dist/styles/variables.js +0 -0
  118. package/dist/{types-BLgvxY4i.d.ts → types-DNSz4kuM.d.ts} +1 -1
  119. package/dist/{use-components-DI-AbT-D.js → use-components-BHEwm0mE.js} +1 -1
  120. package/dist/{utils-BhYTrLot.js → utils-2FmcHPHp.js} +2 -2
  121. package/dist/{utils-B9JL_XWH.d.ts → utils-DVi3gJLL.d.ts} +2 -2
  122. package/dist/utils.d.ts +1 -1
  123. package/dist/utils.js +2 -2
  124. package/package.json +63 -10
  125. package/dist/components/dropdown.d.ts +0 -2
  126. package/dist/components/dropdown.js +0 -4
  127. package/dist/components/scripts/dropdown.d.ts +0 -12
  128. package/dist/components/scripts/dropdown.js +0 -50
  129. package/dist/contexts-DO0sMzym.js +0 -2581
  130. package/dist/dropdown-Dv9VAYCW.d.ts +0 -42
  131. package/dist/dropdown-kUhwBigR.js +0 -38
  132. package/dist/icons--8QR-PrL.js +0 -222
  133. package/dist/index-BW6OPqAo.d.ts +0 -16
  134. package/dist/mcp.cjs +0 -983418
  135. package/src/components/breadcrumbs.tsx +0 -94
  136. package/src/components/chat.tsx +0 -157
  137. package/src/components/icons.tsx +0 -584
  138. package/src/components/index.ts +0 -8
  139. package/src/components/method.tsx +0 -145
  140. package/src/components/overview.tsx +0 -172
  141. package/src/components/primitives.tsx +0 -301
  142. package/src/components/properties.tsx +0 -132
  143. package/src/components/sdk.tsx +0 -408
  144. package/src/components/sidebar.tsx +0 -99
  145. package/src/components/snippets.tsx +0 -197
  146. package/src/contexts/component-generics.tsx +0 -43
  147. package/src/contexts/component-types.tsx +0 -5
  148. package/src/contexts/component.tsx +0 -32
  149. package/src/contexts/docs.tsx +0 -86
  150. package/src/contexts/index.tsx +0 -20
  151. package/src/contexts/markdown.tsx +0 -44
  152. package/src/contexts/navigation.tsx +0 -44
  153. package/src/contexts/search.tsx +0 -27
  154. package/src/contexts/use-components.tsx +0 -4
  155. package/src/hooks/use-strict-context.tsx +0 -16
  156. package/src/index.ts +0 -6
  157. package/src/languages/go.tsx +0 -281
  158. package/src/languages/http.tsx +0 -329
  159. package/src/languages/index.ts +0 -26
  160. package/src/languages/java.tsx +0 -358
  161. package/src/languages/python.tsx +0 -258
  162. package/src/languages/ruby.tsx +0 -327
  163. package/src/languages/typescript.tsx +0 -399
  164. package/src/markdown/index.ts +0 -112
  165. package/src/markdown/md.ts +0 -45
  166. package/src/markdown/utils.ts +0 -52
  167. package/src/routing.ts +0 -238
  168. package/src/search/form.tsx +0 -130
  169. package/src/search/index.tsx +0 -1
  170. package/src/search/indexer.ts +0 -248
  171. package/src/search/mcp.ts +0 -156
  172. package/src/search/printer.tsx +0 -86
  173. package/src/search/providers/algolia.ts +0 -88
  174. package/src/search/providers/fuse.ts +0 -19
  175. package/src/search/providers/pagefind.ts +0 -17
  176. package/src/search/providers/walker.ts +0 -32
  177. package/src/search/results.tsx +0 -183
  178. package/src/search/state.ts +0 -64
  179. package/src/search/types.ts +0 -116
  180. package/src/style.ts +0 -185
  181. package/src/styles/main.css +0 -989
  182. package/src/styles/primitives.css +0 -392
  183. package/src/styles/resets.css +0 -39
  184. package/src/styles/search.css +0 -359
  185. package/src/styles/sidebar.css +0 -85
  186. package/src/styles/snippets.css +0 -130
  187. package/src/styles/variables.css +0 -86
  188. package/src/utils.ts +0 -40
  189. /package/dist/{chunk-Bp6m_JJh.js → chunk-DsStOjWQ.js} +0 -0
  190. /package/dist/{md-Dg8aOyMA.js → md-DxiV1_vy.js} +0 -0
  191. /package/dist/{pagefind-ChrPfuVv.js → pagefind-BaK1krMe.js} +0 -0
  192. /package/dist/{types-DFN4M1Sp.js → types-__XoFvJ_.js} +0 -0
  193. /package/dist/{utils-ByZH9QWT.js → utils-BCfb0F9R.js} +0 -0
  194. /package/dist/{utils-DlayebL1.d.ts → utils-D43p_yTd.d.ts} +0 -0
package/src/search/mcp.ts DELETED
@@ -1,156 +0,0 @@
1
- import { BM25Retriever } from '@langchain/community/retrievers/bm25';
2
- import { renderMarkdown } from '../markdown';
3
- import { DocsLanguage, parseStainlessPath } from '../routing';
4
- import { getResourceFromSpec } from '../utils';
5
- import { buildIndex, search as fuseSearch } from './providers/fuse';
6
- import { generateIndex } from './indexer';
7
- import type { IndexEntry, IndexMethod } from './types';
8
- import natural from 'natural';
9
- import type * as SDKJSON from '@stainless/sdk-json';
10
-
11
- type Item = IndexEntry & IndexMethod;
12
-
13
- export interface SearchResult {
14
- item: Item;
15
- score?: number;
16
- refIndex: number;
17
- }
18
-
19
- export function consolidate(results: IndexEntry[]) {
20
- const resources = new Set<string>();
21
- const methods = new Set<string>();
22
-
23
- for (const entry of results) {
24
- const parsed = parseStainlessPath(entry.stainlessPath)!;
25
- if (parsed.method) methods.add(parsed.routable!);
26
- else resources.add(parsed.routable!);
27
- }
28
-
29
- const filtered = Array.from(methods).filter((path) => !resources.has(path.split(' >').at(0)!));
30
- return [...resources, ...filtered];
31
- }
32
-
33
- export function render(
34
- spec: SDKJSON.Spec,
35
- language: DocsLanguage,
36
- items: Item[],
37
- includeModelProperties: boolean,
38
- ) {
39
- const env = {
40
- spec,
41
- language,
42
- options: {
43
- renderNestedResources: false,
44
- includeModelProperties,
45
- },
46
- };
47
-
48
- const paths = consolidate(items);
49
- const output = paths.map((entry) => {
50
- const parsed = parseStainlessPath(entry)!;
51
- const resource = getResourceFromSpec(parsed.resource!, spec)!;
52
- const target = parsed.method ? resource.methods[parsed.method]! : resource;
53
- const content = renderMarkdown(env, target);
54
- return [entry, content];
55
- });
56
-
57
- return Object.fromEntries(output);
58
- }
59
-
60
- export async function searchAndRender(
61
- spec: SDKJSON.Spec,
62
- language: DocsLanguage,
63
- query: string,
64
- limit?: number,
65
- includeModelProperties: boolean = false,
66
- ) {
67
- const results = await search(spec, language, query, limit);
68
- const items = results.map(({ item }) => item);
69
- return render(spec, language, items, includeModelProperties);
70
- }
71
-
72
- export async function search(
73
- spec: SDKJSON.Spec,
74
- language: DocsLanguage,
75
- query: string,
76
- limit: number = 100,
77
- ): Promise<SearchResult[]> {
78
- const fuseIndex = buildIndex(spec, language);
79
-
80
- // only HTTP methods are useful for MCP
81
- const httpMethodEntries = fuseIndex.content.filter((entry) => entry.kind === 'http_method') as Item[];
82
-
83
- // build BM25 retriever if we have HTTP methods
84
- let bm25Retriever: BM25Retriever | null = null;
85
- if (httpMethodEntries.length > 0) {
86
- const documents = httpMethodEntries.map((entry) => {
87
- // empirically, endpoint + summary seems to be a reasonable semantic encapsulation of what the endpoint does
88
- const content = `${entry.endpoint} ${entry.summary}`;
89
- return {
90
- // stem the content - we will be stemming the query as well
91
- pageContent: stemText(content),
92
- metadata: {
93
- stainlessPath: entry.stainlessPath,
94
- },
95
- };
96
- });
97
-
98
- bm25Retriever = BM25Retriever.fromDocuments(documents, { k: 100 });
99
- }
100
-
101
- // get initial results from Fuse
102
- const rawResults = fuseSearch(fuseIndex, query, 100).filter(
103
- (r) => r.item.kind === 'http_method',
104
- ) as SearchResult[];
105
-
106
- // only keep HTTP methods
107
- const filtered = rawResults.filter((r) => r.item.kind === 'http_method');
108
-
109
- // stem the query and apply BM25 reranking
110
- if (filtered.length > 0 && bm25Retriever) {
111
- const stemmedQuery = stemText(query);
112
-
113
- // get BM25-ranked result
114
- const results = await bm25Retriever.invoke(stemmedQuery);
115
- const reranked = results.map((doc) => doc.metadata);
116
-
117
- // build a map of Fuse results by path for fast lookup
118
- const sortStart = Date.now();
119
- const fuseResultsByPath = new Map(filtered.map((r) => [r.item.stainlessPath, r]));
120
-
121
- // use BM25 ordering to reorder Fuse results
122
- const reorderedResults: SearchResult[] = [];
123
- for (const doc of reranked) {
124
- const fuseResult = fuseResultsByPath.get(doc.stainlessPath);
125
- if (fuseResult) {
126
- reorderedResults.push(fuseResult);
127
- }
128
- }
129
-
130
- // replace filtered with reordered results
131
- filtered.length = 0;
132
- filtered.push(...reorderedResults);
133
- console.debug(` [SORT] Reranked in ${Date.now() - sortStart}ms`);
134
- }
135
-
136
- return filtered.slice(0, limit);
137
- }
138
-
139
- function stemText(text: string): string {
140
- if (!text) return '';
141
-
142
- // tokenize manually and stem each word
143
- const words = text.toLowerCase().split(/\s+/);
144
- const stemmedWords = words
145
- .map((word) => {
146
- // remove punctuation and stem
147
- const cleaned = word.replace(/[^\w]/g, '');
148
- if (!cleaned) return '';
149
- return natural.LancasterStemmer.stem(cleaned);
150
- })
151
- .filter((w) => w);
152
-
153
- return stemmedWords.join(' ');
154
- }
155
-
156
- export { generateIndex };
@@ -1,86 +0,0 @@
1
- import * as React from 'react';
2
- import { renderToStaticMarkup } from 'react-dom/server';
3
- import type * as SDKJSON from '@stainless/sdk-json';
4
- import type { DocsLanguage } from '../routing';
5
-
6
- import { DocsProvider, useLanguageComponents } from '../contexts';
7
-
8
- import style from '../style';
9
- import { ComponentProvider } from '../contexts/component';
10
-
11
- type ProvidersProps = {
12
- language: DocsLanguage;
13
- children: React.ReactNode;
14
- };
15
-
16
- function Providers({ language, children }: ProvidersProps) {
17
- return (
18
- <DocsProvider spec={null} language={language}>
19
- <ComponentProvider
20
- components={{
21
- SDKReference({ stainlessPath, children }) {
22
- if (!stainlessPath) return children;
23
- return <span className={style.TypeReference}>{children}</span>;
24
- },
25
- }}
26
- >
27
- {children}
28
- </ComponentProvider>
29
- </DocsProvider>
30
- );
31
- }
32
-
33
- function RenderType({ type, full }: { type: SDKJSON.Type; full?: boolean }) {
34
- const { Type, TypeName } = useLanguageComponents();
35
- return full ? <Type type={type} /> : <TypeName type={type} />;
36
- }
37
-
38
- export function typeName(language: DocsLanguage, type: SDKJSON.Type) {
39
- const component = (
40
- <Providers language={language}>
41
- <RenderType type={type} />
42
- </Providers>
43
- );
44
-
45
- return renderToStaticMarkup(component);
46
- }
47
-
48
- export function type(language: DocsLanguage, type: SDKJSON.Type) {
49
- const component = (
50
- <Providers language={language}>
51
- <RenderType type={type} full={true} />
52
- </Providers>
53
- );
54
-
55
- return renderToStaticMarkup(component);
56
- }
57
-
58
- function RenderDeclaration({ decl }: { decl: SDKJSON.DeclarationNode }) {
59
- const { Declaration } = useLanguageComponents();
60
- return <Declaration decl={decl} />;
61
- }
62
-
63
- export function declaration(language: DocsLanguage, decl: SDKJSON.DeclarationNode) {
64
- const component = (
65
- <Providers language={language}>
66
- <RenderDeclaration decl={decl} />
67
- </Providers>
68
- );
69
-
70
- return renderToStaticMarkup(component);
71
- }
72
-
73
- function RenderMethod({ method }: { method: SDKJSON.DeclarationNode }) {
74
- const { MethodSignature } = useLanguageComponents();
75
- return <MethodSignature decl={method} />;
76
- }
77
-
78
- export function methodSignature(language: DocsLanguage, decl: SDKJSON.DeclarationNode) {
79
- const component = (
80
- <Providers language={language}>
81
- <RenderMethod method={decl} />
82
- </Providers>
83
- );
84
-
85
- return renderToStaticMarkup(component);
86
- }
@@ -1,88 +0,0 @@
1
- import { searchClient } from '@algolia/client-search';
2
- import { generateChatIndex, generateIndex } from '../indexer';
3
- import { SearchableAttributes, SearchableAttributesChat } from '../types';
4
- import type * as SDKJSON from '@stainless/sdk-json';
5
- import type { ResultRecordType, SearchSettings, SearchParams, ResultType } from '../types';
6
-
7
- export async function buildIndex(
8
- appId: string,
9
- indexName: string,
10
- writeKey: string,
11
- spec: SDKJSON.Spec,
12
- renderMarkdown: (_: string) => string | null,
13
- ): Promise<void> {
14
- if (!appId || !indexName || !writeKey) return;
15
- const objects = Array.from(generateIndex(spec, renderMarkdown));
16
- const client = searchClient(appId, writeKey);
17
-
18
- await client.setSettings({
19
- indexName,
20
- indexSettings: {
21
- highlightPreTag: '<mark>',
22
- highlightPostTag: '</mark>',
23
- customRanking: ['asc(priority)'],
24
- attributesForFaceting: ['language', 'kind'],
25
- searchableAttributes: [...SearchableAttributes],
26
- },
27
- });
28
-
29
- await client.replaceAllObjects({ indexName, objects });
30
- }
31
-
32
- export async function buildChatIndex(
33
- appId: string,
34
- indexName: string,
35
- writeKey: string,
36
- spec: SDKJSON.Spec,
37
- ): Promise<void> {
38
- if (!appId || !indexName || !writeKey) return;
39
- const objects = Array.from(generateChatIndex(spec));
40
- const client = searchClient(appId, writeKey);
41
-
42
- await client.setSettings({
43
- indexName,
44
- indexSettings: {
45
- attributesForFaceting: ['language'],
46
- attributeForDistinct: 'stainlessPath',
47
- searchableAttributes: SearchableAttributesChat,
48
- },
49
- });
50
-
51
- await client.replaceAllObjects({ indexName, objects });
52
- }
53
-
54
- export async function search({
55
- settings: { appId, indexName, searchKey },
56
- params: { query, language, kind },
57
- }: {
58
- params: SearchParams;
59
- settings: SearchSettings;
60
- }): Promise<ResultType | undefined> {
61
- const client = searchClient(appId, searchKey);
62
- const filters = language ? `language:${language}` : undefined;
63
- const facetFilters = kind ? [`kind:${kind}`] : undefined;
64
- const { results } = await client.search<ResultRecordType>({
65
- requests: [
66
- {
67
- query,
68
- indexName,
69
- filters,
70
- hitsPerPage: 5,
71
- facets: ['kind'],
72
- },
73
- {
74
- query,
75
- indexName,
76
- filters,
77
- facetFilters,
78
- facets: ['kind'],
79
- hitsPerPage: 50,
80
- },
81
- ],
82
- });
83
-
84
- if ('hits' in results[0]! && 'hits' in results[1]!) {
85
- const [{ nbHits, facets }, { hits }] = results;
86
- return { hits, nbHits: nbHits ?? 0, facets };
87
- }
88
- }
@@ -1,19 +0,0 @@
1
- import Fuse, { FuseIndex } from 'fuse.js';
2
- import { DocsLanguage } from '../../routing';
3
- import { generateIndex } from '../indexer';
4
- import { IndexEntry, SearchableAttributes } from '../types';
5
- import type * as SDKJSON from '@stainless/sdk-json';
6
-
7
- export type FuseIndexData = { content: IndexEntry[]; index: FuseIndex<IndexEntry> };
8
-
9
- export function buildIndex(spec: SDKJSON.Spec, language?: DocsLanguage): FuseIndexData {
10
- const idx = Array.from(generateIndex(spec, undefined, false));
11
- const content = language ? idx.filter((entry) => entry.language === language) : idx;
12
- const index = Fuse.createIndex([...SearchableAttributes], content);
13
- return { content, index };
14
- }
15
-
16
- export function search({ content, index }: FuseIndexData, query: string, limit: number = 100) {
17
- const fuse = new Fuse(content, { keys: [...SearchableAttributes] }, index);
18
- return fuse.search(query).slice(0, limit);
19
- }
@@ -1,17 +0,0 @@
1
- import type { GuideResultType } from '../types';
2
-
3
- async function loadPagefind(path: string) {
4
- const url = new URL(path, import.meta.url).href;
5
- return await import(/* @vite-ignore */ url);
6
- }
7
-
8
- export async function guideSearch(
9
- loadPath: string,
10
- query: string,
11
- limit?: number,
12
- ): Promise<GuideResultType[]> {
13
- const index = await loadPagefind(loadPath);
14
- const response = await index.search(query);
15
- const items = limit ? response.results.slice(0, limit) : response.results;
16
- return Promise.all(items.map((result: any) => result.data().then((data: any) => ({ ...result, data }))));
17
- }
@@ -1,32 +0,0 @@
1
- import { DocsLanguage } from '../../routing';
2
- import { generateIndex } from '../indexer';
3
- import { IndexEntry, SearchableAttributes } from '../types';
4
- import type * as SDKJSON from '@stainless/sdk-json';
5
-
6
- export function buildIndex(spec: SDKJSON.Spec) {
7
- return generateIndex(spec, undefined, false);
8
- }
9
-
10
- function* findEntryInIndex(index: Generator<IndexEntry>, language: string, query: string) {
11
- for (const entry of index) {
12
- if (entry.language !== language) continue;
13
- for (const attr of SearchableAttributes) {
14
- const attr_ = attr in entry ? (attr as keyof typeof entry) : null;
15
- if (attr_ && entry[attr_] && typeof entry[attr_] === 'string' && entry[attr_].includes(query))
16
- yield entry;
17
- }
18
- }
19
- }
20
-
21
- export function search(
22
- index: Generator<IndexEntry>,
23
- language: DocsLanguage,
24
- query: string,
25
- limit: number = 100,
26
- ) {
27
- const results = findEntryInIndex(index, language, query);
28
- const sorted = Array.from(results)
29
- .sort((a, b) => a.priority - b.priority)
30
- .slice(0, limit);
31
- return sorted;
32
- }
@@ -1,183 +0,0 @@
1
- import { Folder, Box, Code, Wrench, BookOpenText, Search } from 'lucide-react';
2
- import { useLanguage } from '../contexts';
3
- import { useComponents } from '../contexts/use-components';
4
- import { GuideResultType, QueryKindsType, ResultRecordType, SearchAttributeNames } from './types';
5
-
6
- import style from '../style';
7
-
8
- export const QueryKindDisplay: Record<QueryKindsType, { name: string; icon: typeof Folder }> = {
9
- all: { name: 'Results', icon: Search },
10
- resource: { name: 'Resources', icon: Folder },
11
- http_method: { name: 'Methods', icon: Box },
12
- model: { name: 'Types', icon: Code },
13
- property: { name: 'Properties', icon: Wrench },
14
- guide: { name: 'Guide', icon: BookOpenText },
15
- };
16
-
17
- export type HighlightProps = {
18
- result: ResultRecordType;
19
- name: SearchAttributeNames;
20
- };
21
-
22
- export function Highlight({ result, name }: HighlightProps) {
23
- const value = result._highlightResult[name]?.value;
24
- if (value) return <span dangerouslySetInnerHTML={{ __html: value }} />;
25
- }
26
-
27
- export type SearchResultProps = {
28
- result: ResultRecordType;
29
- };
30
-
31
- export function SearchResultBreadcrumb({ result }: SearchResultProps) {
32
- const Docs = useComponents();
33
- const Icon = QueryKindDisplay[result.kind].icon;
34
- const items = result.crumbs?.map((crumb) => (
35
- <span key={crumb} className={style.SearchBreadcrumbItem}>
36
- {crumb}
37
- </span>
38
- ));
39
-
40
- return (
41
- <div className={style.SearchBreadcrumb}>
42
- <Icon className={style.Icon} size={14} />
43
- {Array.isArray(result.crumbs) && (
44
- <Docs.Join items={items}>
45
- <span className={style.SearchBreadcrumbDivider}>{'›'}</span>
46
- </Docs.Join>
47
- )}
48
- </div>
49
- );
50
- }
51
-
52
- export function SearchResult({ result }: SearchResultProps) {
53
- return (
54
- <div className={style.SearchResult} data-stldocs-search-result={result.kind}>
55
- <SearchResultBreadcrumb result={result} />
56
- <SearchResultContent result={result} />
57
- </div>
58
- );
59
- }
60
-
61
- export type GuideResultProps = {
62
- result: GuideResultType;
63
- };
64
-
65
- export function GuideResult({ result }: GuideResultProps) {
66
- const Docs = useComponents();
67
- const Icon = QueryKindDisplay['guide'].icon;
68
- const path = result.data.url
69
- .slice(1, -1)
70
- .split('/')
71
- .map((crumb) => (
72
- <span className={style.SearchBreadcrumbItem} key={crumb}>
73
- {crumb}
74
- </span>
75
- ));
76
-
77
- const crumbs =
78
- path.length > 1
79
- ? path
80
- : [
81
- <span className={style.SearchBreadcrumbItem} key="overview">
82
- Overview
83
- </span>,
84
- ];
85
-
86
- return (
87
- <div className={style.SearchResult} data-stldocs-search-result="guide">
88
- <div className={style.SearchBreadcrumb}>
89
- <Icon className={style.Icon} size={14} />
90
- <Docs.Join items={crumbs}>
91
- <span className={style.SearchBreadcrumbDivider}>{'›'}</span>
92
- </Docs.Join>
93
- </div>
94
- <h3 className={style.SearchResultGuideTitle}>{result.data.meta.title}</h3>
95
- <div
96
- className={style.SearchResultGuideExcerpt}
97
- dangerouslySetInnerHTML={{ __html: result.data.excerpt }}
98
- />
99
- </div>
100
- );
101
- }
102
-
103
- export function SearchResultContent({ result }: SearchResultProps) {
104
- const Docs = useComponents();
105
- const language = useLanguage();
106
-
107
- switch (result.kind) {
108
- case 'http_method':
109
- return (
110
- <>
111
- <Docs.MethodHeader
112
- level="h5"
113
- title={<Highlight result={result} name={result.summary ? 'summary' : 'title'} />}
114
- signature={result['qualified'] && <Highlight result={result} name={'qualified'} />}
115
- >
116
- <Docs.MethodRoute
117
- httpMethod={result.httpMethod}
118
- endpoint={<Highlight result={result} name="endpoint" />}
119
- />
120
- </Docs.MethodHeader>
121
- <div className={`${style.MethodDescription} ${style.Content}`}>
122
- <Highlight result={result} name="description" />
123
- </div>
124
- </>
125
- );
126
-
127
- case 'model': {
128
- const properties =
129
- result.children?.map((child, index) => (
130
- <span key={index} className={style.TextIdentifier}>
131
- {child}
132
- </span>
133
- )) ?? [];
134
-
135
- return (
136
- <div className={style.Property} data-stldocs-language={language}>
137
- <div className={style.PropertyHeader}>
138
- <span className={style.PropertyName}>
139
- <Highlight result={result} name={result.title ? 'title' : 'name'} />
140
- </span>
141
- </div>
142
- <span className={style.PropertyDeclaration}>
143
- <Highlight result={result} name="ident" />:{' '}
144
- <Docs.Join items={properties} limit={3}>
145
- <span className={style.TextPunctuation}>, </span>
146
- </Docs.Join>
147
- </span>
148
- </div>
149
- );
150
- }
151
-
152
- case 'resource':
153
- return (
154
- <div className={style.SearchResultResourceInfo}>
155
- <span className={style.SearchResultResourceTitle}>
156
- <Highlight result={result} name="title" />
157
- </span>
158
- <span className={style.SearchResultResourcePath}>
159
- <Highlight result={result} name="QualifiedName" />
160
- </span>
161
- </div>
162
- );
163
-
164
- case 'property':
165
- return (
166
- <div className={style.Property} data-stldocs-language={language}>
167
- <div className={style.PropertyHeader}>
168
- <span className={style.PropertyName}>
169
- <Highlight result={result} name="name" />
170
- </span>
171
- <span className={style.PropertyTypeName}>
172
- <span dangerouslySetInnerHTML={{ __html: result.type ?? '' }} />
173
- </span>
174
- </div>
175
- {result.docstring && (
176
- <span className={style.PropertyDescription}>
177
- <Highlight result={result} name="docstring" />
178
- </span>
179
- )}
180
- </div>
181
- );
182
- }
183
- }
@@ -1,64 +0,0 @@
1
- import { useReducer } from 'react';
2
- import { QueryKindsType, ResultRecordType } from './types';
3
-
4
- export type SearchReducerState = {
5
- results: ResultRecordType[];
6
- resultsCount: number;
7
- filterKind?: QueryKindsType;
8
- filterKindCount?: Record<QueryKindsType, number>;
9
- keyboardSelection?: number;
10
- selectedIndex: number;
11
- searchQuery: string;
12
- };
13
-
14
- export type SearchReducerAction =
15
- | { action: 'DecrementSelection' }
16
- | { action: 'IncrementSelection' }
17
- | { action: 'SetSelectedIndex'; selectedIndex: number }
18
- | { action: 'SetFilterKind'; filterKind: QueryKindsType }
19
- | { action: 'UpdateQuery'; searchQuery: string }
20
- | ({ action: 'UpdateResults' } & Pick<SearchReducerState, 'results' | 'resultsCount' | 'filterKindCount'>);
21
-
22
- export const SearchReducerDefaults: SearchReducerState = {
23
- results: [],
24
- resultsCount: 0,
25
- selectedIndex: 0,
26
- searchQuery: '',
27
- };
28
-
29
- export function searchReducer(state: SearchReducerState, op: SearchReducerAction): SearchReducerState {
30
- switch (op.action) {
31
- case 'IncrementSelection': {
32
- const value = Math.min(state.resultsCount, state.selectedIndex + 1);
33
- return { ...state, selectedIndex: value, keyboardSelection: value };
34
- }
35
-
36
- case 'DecrementSelection': {
37
- const value = Math.max(0, state.selectedIndex - 1);
38
- return { ...state, selectedIndex: value, keyboardSelection: value };
39
- }
40
-
41
- case 'SetSelectedIndex':
42
- return { ...state, selectedIndex: op.selectedIndex };
43
-
44
- case 'SetFilterKind':
45
- return { ...state, filterKind: op.filterKind };
46
-
47
- case 'UpdateQuery':
48
- return { ...state, searchQuery: op.searchQuery };
49
-
50
- case 'UpdateResults':
51
- return {
52
- ...state,
53
- results: op.results,
54
- resultsCount: op.resultsCount,
55
- filterKindCount: op.filterKindCount,
56
- keyboardSelection: undefined,
57
- selectedIndex: 0,
58
- };
59
- }
60
- }
61
-
62
- export function useSearchReducer() {
63
- return useReducer(searchReducer, SearchReducerDefaults);
64
- }