@stainless-api/docs-ui 0.1.0-beta.5 → 0.1.0-beta.50
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-C6pTTw_o.d.ts +20 -0
- package/dist/breadcrumbs-DEyC9k79.d.ts +20 -0
- package/dist/breadcrumbs-nSFZO5Gf.js +63 -0
- package/dist/chunk-DRcLgZ1e.js +18 -0
- package/dist/component-DRO8kQSp.js +23 -0
- package/dist/component-generics-B6Fn47Mz.js +45 -0
- package/dist/component-generics-D_yxZT6v.d.ts +30 -0
- package/dist/component-generics-DxN-MaP2.d.ts +30 -0
- package/dist/components/MaskedInput.d.ts +14 -0
- package/dist/components/MaskedInput.js +76 -0
- package/dist/components/breadcrumbs.d.ts +2 -0
- package/dist/components/breadcrumbs.js +9 -0
- package/dist/components/icons.d.ts +55 -0
- package/dist/components/icons.js +3 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.js +18 -0
- package/dist/components/method.d.ts +2 -0
- package/dist/components/method.js +10 -0
- package/dist/components/overview.d.ts +2 -0
- package/dist/components/overview.js +11 -0
- package/dist/components/primitives.d.ts +2 -0
- package/dist/components/primitives.js +8 -0
- package/dist/components/properties.d.ts +2 -0
- package/dist/components/properties.js +9 -0
- package/dist/components/sdk.d.ts +2 -0
- package/dist/components/sdk.js +10 -0
- package/dist/components/sidebar.d.ts +2 -0
- package/dist/components/sidebar.js +11 -0
- package/dist/components/snippets.d.ts +3 -0
- package/dist/components/snippets.js +9 -0
- package/dist/components-D7M-BwNI.js +71 -0
- package/dist/contexts/component-generics.d.ts +2 -0
- package/dist/contexts/component-generics.js +3 -0
- package/dist/contexts/component-types.d.ts +16 -0
- package/dist/contexts/component-types.js +0 -0
- package/dist/contexts/component.d.ts +29 -0
- package/dist/contexts/component.js +27 -0
- package/dist/contexts/docs.d.ts +2 -0
- package/dist/contexts/docs.js +3 -0
- package/dist/contexts/index.d.ts +16 -0
- package/dist/contexts/index.js +7 -0
- package/dist/contexts/markdown.d.ts +2 -0
- package/dist/contexts/markdown.js +4 -0
- package/dist/contexts/navigation.d.ts +2 -0
- package/dist/contexts/navigation.js +3 -0
- package/dist/contexts/use-components.d.ts +14 -0
- package/dist/contexts/use-components.js +4 -0
- package/dist/contexts-p3rRZDlM.js +39 -0
- package/dist/csharp-CDSxfCZE.js +283 -0
- package/dist/docs-CXqi26jB.js +54 -0
- package/dist/docs-dNFWvk6w.d.ts +47 -0
- package/dist/docs-mMDqYdkf.d.ts +47 -0
- package/dist/go-1c3S5ETL.js +303 -0
- package/dist/http-2QNWXH9t.js +330 -0
- package/dist/icons-Ckod9aod.js +869 -0
- package/dist/index-0imEqwWy.d.ts +15 -0
- package/dist/index-BJR7MT73.d.ts +13 -0
- package/dist/index-DGWbX2x8.d.ts +13 -0
- package/dist/index-DJO7hQAU.d.ts +274 -0
- package/dist/index-DMFZJxNb.d.ts +15 -0
- package/dist/index-tw6MEWKp.d.ts +274 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +29 -7542
- package/dist/java-BbjF_oUI.js +403 -0
- package/dist/languages/csharp.d.ts +11 -0
- package/dist/languages/csharp.js +9 -0
- package/dist/languages/go.d.ts +11 -0
- package/dist/languages/go.js +9 -0
- package/dist/languages/http.d.ts +11 -0
- package/dist/languages/http.js +19 -0
- package/dist/languages/index.d.ts +11 -0
- package/dist/languages/index.js +26 -0
- package/dist/languages/java.d.ts +11 -0
- package/dist/languages/java.js +9 -0
- package/dist/languages/python.d.ts +11 -0
- package/dist/languages/python.js +9 -0
- package/dist/languages/ruby.d.ts +11 -0
- package/dist/languages/ruby.js +9 -0
- package/dist/languages/typescript.d.ts +11 -0
- package/dist/languages/typescript.js +9 -0
- package/dist/languages-BCYZjzuS.js +26 -0
- package/dist/markdown/index.d.ts +12 -0
- package/dist/markdown/index.js +104 -0
- package/dist/markdown/md.d.ts +15 -0
- package/dist/markdown/md.js +3 -0
- package/dist/markdown/printer.d.ts +2 -0
- package/dist/markdown/printer.js +28 -0
- package/dist/markdown/utils.d.ts +3 -0
- package/dist/markdown/utils.js +3 -0
- package/dist/markdown-CxdeWgjV.js +48 -0
- package/dist/markdown-DeSSIANr.d.ts +22 -0
- package/dist/markdown-OuUthjwK.d.ts +22 -0
- package/dist/md-oM2tUaCA.js +41 -0
- package/dist/method-BiXJltKa.d.ts +71 -0
- package/dist/method-CE08mUME.js +115 -0
- package/dist/method-DQ3lDoTM.d.ts +71 -0
- package/dist/navigation-BX8nuda9.d.ts +29 -0
- package/dist/navigation-C5TN0SgC.js +24 -0
- package/dist/navigation-CWDfzVoR.d.ts +29 -0
- package/dist/overview-B43BuZbK.d.ts +39 -0
- package/dist/overview-MTDgZ7Xr.d.ts +39 -0
- package/dist/overview-S2hUqPXA.js +139 -0
- package/dist/primitives-1lB1L0is.d.ts +97 -0
- package/dist/primitives-BIWfwN5L.js +258 -0
- package/dist/primitives-DLv4uMoz.d.ts +97 -0
- package/dist/printer-DBw4S_Jn.d.ts +13 -0
- package/dist/printer-bNxiG6UB.js +74 -0
- package/dist/properties-B-giMW4K.d.ts +54 -0
- package/dist/properties-BvP2WAjP.d.ts +54 -0
- package/dist/properties-jlGW3USi.js +131 -0
- package/dist/python-USOwFDv_.js +279 -0
- package/dist/routing-CMqh1cTZ.d.ts +54 -0
- package/dist/routing-Wbb7YECB.js +194 -0
- package/dist/routing.d.ts +2 -0
- package/dist/routing.js +3 -180
- package/dist/ruby-CSvGbSLe.js +387 -0
- package/dist/sdk-BwXeHS3_.d.ts +118 -0
- package/dist/sdk-CSCbbn3O.js +336 -0
- package/dist/sdk-DXdNszcC.d.ts +118 -0
- package/dist/sidebar-CWyvCrJ0.js +81 -0
- package/dist/sidebar-DGGt5gik.d.ts +36 -0
- package/dist/sidebar-DfS6SWQz.d.ts +36 -0
- package/dist/snippets-BQLXEIf6.js +161 -0
- package/dist/snippets-BRs_4F1I.d.ts +51 -0
- package/dist/snippets-DxSMK50g.d.ts +51 -0
- package/dist/spec.d.ts +65 -0
- package/dist/spec.js +167 -0
- package/dist/style-D7RO5ymE.d.ts +168 -0
- package/dist/style-gnVEeXFj.js +169 -0
- package/dist/style.d.ts +2 -0
- package/dist/style.js +3 -0
- package/dist/styles/main.css +727 -754
- package/dist/styles/main.js +0 -0
- package/dist/styles/primitives.css +317 -461
- package/dist/styles/primitives.js +0 -0
- package/dist/styles/resets.css +32 -41
- package/dist/styles/resets.js +0 -0
- package/dist/styles/search.css +175 -274
- package/dist/styles/search.js +0 -0
- package/dist/styles/sidebar.css +59 -60
- package/dist/styles/sidebar.js +0 -0
- package/dist/styles/variables.css +26 -89
- package/dist/styles/variables.js +0 -0
- package/dist/styles.css +2910 -0
- package/dist/styles.mjs +1 -0
- package/dist/typescript-DXG9psK3.js +449 -0
- package/dist/use-components-RWQbviGq.js +7 -0
- package/dist/utils-BaLi5Bed.d.ts +21 -0
- package/dist/utils-CqnL9Fc3.js +31 -0
- package/dist/utils-D_1AWSRX.js +32 -0
- package/dist/utils-_AEBNJhG.d.ts +21 -0
- package/dist/utils-d8paVwKN.d.ts +14 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +3 -0
- package/package.json +73 -21
- package/dist/mcp.js +0 -16003
- package/dist/styles/snippets.css +0 -132
- package/src/components/breadcrumbs.tsx +0 -94
- package/src/components/chat.tsx +0 -154
- package/src/components/dropdown.tsx +0 -91
- package/src/components/icons.tsx +0 -584
- package/src/components/index.ts +0 -9
- package/src/components/method.tsx +0 -144
- package/src/components/overview.tsx +0 -159
- package/src/components/primitives.tsx +0 -284
- package/src/components/properties.tsx +0 -130
- package/src/components/scripts/dropdown.ts +0 -78
- package/src/components/sdk.tsx +0 -402
- package/src/components/sidebar.tsx +0 -99
- package/src/components/snippets.tsx +0 -179
- package/src/contexts/component-generics.tsx +0 -48
- package/src/contexts/component-types.tsx +0 -5
- package/src/contexts/component.tsx +0 -32
- package/src/contexts/docs.tsx +0 -75
- package/src/contexts/index.tsx +0 -17
- package/src/contexts/markdown.tsx +0 -43
- package/src/contexts/navigation.tsx +0 -44
- package/src/contexts/search.tsx +0 -28
- package/src/contexts/use-components.tsx +0 -4
- package/src/index.ts +0 -6
- package/src/languages/go.tsx +0 -281
- package/src/languages/http.tsx +0 -321
- package/src/languages/index.ts +0 -26
- package/src/languages/java.tsx +0 -358
- package/src/languages/python.tsx +0 -255
- package/src/languages/ruby.tsx +0 -320
- package/src/languages/typescript.tsx +0 -393
- package/src/markdown/index.ts +0 -107
- package/src/markdown/md.ts +0 -45
- package/src/markdown/utils.ts +0 -49
- package/src/routing.ts +0 -238
- package/src/search/form.tsx +0 -127
- package/src/search/index.tsx +0 -1
- package/src/search/indexer.ts +0 -246
- package/src/search/mcp.ts +0 -61
- 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 -30
- package/src/search/results.tsx +0 -181
- package/src/search/state.ts +0 -64
- package/src/search/types.ts +0 -116
- package/src/style.ts +0 -197
- package/src/styles/main.css +0 -993
- package/src/styles/primitives.css +0 -573
- package/src/styles/resets.css +0 -47
- package/src/styles/search.css +0 -342
- package/src/styles/sidebar.css +0 -87
- package/src/styles/snippets.css +0 -132
- package/src/styles/variables.css +0 -90
- package/src/utils.ts +0 -41
package/src/routing.ts
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import type * as SDKJSON from '~/lib/json-spec-v2/types';
|
|
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) return null;
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
resource: match.groups.resource.split('.'),
|
|
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) {
|
|
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) {
|
|
221
|
-
while (el) {
|
|
222
|
-
if (el.tagName === 'DETAILS') 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,127 +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
|
-
React.useEffect(() => void performSearch(), [searchQuery, filterKind, language]);
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<div className={style.SearchForm}>
|
|
50
|
-
<Docs.Input
|
|
51
|
-
ref={inputRef}
|
|
52
|
-
autoFocus
|
|
53
|
-
onChange={(ev) => setSearchQuery(ev.target.value)}
|
|
54
|
-
left={<SearchIcon size={16} className={style.Icon} />}
|
|
55
|
-
right={
|
|
56
|
-
searchQuery && (
|
|
57
|
-
<XIcon cursor="pointer" onClick={() => clearInput()} size={16} className={style.Icon} />
|
|
58
|
-
)
|
|
59
|
-
}
|
|
60
|
-
value={searchQuery}
|
|
61
|
-
placeholder="Search"
|
|
62
|
-
/>
|
|
63
|
-
|
|
64
|
-
<SearchFilter
|
|
65
|
-
results={results}
|
|
66
|
-
filterKind={filterKind}
|
|
67
|
-
onChange={(filterKind) => setFilterKind(filterKind)}
|
|
68
|
-
/>
|
|
69
|
-
|
|
70
|
-
<Docs.ListView
|
|
71
|
-
items={results?.items ?? []}
|
|
72
|
-
itemDelegate={(item) =>
|
|
73
|
-
'kind' in item ? <SearchResult result={item} /> : <GuideResult result={item} />
|
|
74
|
-
}
|
|
75
|
-
onSelectListItem={(item) => onSelect?.(item['data']?.['url'] ?? item['stainlessPath'])}
|
|
76
|
-
/>
|
|
77
|
-
</div>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export type SearchFilterProps = {
|
|
82
|
-
results: ResultData;
|
|
83
|
-
filterKind: QueryKindsType;
|
|
84
|
-
onChange: (filterKind?: QueryKindsType) => void;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export function SearchFilter({ results, filterKind, onChange }: SearchFilterProps) {
|
|
88
|
-
const Docs = useComponents();
|
|
89
|
-
const { pageFind } = useSearchContext();
|
|
90
|
-
const toggles = pageFind ? QueryKinds : QueryKinds.slice(0, -1);
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<div className={style.SearchFilter}>
|
|
94
|
-
{toggles.map((kind, index) => (
|
|
95
|
-
<Docs.ToggleButton key={index} selected={filterKind === kind} onClick={() => onChange?.(kind)}>
|
|
96
|
-
{React.createElement(QueryKindDisplay[kind].icon, {
|
|
97
|
-
size: 16,
|
|
98
|
-
className: style.Icon,
|
|
99
|
-
})}
|
|
100
|
-
{QueryKindDisplay[kind].name}
|
|
101
|
-
<span className={style.SearchFilterCount}>{results?.counts?.[kind] ?? 0}</span>
|
|
102
|
-
</Docs.ToggleButton>
|
|
103
|
-
))}
|
|
104
|
-
</div>
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export type SearchModalProps = {
|
|
109
|
-
id?: string;
|
|
110
|
-
open?: boolean;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export function SearchModal({ id, open: isOpen }: SearchModalProps) {
|
|
114
|
-
const [open, setOpen] = React.useState<boolean>(isOpen);
|
|
115
|
-
|
|
116
|
-
return (
|
|
117
|
-
<div
|
|
118
|
-
id={id}
|
|
119
|
-
onToggle={(ev) => setOpen(ev.newState === 'open')}
|
|
120
|
-
className={style.SearchModal}
|
|
121
|
-
popover="auto"
|
|
122
|
-
data-stldocs-modal-open={open}
|
|
123
|
-
>
|
|
124
|
-
{open && <SearchForm />}
|
|
125
|
-
</div>
|
|
126
|
-
);
|
|
127
|
-
}
|
package/src/search/index.tsx
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './form';
|
package/src/search/indexer.ts
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import { generateRoute, Languages, parseStainlessPath, walkTree } from '../routing';
|
|
2
|
-
import * as printer from './printer';
|
|
3
|
-
import type * as SDKJSON from '~/lib/json-spec-v2/types';
|
|
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: decl['qualified'],
|
|
97
|
-
ident: decl['ident'],
|
|
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 = found['qualified'];
|
|
148
|
-
const ident = qualified?.split('.')?.at(-1);
|
|
149
|
-
|
|
150
|
-
yield {
|
|
151
|
-
kind,
|
|
152
|
-
crumbs: [...crumbs, title],
|
|
153
|
-
ident,
|
|
154
|
-
qualified,
|
|
155
|
-
language,
|
|
156
|
-
description: renderMarkdownFn?.(data.description) ?? data.description,
|
|
157
|
-
endpoint: endpoint.slice(httpMethod.length).trim(),
|
|
158
|
-
httpMethod,
|
|
159
|
-
summary,
|
|
160
|
-
priority: 0,
|
|
161
|
-
...common,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
case 'model':
|
|
169
|
-
for (const language of Languages) {
|
|
170
|
-
if (!spec.decls[language]) continue;
|
|
171
|
-
|
|
172
|
-
parentCrumbs[stainlessPath] = [...crumbs, title];
|
|
173
|
-
const schema = spec.decls[language]?.[`${stainlessPath} > (schema)`];
|
|
174
|
-
const children =
|
|
175
|
-
schema?.['children']
|
|
176
|
-
?.map((childPath) => {
|
|
177
|
-
const child = spec.decls?.[language]?.[childPath];
|
|
178
|
-
return (
|
|
179
|
-
child?.['ident'] ??
|
|
180
|
-
child?.['name'] ??
|
|
181
|
-
child?.['key'] ??
|
|
182
|
-
child?.['type']?.['literal']?.['value'] ??
|
|
183
|
-
child?.['type']?.['literal'] ??
|
|
184
|
-
child?.['type']?.['value']
|
|
185
|
-
);
|
|
186
|
-
})
|
|
187
|
-
?.filter((child) => child) ?? [];
|
|
188
|
-
|
|
189
|
-
yield {
|
|
190
|
-
kind,
|
|
191
|
-
crumbs: [...crumbs, title],
|
|
192
|
-
children,
|
|
193
|
-
language,
|
|
194
|
-
priority: 2,
|
|
195
|
-
ident: schema?.['ident'],
|
|
196
|
-
...common,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
for (const language of Languages) {
|
|
203
|
-
const decls = spec.decls?.[language];
|
|
204
|
-
if (!decls) continue;
|
|
205
|
-
|
|
206
|
-
for (const decl of Object.values<SDKJSON.LanguageDeclNodes[SDKJSON.SpecLanguage]>(decls)) {
|
|
207
|
-
switch (decl.kind) {
|
|
208
|
-
// case "TerraformDeclAttribute":
|
|
209
|
-
case 'JavaDeclProperty':
|
|
210
|
-
case 'GoDeclProperty':
|
|
211
|
-
case 'PythonDeclProperty':
|
|
212
|
-
case 'RubyDeclProperty':
|
|
213
|
-
case 'HttpDeclProperty':
|
|
214
|
-
case 'TSDeclProperty':
|
|
215
|
-
{
|
|
216
|
-
const parsedPath = parseStainlessPath(decl.stainlessPath);
|
|
217
|
-
const type = includeTypes === false ? undefined : printer.typeName(language, decl.type);
|
|
218
|
-
const name = decl['ident'] ?? decl['name'] ?? decl['key'];
|
|
219
|
-
|
|
220
|
-
const parent = parentCrumbs[parsedPath.routable];
|
|
221
|
-
// Filter out properties of non-routable response types
|
|
222
|
-
if (parent === undefined) continue;
|
|
223
|
-
|
|
224
|
-
const matches = decl.stainlessPath.matchAll(/\((property|params|param)\) ([^\s]+)/g);
|
|
225
|
-
|
|
226
|
-
const props = Array.from(matches)
|
|
227
|
-
.map((p) => p[2])
|
|
228
|
-
.filter((p) => p !== undefined);
|
|
229
|
-
|
|
230
|
-
yield {
|
|
231
|
-
kind: 'property',
|
|
232
|
-
name,
|
|
233
|
-
stainlessPath: decl.stainlessPath,
|
|
234
|
-
crumbs: [...parent, ...props],
|
|
235
|
-
docstring: renderMarkdownFn?.(decl.docstring) ?? decl.docstring,
|
|
236
|
-
type,
|
|
237
|
-
language,
|
|
238
|
-
priority: 3,
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
break;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
package/src/search/mcp.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { renderMarkdown } from '../markdown';
|
|
2
|
-
import { DocsLanguage, parseStainlessPath } from '../routing';
|
|
3
|
-
import { getResourceFromSpec } from '../utils';
|
|
4
|
-
import { buildIndex, search } from './providers/fuse';
|
|
5
|
-
import type { IndexEntry } from './types';
|
|
6
|
-
import type * as SDKJSON from '~/lib/json-spec-v2/types';
|
|
7
|
-
|
|
8
|
-
export function consolidate(results: IndexEntry[]) {
|
|
9
|
-
const resources = new Set<string>();
|
|
10
|
-
const methods = new Set<string>();
|
|
11
|
-
|
|
12
|
-
for (const entry of results) {
|
|
13
|
-
const parsed = parseStainlessPath(entry.stainlessPath);
|
|
14
|
-
if (parsed.method) methods.add(parsed.routable);
|
|
15
|
-
else resources.add(parsed.routable);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const filtered = Array.from(methods).filter((path) => !resources.has(path.split(' >').at(0)));
|
|
19
|
-
return [...resources, ...filtered];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function render(
|
|
23
|
-
spec: SDKJSON.Spec,
|
|
24
|
-
language: DocsLanguage,
|
|
25
|
-
items: IndexEntry[],
|
|
26
|
-
includeModelProperties: boolean,
|
|
27
|
-
) {
|
|
28
|
-
const env = {
|
|
29
|
-
spec,
|
|
30
|
-
language,
|
|
31
|
-
options: {
|
|
32
|
-
renderNestedResources: false,
|
|
33
|
-
includeModelProperties,
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const paths = consolidate(items);
|
|
38
|
-
const output = paths.map((entry) => {
|
|
39
|
-
const parsed = parseStainlessPath(entry);
|
|
40
|
-
const resource = getResourceFromSpec(parsed.resource, spec);
|
|
41
|
-
const target = parsed.method ? resource.methods[parsed.method] : resource;
|
|
42
|
-
const content = renderMarkdown(env, target);
|
|
43
|
-
return [entry, content];
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return Object.fromEntries(output);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function searchAndRender(
|
|
50
|
-
spec: SDKJSON.Spec,
|
|
51
|
-
language: DocsLanguage,
|
|
52
|
-
query: string,
|
|
53
|
-
limit?: number,
|
|
54
|
-
includeModelProperties: boolean = false,
|
|
55
|
-
) {
|
|
56
|
-
const idx = buildIndex(spec, language);
|
|
57
|
-
const results = search(idx, query, limit).map(({ item }) => item);
|
|
58
|
-
return render(spec, language, results, includeModelProperties);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export { buildIndex };
|