@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.
- package/dist/{breadcrumbs-D5viAm7a.d.ts → breadcrumbs-wJ7A9MGt.d.ts} +2 -2
- package/dist/{component-generics-BnrVqdQj.d.ts → component-generics--y1IC_M-.d.ts} +2 -1
- package/dist/{component-generics-Df4EDvxk.js → component-generics-D3ybuN5r.js} +5 -1
- package/dist/components/breadcrumbs.d.ts +1 -1
- package/dist/components/breadcrumbs.js +13 -14
- package/dist/components/chat.d.ts +3 -3
- package/dist/components/chat.js +64 -50
- package/dist/components/icons.d.ts +10 -10
- package/dist/components/icons.js +1 -1
- package/dist/components/index.d.ts +11 -12
- package/dist/components/index.js +14 -15
- package/dist/components/method.d.ts +1 -1
- package/dist/components/method.js +13 -14
- package/dist/components/overview.d.ts +1 -1
- package/dist/components/overview.js +13 -14
- package/dist/components/primitives.d.ts +1 -1
- package/dist/components/primitives.js +13 -14
- package/dist/components/properties.d.ts +1 -1
- package/dist/components/properties.js +13 -14
- package/dist/components/sdk.d.ts +2 -2
- package/dist/components/sdk.js +13 -14
- package/dist/components/sidebar.d.ts +1 -1
- package/dist/components/sidebar.js +13 -14
- package/dist/components/snippets.d.ts +3 -3
- package/dist/components/snippets.js +13 -14
- package/dist/contexts/component-generics.d.ts +1 -1
- package/dist/contexts/component-generics.js +1 -1
- package/dist/contexts/component-types.d.ts +11 -12
- package/dist/contexts/component-types.js +0 -1
- package/dist/contexts/component.d.ts +14 -14
- package/dist/contexts/component.js +13 -14
- package/dist/contexts/docs.d.ts +1 -1
- package/dist/contexts/docs.js +1 -1
- package/dist/contexts/index.d.ts +18 -19
- package/dist/contexts/index.js +13 -14
- package/dist/contexts/markdown.d.ts +1 -1
- package/dist/contexts/markdown.js +2 -2
- package/dist/contexts/navigation.d.ts +2 -2
- package/dist/contexts/navigation.js +1 -1
- package/dist/contexts/search.d.ts +3 -3
- package/dist/contexts/search.js +13 -14
- package/dist/contexts/use-components.d.ts +10 -11
- package/dist/contexts/use-components.js +2 -2
- package/dist/contexts-CMNI3ctP.js +3799 -0
- package/dist/{docs-DhNaW0DE.d.ts → docs-BvahWQ28.d.ts} +2 -1
- package/dist/{docs-Cj25B-Sh.js → docs-CopwX9a7.js} +5 -1
- package/dist/icons-yb-Jhkmg.js +753 -0
- package/dist/{index-d8_VR8Z5.d.ts → index-BmPNhnpe.d.ts} +6 -6
- package/dist/{index-BXO3gZup.d.ts → index-D5NMSAld.d.ts} +26 -25
- package/dist/index-rVFBdVz8.d.ts +15 -0
- package/dist/index.d.ts +20 -21
- package/dist/index.js +15 -7700
- package/dist/languages/go.d.ts +11 -12
- package/dist/languages/go.js +13 -14
- package/dist/languages/http.d.ts +11 -12
- package/dist/languages/http.js +13 -14
- package/dist/languages/index.d.ts +11 -12
- package/dist/languages/index.js +13 -14
- package/dist/languages/java.d.ts +11 -12
- package/dist/languages/java.js +13 -14
- package/dist/languages/python.d.ts +11 -12
- package/dist/languages/python.js +13 -14
- package/dist/languages/ruby.d.ts +11 -12
- package/dist/languages/ruby.js +13 -14
- package/dist/languages/typescript.d.ts +11 -12
- package/dist/languages/typescript.js +13 -14
- package/dist/markdown/index.d.ts +3 -3
- package/dist/markdown/index.js +13 -14
- package/dist/markdown/md.js +1 -1
- package/dist/markdown/utils.d.ts +3 -3
- package/dist/markdown/utils.js +1 -1
- package/dist/{markdown-DunIdqFE.js → markdown-BmpyokB7.js} +9 -5
- package/dist/{markdown-DN8KaRR2.d.ts → markdown-w5UpIiGc.d.ts} +2 -1
- package/dist/{method-c3XDArUn.d.ts → method-CLpRObBV.d.ts} +7 -6
- package/dist/{navigation-BSn6PX-7.d.ts → navigation-Blr3LaES.d.ts} +3 -2
- package/dist/{navigation-CuCg3le8.js → navigation-CGr5_w6z.js} +5 -1
- package/dist/{overview-D21weqVJ.d.ts → overview-DBnqhjAg.d.ts} +6 -6
- package/dist/{primitives-iB9fIrMF.d.ts → primitives-BFubD3w8.d.ts} +9 -8
- package/dist/{properties-Ba6F_GGj.d.ts → properties-DeQRa6VK.d.ts} +4 -4
- package/dist/{routing-C8oZYLsf.js → routing-8itEXLx6.js} +1 -1
- package/dist/{routing-BE6Vrs-z.d.ts → routing-DNN8R6bZ.d.ts} +1 -1
- package/dist/routing.d.ts +1 -1
- package/dist/routing.js +3 -180
- package/dist/{sdk-D2x2l6JH.d.ts → sdk-BVQyp5Dw.d.ts} +14 -13
- package/dist/search/index.d.ts +6 -6
- package/dist/search/index.js +233 -110
- package/dist/search/providers/algolia.d.ts +2 -2
- package/dist/search/providers/algolia.js +13 -14
- package/dist/search/providers/fuse.d.ts +2 -2
- package/dist/search/providers/fuse.js +13 -14
- package/dist/search/providers/pagefind.d.ts +2 -2
- package/dist/search/providers/pagefind.js +1 -1
- package/dist/search/providers/walker.d.ts +2 -2
- package/dist/search/providers/walker.js +13 -14
- package/dist/search/types.d.ts +2 -2
- package/dist/search/types.js +1 -1
- package/dist/{search-KMqOU2tz.d.ts → search-CPp6HpUy.d.ts} +3 -2
- package/dist/{sidebar-B1X4gmY2.d.ts → sidebar-BoPLeaxp.d.ts} +5 -4
- package/dist/{snippets-BApdMOXp.d.ts → snippets-DLHH_Voi.d.ts} +7 -6
- package/dist/{style-BWu-Pqcm.d.ts → style-BEMLtSIK.d.ts} +0 -10
- package/dist/{style-CkbsakoF.js → style-CPgcT0Fw.js} +1 -11
- package/dist/style.d.ts +1 -1
- package/dist/style.js +1 -1
- package/dist/styles/main.css +51 -20
- package/dist/styles/main.js +0 -0
- package/dist/styles/primitives.css +1 -0
- package/dist/styles/primitives.js +0 -0
- package/dist/styles/resets.css +1 -0
- package/dist/styles/resets.js +0 -0
- package/dist/styles/search.css +1 -0
- package/dist/styles/search.js +0 -0
- package/dist/styles/sidebar.css +1 -0
- package/dist/styles/sidebar.js +0 -0
- package/dist/styles/snippets.css +1 -0
- package/dist/styles/snippets.js +0 -0
- package/dist/styles/variables.css +2 -0
- package/dist/styles/variables.js +0 -0
- package/dist/{types-BLgvxY4i.d.ts → types-DNSz4kuM.d.ts} +1 -1
- package/dist/{use-components-DI-AbT-D.js → use-components-BHEwm0mE.js} +1 -1
- package/dist/{utils-BhYTrLot.js → utils-2FmcHPHp.js} +2 -2
- package/dist/{utils-B9JL_XWH.d.ts → utils-DVi3gJLL.d.ts} +2 -2
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +2 -2
- package/package.json +63 -10
- package/dist/components/dropdown.d.ts +0 -2
- package/dist/components/dropdown.js +0 -4
- package/dist/components/scripts/dropdown.d.ts +0 -12
- package/dist/components/scripts/dropdown.js +0 -50
- package/dist/contexts-DO0sMzym.js +0 -2581
- package/dist/dropdown-Dv9VAYCW.d.ts +0 -42
- package/dist/dropdown-kUhwBigR.js +0 -38
- package/dist/icons--8QR-PrL.js +0 -222
- package/dist/index-BW6OPqAo.d.ts +0 -16
- package/dist/mcp.cjs +0 -983418
- package/src/components/breadcrumbs.tsx +0 -94
- package/src/components/chat.tsx +0 -157
- package/src/components/icons.tsx +0 -584
- package/src/components/index.ts +0 -8
- package/src/components/method.tsx +0 -145
- package/src/components/overview.tsx +0 -172
- package/src/components/primitives.tsx +0 -301
- package/src/components/properties.tsx +0 -132
- package/src/components/sdk.tsx +0 -408
- package/src/components/sidebar.tsx +0 -99
- package/src/components/snippets.tsx +0 -197
- package/src/contexts/component-generics.tsx +0 -43
- package/src/contexts/component-types.tsx +0 -5
- package/src/contexts/component.tsx +0 -32
- package/src/contexts/docs.tsx +0 -86
- package/src/contexts/index.tsx +0 -20
- package/src/contexts/markdown.tsx +0 -44
- package/src/contexts/navigation.tsx +0 -44
- package/src/contexts/search.tsx +0 -27
- package/src/contexts/use-components.tsx +0 -4
- package/src/hooks/use-strict-context.tsx +0 -16
- package/src/index.ts +0 -6
- package/src/languages/go.tsx +0 -281
- package/src/languages/http.tsx +0 -329
- package/src/languages/index.ts +0 -26
- package/src/languages/java.tsx +0 -358
- package/src/languages/python.tsx +0 -258
- package/src/languages/ruby.tsx +0 -327
- package/src/languages/typescript.tsx +0 -399
- package/src/markdown/index.ts +0 -112
- package/src/markdown/md.ts +0 -45
- package/src/markdown/utils.ts +0 -52
- package/src/routing.ts +0 -238
- package/src/search/form.tsx +0 -130
- package/src/search/index.tsx +0 -1
- package/src/search/indexer.ts +0 -248
- package/src/search/mcp.ts +0 -156
- package/src/search/printer.tsx +0 -86
- package/src/search/providers/algolia.ts +0 -88
- package/src/search/providers/fuse.ts +0 -19
- package/src/search/providers/pagefind.ts +0 -17
- package/src/search/providers/walker.ts +0 -32
- package/src/search/results.tsx +0 -183
- package/src/search/state.ts +0 -64
- package/src/search/types.ts +0 -116
- package/src/style.ts +0 -185
- package/src/styles/main.css +0 -989
- package/src/styles/primitives.css +0 -392
- package/src/styles/resets.css +0 -39
- package/src/styles/search.css +0 -359
- package/src/styles/sidebar.css +0 -85
- package/src/styles/snippets.css +0 -130
- package/src/styles/variables.css +0 -86
- package/src/utils.ts +0 -40
- /package/dist/{chunk-Bp6m_JJh.js → chunk-DsStOjWQ.js} +0 -0
- /package/dist/{md-Dg8aOyMA.js → md-DxiV1_vy.js} +0 -0
- /package/dist/{pagefind-ChrPfuVv.js → pagefind-BaK1krMe.js} +0 -0
- /package/dist/{types-DFN4M1Sp.js → types-__XoFvJ_.js} +0 -0
- /package/dist/{utils-ByZH9QWT.js → utils-BCfb0F9R.js} +0 -0
- /package/dist/{utils-DlayebL1.d.ts → utils-D43p_yTd.d.ts} +0 -0
package/src/routing.ts
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import type * as SDKJSON from '@stainless/sdk-json';
|
|
2
|
-
|
|
3
|
-
export const Languages = [
|
|
4
|
-
'http',
|
|
5
|
-
'node',
|
|
6
|
-
'python',
|
|
7
|
-
'go',
|
|
8
|
-
'typescript',
|
|
9
|
-
'terraform',
|
|
10
|
-
'ruby',
|
|
11
|
-
'java',
|
|
12
|
-
'kotlin',
|
|
13
|
-
] as const;
|
|
14
|
-
|
|
15
|
-
export const SupportedLanguageSyntaxes = [
|
|
16
|
-
'http',
|
|
17
|
-
'javascript',
|
|
18
|
-
'python',
|
|
19
|
-
'go',
|
|
20
|
-
'typescript',
|
|
21
|
-
'terraform',
|
|
22
|
-
'ruby',
|
|
23
|
-
'java',
|
|
24
|
-
'kotlin',
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
export type DocsLanguage = (typeof Languages)[number];
|
|
28
|
-
|
|
29
|
-
export const LanguageNames: Record<DocsLanguage, string> = {
|
|
30
|
-
http: 'HTTP',
|
|
31
|
-
node: 'TypeScript',
|
|
32
|
-
typescript: 'TypeScript',
|
|
33
|
-
python: 'Python',
|
|
34
|
-
go: 'Go',
|
|
35
|
-
ruby: 'Ruby',
|
|
36
|
-
java: 'Java',
|
|
37
|
-
kotlin: 'Kotlin',
|
|
38
|
-
terraform: 'Terraform',
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export function getLanguageSnippet(language: DocsLanguage) {
|
|
42
|
-
return language === 'http' ? ('http.curl' as const) : (`${language}.default` as const);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function isSupportedLanguage(language: string): language is DocsLanguage {
|
|
46
|
-
return Languages.includes(language as DocsLanguage);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const DefaultLanguage = 'http';
|
|
50
|
-
|
|
51
|
-
const StainlessPathPattern =
|
|
52
|
-
/(\(resource\) (?<resource>[^\s]+))( > (\(method\) (?<method>[^\s]+)|\(model\) (?<model>[^\s]+))?)?/;
|
|
53
|
-
|
|
54
|
-
export type ParsedStainlessPath = ReturnType<typeof parseStainlessPath>;
|
|
55
|
-
|
|
56
|
-
export function parseStainlessPath(stainlessPath: string) {
|
|
57
|
-
const match = stainlessPath.match(StainlessPathPattern);
|
|
58
|
-
|
|
59
|
-
if (!match?.groups) return null;
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
resource: match.groups.resource?.split('.') ?? null,
|
|
63
|
-
method: match.groups.method ?? null,
|
|
64
|
-
model: match.groups.model ?? null,
|
|
65
|
-
routable: match.groups.model ? match[1] : match[0],
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function trimStainlessPath(stainlessPath: string) {
|
|
70
|
-
return stainlessPath.replace(/ > \([^\s]+\)$/, '');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function getResource(stainlessPath: string) {
|
|
74
|
-
const parsed = parseStainlessPath(stainlessPath);
|
|
75
|
-
return parsed?.resource?.[0];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function parseRoute(
|
|
79
|
-
basePath: string,
|
|
80
|
-
route: string,
|
|
81
|
-
): { stainlessPath: string; language: DocsLanguage } {
|
|
82
|
-
if (!route.startsWith(basePath)) return { stainlessPath: '', language: DefaultLanguage };
|
|
83
|
-
|
|
84
|
-
if (basePath && route.startsWith(basePath)) route = route.slice(basePath.length);
|
|
85
|
-
|
|
86
|
-
let stainlessPath = '';
|
|
87
|
-
let elements = route.slice(1).split('/');
|
|
88
|
-
let language: DocsLanguage = DefaultLanguage;
|
|
89
|
-
|
|
90
|
-
if (elements[0] && Languages.includes(elements[0] as DocsLanguage)) {
|
|
91
|
-
language = elements[0] as DocsLanguage;
|
|
92
|
-
elements = elements.slice(1);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
while (elements.length > 0) {
|
|
96
|
-
const element = elements.shift();
|
|
97
|
-
switch (element) {
|
|
98
|
-
case 'resources':
|
|
99
|
-
stainlessPath += `(resource) ${elements.shift()}`;
|
|
100
|
-
break;
|
|
101
|
-
|
|
102
|
-
case 'subresources':
|
|
103
|
-
stainlessPath += `.${elements.shift()}`;
|
|
104
|
-
break;
|
|
105
|
-
|
|
106
|
-
case 'methods':
|
|
107
|
-
stainlessPath += ` > (method) ${elements.shift()}`;
|
|
108
|
-
break;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return { stainlessPath, language };
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function generateRoute(basePath: string, language: string, stainlessPath: string) {
|
|
116
|
-
const parsedPath = parseStainlessPath(stainlessPath);
|
|
117
|
-
if (!parsedPath) return null;
|
|
118
|
-
|
|
119
|
-
const path = [basePath.endsWith('/') ? basePath.slice(0, -1) : basePath];
|
|
120
|
-
if (language && language !== DefaultLanguage) path.push(language);
|
|
121
|
-
|
|
122
|
-
const resources = parsedPath.resource!.flatMap((name, index) => [
|
|
123
|
-
index > 0 ? 'subresources' : 'resources',
|
|
124
|
-
name,
|
|
125
|
-
]);
|
|
126
|
-
|
|
127
|
-
// Ensure model links always go to top-level resource page
|
|
128
|
-
const resourcePath = parsedPath.model ? resources.slice(0, 2) : resources;
|
|
129
|
-
path.push(...resourcePath);
|
|
130
|
-
|
|
131
|
-
if (parsedPath.method) path.push('methods', parsedPath.method);
|
|
132
|
-
|
|
133
|
-
return stainlessPath.length > parsedPath.routable!.length
|
|
134
|
-
? `${path.join('/')}#${encodeURIComponent(stainlessPath)}`
|
|
135
|
-
: path.join('/');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export type SpecTreeEntry = {
|
|
139
|
-
data: SDKJSON.Method | SDKJSON.Resource | SDKJSON.Model;
|
|
140
|
-
path: string[];
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
function* walkResource(
|
|
144
|
-
resource: SDKJSON.Resource,
|
|
145
|
-
path: string[],
|
|
146
|
-
includeModels?: boolean,
|
|
147
|
-
): Generator<SpecTreeEntry> {
|
|
148
|
-
yield { data: resource, path };
|
|
149
|
-
|
|
150
|
-
for (const data of Object.values(resource.methods)) {
|
|
151
|
-
yield { data, path: [...path, 'methods', data.name] };
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (includeModels)
|
|
155
|
-
for (const data of Object.values(resource.models)) {
|
|
156
|
-
yield { data, path: [...path, 'models', data.name] };
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
for (const data of Object.values(resource.subresources ?? {})) {
|
|
160
|
-
yield* walkResource(data, [...path, 'subresources', data.name]);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export function* walkTree(spec: SDKJSON.Spec, includeModels?: boolean) {
|
|
165
|
-
for (const data of Object.values(spec.resources)) {
|
|
166
|
-
yield* walkResource(data, ['resources', data.name], includeModels);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export type RouteEntry = {
|
|
171
|
-
title: string;
|
|
172
|
-
kind: SpecTreeEntry['data']['kind'];
|
|
173
|
-
language: DocsLanguage;
|
|
174
|
-
stainlessPath: string;
|
|
175
|
-
slug: string;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
export function generateRouteList({
|
|
179
|
-
spec,
|
|
180
|
-
languages,
|
|
181
|
-
excludeLanguages = [],
|
|
182
|
-
}: {
|
|
183
|
-
spec: SDKJSON.Spec;
|
|
184
|
-
languages?: DocsLanguage[];
|
|
185
|
-
excludeLanguages?: DocsLanguage[];
|
|
186
|
-
}): RouteEntry[] {
|
|
187
|
-
const entries = Array.from(walkTree(spec));
|
|
188
|
-
const langs = languages ?? spec.docs?.languages ?? ['http'];
|
|
189
|
-
|
|
190
|
-
return langs
|
|
191
|
-
.filter((lang) => Languages.includes(lang) && lang !== 'terraform')
|
|
192
|
-
.filter((lang) => !excludeLanguages?.includes(lang))
|
|
193
|
-
.flatMap((language) =>
|
|
194
|
-
entries.map(({ path, data: { title, kind, stainlessPath } }) => ({
|
|
195
|
-
title,
|
|
196
|
-
kind,
|
|
197
|
-
language,
|
|
198
|
-
stainlessPath,
|
|
199
|
-
slug: (language === 'http' ? path : [language, ...path]).join('/'),
|
|
200
|
-
})),
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
type ResourceOrMethod = SDKJSON.Resource | SDKJSON.Method;
|
|
205
|
-
|
|
206
|
-
export function findNavigationPath(items: ResourceOrMethod[], target: string): string[] | undefined {
|
|
207
|
-
for (const item of Object.values(items)) {
|
|
208
|
-
if (item.stainlessPath === target) return [item.stainlessPath];
|
|
209
|
-
if (item.kind === 'http_method') continue;
|
|
210
|
-
|
|
211
|
-
const path = findNavigationPath(
|
|
212
|
-
[...Object.values(item.methods ?? {}), ...Object.values(item.subresources ?? {})],
|
|
213
|
-
target,
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
if (path) return [item.stainlessPath, ...path];
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
export function expandToElement(el: HTMLElement | null) {
|
|
221
|
-
while (el) {
|
|
222
|
-
if (el instanceof HTMLDetailsElement) el.open = true;
|
|
223
|
-
el = el.parentElement;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export function scrollToPath(stainlessPath: string) {
|
|
228
|
-
const el = document.getElementById(stainlessPath);
|
|
229
|
-
if (el) {
|
|
230
|
-
expandToElement(el);
|
|
231
|
-
el.scrollIntoView({ behavior: 'smooth' });
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export function updateHistory(basePath: string, language: DocsLanguage, stainlessPath: string) {
|
|
236
|
-
const path = generateRoute(basePath, language, stainlessPath);
|
|
237
|
-
window.history.pushState({ stainlessPath, language }, '', path);
|
|
238
|
-
}
|
package/src/search/form.tsx
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { Search as SearchIcon, X as XIcon } from 'lucide-react';
|
|
3
|
-
import { QueryKinds, QueryKindsType, ResultData } from './types';
|
|
4
|
-
import { GuideResult, QueryKindDisplay, SearchResult } from './results';
|
|
5
|
-
import { guideSearch } from './providers/pagefind';
|
|
6
|
-
import { useLanguage, useSearch, useSearchContext } from '../contexts';
|
|
7
|
-
import { useComponents } from '../contexts/use-components';
|
|
8
|
-
|
|
9
|
-
import style from '../style';
|
|
10
|
-
|
|
11
|
-
export function SearchForm() {
|
|
12
|
-
const Docs = useComponents();
|
|
13
|
-
const search = useSearch();
|
|
14
|
-
const language = useLanguage();
|
|
15
|
-
const { onSelect, pageFind } = useSearchContext();
|
|
16
|
-
|
|
17
|
-
const [results, setResults] = React.useState<ResultData>(null!);
|
|
18
|
-
const [filterKind, setFilterKind] = React.useState<QueryKindsType>('all');
|
|
19
|
-
const [searchQuery, setSearchQuery] = React.useState<string>('');
|
|
20
|
-
const inputRef = React.useRef<HTMLInputElement>(null);
|
|
21
|
-
|
|
22
|
-
async function performSearch() {
|
|
23
|
-
const guideLimit = filterKind === 'guide' ? 25 : 5;
|
|
24
|
-
const kind = ['all', 'guide'].includes(filterKind) ? undefined : filterKind;
|
|
25
|
-
|
|
26
|
-
const [guideResults, apiResults] = await Promise.all([
|
|
27
|
-
pageFind ? guideSearch(pageFind, searchQuery, guideLimit) : [],
|
|
28
|
-
search({ query: searchQuery, kind, language }),
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
|
-
setResults({
|
|
32
|
-
items: filterKind === 'guide' ? guideResults : [...guideResults, ...(apiResults?.hits ?? [])],
|
|
33
|
-
counts: {
|
|
34
|
-
...apiResults?.facets?.['kind'],
|
|
35
|
-
guide: guideResults.length,
|
|
36
|
-
all: apiResults?.nbHits,
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function clearInput() {
|
|
42
|
-
setSearchQuery('');
|
|
43
|
-
inputRef?.current?.focus();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
|
-
React.useEffect(() => void performSearch(), [searchQuery, filterKind, language]);
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<div className={style.SearchForm}>
|
|
51
|
-
<Docs.Input
|
|
52
|
-
ref={inputRef}
|
|
53
|
-
autoFocus
|
|
54
|
-
onChange={(ev) => setSearchQuery(ev.target.value)}
|
|
55
|
-
left={<SearchIcon size={16} className={style.Icon} />}
|
|
56
|
-
right={
|
|
57
|
-
searchQuery && (
|
|
58
|
-
<XIcon cursor="pointer" onClick={() => clearInput()} size={16} className={style.Icon} />
|
|
59
|
-
)
|
|
60
|
-
}
|
|
61
|
-
value={searchQuery}
|
|
62
|
-
placeholder="Search"
|
|
63
|
-
/>
|
|
64
|
-
|
|
65
|
-
<SearchFilter
|
|
66
|
-
results={results}
|
|
67
|
-
filterKind={filterKind}
|
|
68
|
-
onChange={(filterKind) => setFilterKind(filterKind)}
|
|
69
|
-
/>
|
|
70
|
-
|
|
71
|
-
<Docs.ListView
|
|
72
|
-
items={results?.items ?? []}
|
|
73
|
-
itemDelegate={(item) =>
|
|
74
|
-
'kind' in item ? <SearchResult result={item} /> : <GuideResult result={item} />
|
|
75
|
-
}
|
|
76
|
-
onSelectListItem={(item) =>
|
|
77
|
-
onSelect?.((item as any)['data']?.['url'] ?? (item as any)['stainlessPath'])
|
|
78
|
-
}
|
|
79
|
-
/>
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export type SearchFilterProps = {
|
|
85
|
-
results: ResultData;
|
|
86
|
-
filterKind: QueryKindsType;
|
|
87
|
-
onChange: (filterKind: QueryKindsType) => void;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export function SearchFilter({ results, filterKind, onChange }: SearchFilterProps) {
|
|
91
|
-
const Docs = useComponents();
|
|
92
|
-
const { pageFind } = useSearchContext();
|
|
93
|
-
const toggles = pageFind ? QueryKinds : QueryKinds.slice(0, -1);
|
|
94
|
-
|
|
95
|
-
return (
|
|
96
|
-
<div className={style.SearchFilter}>
|
|
97
|
-
{toggles.map((kind, index) => (
|
|
98
|
-
<Docs.ToggleButton key={index} selected={filterKind === kind} onClick={() => onChange?.(kind)}>
|
|
99
|
-
{React.createElement(QueryKindDisplay[kind].icon, {
|
|
100
|
-
size: 16,
|
|
101
|
-
className: style.Icon,
|
|
102
|
-
})}
|
|
103
|
-
<span className={style.SearchFilterLabel}>{QueryKindDisplay[kind].name}</span>
|
|
104
|
-
<span className={style.SearchFilterCount}>{results?.counts?.[kind] ?? 0}</span>
|
|
105
|
-
</Docs.ToggleButton>
|
|
106
|
-
))}
|
|
107
|
-
</div>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export type SearchModalProps = {
|
|
112
|
-
id?: string;
|
|
113
|
-
open?: boolean;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export function SearchModal({ id, open: isOpen }: SearchModalProps) {
|
|
117
|
-
const [open, setOpen] = React.useState<boolean>(isOpen ?? false);
|
|
118
|
-
|
|
119
|
-
return (
|
|
120
|
-
<div
|
|
121
|
-
id={id}
|
|
122
|
-
onToggle={(ev) => setOpen(ev.newState === 'open')}
|
|
123
|
-
className={style.SearchModal}
|
|
124
|
-
popover="auto"
|
|
125
|
-
data-stldocs-modal-open={open}
|
|
126
|
-
>
|
|
127
|
-
{open && <SearchForm />}
|
|
128
|
-
</div>
|
|
129
|
-
);
|
|
130
|
-
}
|
package/src/search/index.tsx
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './form';
|
package/src/search/indexer.ts
DELETED
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import { generateRoute, Languages, parseStainlessPath, walkTree } from '../routing';
|
|
2
|
-
import * as printer from './printer';
|
|
3
|
-
import type * as SDKJSON from '@stainless/sdk-json';
|
|
4
|
-
import type { IndexEntry } from './types';
|
|
5
|
-
import { renderMarkdown } from '../markdown';
|
|
6
|
-
|
|
7
|
-
// function sanitizeTerraformType(key: string, value: any) {
|
|
8
|
-
// return typeof value === "number" && !Number.isSafeInteger(value)
|
|
9
|
-
// ? value.toString()
|
|
10
|
-
// : value;
|
|
11
|
-
// }
|
|
12
|
-
|
|
13
|
-
export function getResourceNames(resourceIds: string[], topResources?: Record<string, SDKJSON.Resource>) {
|
|
14
|
-
let element: SDKJSON.Resource | undefined = undefined;
|
|
15
|
-
let resources: Record<string, SDKJSON.Resource> | undefined = topResources;
|
|
16
|
-
const resourceName = [];
|
|
17
|
-
for (const resource of resourceIds) {
|
|
18
|
-
element = resources?.[resource];
|
|
19
|
-
if (!element) break;
|
|
20
|
-
resourceName.push(element.title);
|
|
21
|
-
resources = element?.subresources;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return resourceName;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function chunkByLines(content: string, maxSize: number = 60000) {
|
|
28
|
-
if (Buffer.byteLength(content, 'utf8') < maxSize) return [content];
|
|
29
|
-
|
|
30
|
-
const lines = content.split('\n');
|
|
31
|
-
const chunks = [];
|
|
32
|
-
|
|
33
|
-
let currentChunk = [];
|
|
34
|
-
let currentSize = 0;
|
|
35
|
-
|
|
36
|
-
for (const line of lines) {
|
|
37
|
-
const lineSize = Buffer.byteLength(line + '\n', 'utf8');
|
|
38
|
-
if (currentSize + lineSize > maxSize) {
|
|
39
|
-
chunks.push(currentChunk.join('\n'));
|
|
40
|
-
currentChunk = [];
|
|
41
|
-
currentSize = 0;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
currentChunk.push(line);
|
|
45
|
-
currentSize += lineSize;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (currentChunk.length > 0) chunks.push(currentChunk.join('\n'));
|
|
49
|
-
return chunks;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function* generateChatIndex(spec: SDKJSON.Spec) {
|
|
53
|
-
for (const [language, readme] of Object.entries(spec.readme)) {
|
|
54
|
-
const chunks = chunkByLines(readme);
|
|
55
|
-
|
|
56
|
-
for (const chunk of chunks) {
|
|
57
|
-
yield {
|
|
58
|
-
language,
|
|
59
|
-
title: 'Overview',
|
|
60
|
-
content: chunk,
|
|
61
|
-
url: `docs://BASE_PATH/${language}`,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
for (const { data } of walkTree(spec)) {
|
|
67
|
-
if (data.kind !== 'http_method') continue;
|
|
68
|
-
const { title, name, stainlessPath, httpMethod, summary, description } = data;
|
|
69
|
-
const endpoint = data.endpoint.slice(httpMethod.length).trim();
|
|
70
|
-
|
|
71
|
-
for (const language of Languages) {
|
|
72
|
-
const decl = spec.decls[language]?.[stainlessPath];
|
|
73
|
-
if (!decl) continue;
|
|
74
|
-
|
|
75
|
-
const env = {
|
|
76
|
-
spec,
|
|
77
|
-
language,
|
|
78
|
-
options: {
|
|
79
|
-
includeModelProperties: true,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const content = renderMarkdown(env, data);
|
|
84
|
-
const chunks = chunkByLines(content);
|
|
85
|
-
|
|
86
|
-
for (const chunk of chunks) {
|
|
87
|
-
yield {
|
|
88
|
-
language,
|
|
89
|
-
title,
|
|
90
|
-
name,
|
|
91
|
-
endpoint,
|
|
92
|
-
httpMethod,
|
|
93
|
-
summary,
|
|
94
|
-
description,
|
|
95
|
-
stainlessPath,
|
|
96
|
-
qualified: 'qualified' in decl ? decl['qualified'] : undefined,
|
|
97
|
-
ident: 'ident' in decl ? decl['ident'] : undefined,
|
|
98
|
-
content: chunk,
|
|
99
|
-
url: generateRoute('docs://BASE_PATH', language, stainlessPath),
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function* generateIndex(
|
|
107
|
-
spec: SDKJSON.Spec,
|
|
108
|
-
renderMarkdownFn?: (_: string) => string | null,
|
|
109
|
-
includeTypes?: boolean,
|
|
110
|
-
): Generator<IndexEntry> {
|
|
111
|
-
const parentCrumbs: Record<string, string[]> = {};
|
|
112
|
-
for (const { data } of walkTree(spec, true)) {
|
|
113
|
-
const { kind, name, title, stainlessPath } = data;
|
|
114
|
-
const common = { name, title, stainlessPath };
|
|
115
|
-
|
|
116
|
-
const parsedPath = parseStainlessPath(stainlessPath)!;
|
|
117
|
-
const crumbs = getResourceNames(parsedPath.resource!, spec.resources);
|
|
118
|
-
|
|
119
|
-
switch (kind) {
|
|
120
|
-
case 'resource':
|
|
121
|
-
for (const language of Languages) {
|
|
122
|
-
if (!data[language]) continue;
|
|
123
|
-
|
|
124
|
-
parentCrumbs[stainlessPath] = crumbs;
|
|
125
|
-
const { Name, QualifiedName } = data[language]!;
|
|
126
|
-
|
|
127
|
-
yield {
|
|
128
|
-
kind,
|
|
129
|
-
crumbs,
|
|
130
|
-
language,
|
|
131
|
-
Name,
|
|
132
|
-
QualifiedName,
|
|
133
|
-
priority: 0,
|
|
134
|
-
...common,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
break;
|
|
139
|
-
|
|
140
|
-
case 'http_method': {
|
|
141
|
-
const { summary, endpoint, httpMethod } = data;
|
|
142
|
-
for (const language of Languages) {
|
|
143
|
-
const found = spec.decls[language]?.[stainlessPath];
|
|
144
|
-
if (!found) continue;
|
|
145
|
-
|
|
146
|
-
parentCrumbs[stainlessPath] = [...crumbs, title];
|
|
147
|
-
const qualified = 'qualified' in found ? found['qualified'] : undefined;
|
|
148
|
-
const ident = qualified?.split('.')?.at(-1);
|
|
149
|
-
|
|
150
|
-
yield {
|
|
151
|
-
kind,
|
|
152
|
-
crumbs: [...crumbs, title],
|
|
153
|
-
ident,
|
|
154
|
-
qualified,
|
|
155
|
-
language,
|
|
156
|
-
description: data.description
|
|
157
|
-
? (renderMarkdownFn?.(data.description) ?? data.description)
|
|
158
|
-
: undefined,
|
|
159
|
-
endpoint: endpoint.slice(httpMethod.length).trim(),
|
|
160
|
-
httpMethod,
|
|
161
|
-
summary,
|
|
162
|
-
priority: 0,
|
|
163
|
-
...common,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
case 'model':
|
|
171
|
-
for (const language of Languages) {
|
|
172
|
-
if (!spec.decls[language]) continue;
|
|
173
|
-
|
|
174
|
-
parentCrumbs[stainlessPath] = [...crumbs, title];
|
|
175
|
-
const schema = spec.decls[language]?.[`${stainlessPath} > (schema)`];
|
|
176
|
-
const children =
|
|
177
|
-
(schema && 'children' in schema ? schema?.['children'] : undefined)
|
|
178
|
-
?.map((childPath) => {
|
|
179
|
-
const child = spec.decls?.[language]?.[childPath] as any;
|
|
180
|
-
return (
|
|
181
|
-
child?.['ident'] ??
|
|
182
|
-
child?.['name'] ??
|
|
183
|
-
child?.['key'] ??
|
|
184
|
-
child?.['type']?.['literal']?.['value'] ??
|
|
185
|
-
child?.['type']?.['literal'] ??
|
|
186
|
-
child?.['type']?.['value']
|
|
187
|
-
);
|
|
188
|
-
})
|
|
189
|
-
?.filter((child) => child) ?? [];
|
|
190
|
-
|
|
191
|
-
yield {
|
|
192
|
-
kind,
|
|
193
|
-
crumbs: [...crumbs, title],
|
|
194
|
-
children,
|
|
195
|
-
language,
|
|
196
|
-
priority: 2,
|
|
197
|
-
ident: schema && 'ident' in schema ? schema?.['ident'] : undefined,
|
|
198
|
-
...common,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
for (const language of Languages) {
|
|
205
|
-
const decls = spec.decls?.[language];
|
|
206
|
-
if (!decls) continue;
|
|
207
|
-
|
|
208
|
-
for (const decl of Object.values<SDKJSON.LanguageDeclNodes[SDKJSON.SpecLanguage]>(decls)) {
|
|
209
|
-
switch (decl.kind) {
|
|
210
|
-
// case "TerraformDeclAttribute":
|
|
211
|
-
case 'JavaDeclProperty':
|
|
212
|
-
case 'GoDeclProperty':
|
|
213
|
-
case 'PythonDeclProperty':
|
|
214
|
-
case 'RubyDeclProperty':
|
|
215
|
-
case 'HttpDeclProperty':
|
|
216
|
-
case 'TSDeclProperty':
|
|
217
|
-
{
|
|
218
|
-
const parsedPath = parseStainlessPath(decl.stainlessPath)!;
|
|
219
|
-
const type = includeTypes === false ? undefined : printer.typeName(language, decl.type);
|
|
220
|
-
const name: string = (decl as any)['ident'] ?? (decl as any)['name'] ?? (decl as any)['key'];
|
|
221
|
-
|
|
222
|
-
const parent = parentCrumbs[parsedPath.routable!];
|
|
223
|
-
// Filter out properties of non-routable response types
|
|
224
|
-
if (parent === undefined) continue;
|
|
225
|
-
|
|
226
|
-
const matches = decl.stainlessPath.matchAll(/\((property|params|param)\) ([^\s]+)/g);
|
|
227
|
-
|
|
228
|
-
const props = Array.from(matches)
|
|
229
|
-
.map((p) => p[2])
|
|
230
|
-
.filter((p) => p !== undefined);
|
|
231
|
-
|
|
232
|
-
yield {
|
|
233
|
-
kind: 'property',
|
|
234
|
-
name,
|
|
235
|
-
stainlessPath: decl.stainlessPath,
|
|
236
|
-
crumbs: [...parent, ...props],
|
|
237
|
-
docstring: decl.docstring ? (renderMarkdownFn?.(decl.docstring) ?? decl.docstring) : undefined,
|
|
238
|
-
type,
|
|
239
|
-
language,
|
|
240
|
-
priority: 3,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|