@stainless-api/docs-search 0.1.0-beta.1
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/algolia-BOY-OcxU.js +83 -0
- package/dist/context-CBTWkDal.js +32 -0
- package/dist/context.d.ts +21 -0
- package/dist/context.js +5 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +328 -0
- package/dist/indexer-DBU0POrK.js +181 -0
- package/dist/mcp.d.ts +13 -0
- package/dist/mcp.js +36 -0
- package/dist/pagefind-Dcn-gjDe.js +15 -0
- package/dist/providers/algolia.d.ts +24 -0
- package/dist/providers/algolia.js +4 -0
- package/dist/providers/fuse.d.ts +18 -0
- package/dist/providers/fuse.js +19 -0
- package/dist/providers/pagefind.d.ts +6 -0
- package/dist/providers/pagefind.js +3 -0
- package/dist/providers/walker.d.ts +9 -0
- package/dist/providers/walker.js +23 -0
- package/dist/types-BhJLoaNF.js +35 -0
- package/dist/types-Gg968wOz.d.ts +91 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +3 -0
- package/package.json +59 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { n as generateIndex, t as generateChatIndex } from "./indexer-DBU0POrK.js";
|
|
2
|
+
import { i as SearchableAttributesProse, n as SearchableAttributes, r as SearchableAttributesChat } from "./types-BhJLoaNF.js";
|
|
3
|
+
import { searchClient } from "@algolia/client-search";
|
|
4
|
+
|
|
5
|
+
//#region src/providers/algolia.ts
|
|
6
|
+
async function buildIndex(appId, indexName, writeKey, spec, renderMarkdown) {
|
|
7
|
+
if (!appId || !indexName || !writeKey) return;
|
|
8
|
+
const objects = Array.from(generateIndex(spec, renderMarkdown));
|
|
9
|
+
const client = searchClient(appId, writeKey);
|
|
10
|
+
await client.setSettings({
|
|
11
|
+
indexName,
|
|
12
|
+
indexSettings: {
|
|
13
|
+
highlightPreTag: "<mark>",
|
|
14
|
+
highlightPostTag: "</mark>",
|
|
15
|
+
customRanking: ["asc(priority)"],
|
|
16
|
+
attributesForFaceting: ["language", "kind"],
|
|
17
|
+
searchableAttributes: [...SearchableAttributes]
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
await client.replaceAllObjects({
|
|
21
|
+
indexName,
|
|
22
|
+
objects
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
async function buildChatIndex(appId, indexName, writeKey, spec) {
|
|
26
|
+
if (!appId || !indexName || !writeKey) return;
|
|
27
|
+
const objects = Array.from(generateChatIndex(spec));
|
|
28
|
+
const client = searchClient(appId, writeKey);
|
|
29
|
+
await client.setSettings({
|
|
30
|
+
indexName,
|
|
31
|
+
indexSettings: {
|
|
32
|
+
attributesForFaceting: ["language"],
|
|
33
|
+
attributeForDistinct: "stainlessPath",
|
|
34
|
+
searchableAttributes: SearchableAttributesChat
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
await client.replaceAllObjects({
|
|
38
|
+
indexName,
|
|
39
|
+
objects
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async function buildProseIndex(appId, indexName, writeKey, objects) {
|
|
43
|
+
if (!appId || !indexName || !writeKey) return;
|
|
44
|
+
const client = searchClient(appId, writeKey);
|
|
45
|
+
await client.setSettings({
|
|
46
|
+
indexName,
|
|
47
|
+
indexSettings: { searchableAttributes: SearchableAttributesProse }
|
|
48
|
+
});
|
|
49
|
+
await client.replaceAllObjects({
|
|
50
|
+
indexName,
|
|
51
|
+
objects
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async function search({ settings: { appId, indexName, searchKey }, params: { query, language, kind } }) {
|
|
55
|
+
const client = searchClient(appId, searchKey);
|
|
56
|
+
const filters = language ? `language:${language}` : void 0;
|
|
57
|
+
const facetFilters = kind ? [`kind:${kind}`] : void 0;
|
|
58
|
+
const { results } = await client.search({ requests: [{
|
|
59
|
+
query,
|
|
60
|
+
indexName,
|
|
61
|
+
filters,
|
|
62
|
+
hitsPerPage: 5,
|
|
63
|
+
facets: ["kind"]
|
|
64
|
+
}, {
|
|
65
|
+
query,
|
|
66
|
+
indexName,
|
|
67
|
+
filters,
|
|
68
|
+
facetFilters,
|
|
69
|
+
facets: ["kind"],
|
|
70
|
+
hitsPerPage: 50
|
|
71
|
+
}] });
|
|
72
|
+
if ("hits" in results[0] && "hits" in results[1]) {
|
|
73
|
+
const [{ nbHits, facets }, { hits }] = results;
|
|
74
|
+
return {
|
|
75
|
+
hits,
|
|
76
|
+
nbHits: nbHits ?? 0,
|
|
77
|
+
facets
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
export { search as i, buildIndex as n, buildProseIndex as r, buildChatIndex as t };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { i as search } from "./algolia-BOY-OcxU.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/context.tsx
|
|
6
|
+
function createStrictContext(displayName) {
|
|
7
|
+
const Context = React.createContext(null);
|
|
8
|
+
Context.displayName = displayName;
|
|
9
|
+
function useStrictContext() {
|
|
10
|
+
const context = React.useContext(Context);
|
|
11
|
+
if (context === null) throw new Error(`use${displayName} must be used within a ${displayName}Provider`);
|
|
12
|
+
return context;
|
|
13
|
+
}
|
|
14
|
+
return [Context.Provider, useStrictContext];
|
|
15
|
+
}
|
|
16
|
+
const [Provider, useSearchContext] = createStrictContext("SearchContext");
|
|
17
|
+
function useSearch() {
|
|
18
|
+
const { settings } = useSearchContext();
|
|
19
|
+
return (params) => search({
|
|
20
|
+
settings,
|
|
21
|
+
params
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function SearchProvider({ children, ...props }) {
|
|
25
|
+
return /* @__PURE__ */ jsx(Provider, {
|
|
26
|
+
value: props,
|
|
27
|
+
children
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { useSearch as n, useSearchContext as r, SearchProvider as t };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { f as ResultType, g as SearchSettings, h as SearchParams } from "./types-Gg968wOz.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/context.d.ts
|
|
6
|
+
type SearchContextType = {
|
|
7
|
+
settings: SearchSettings;
|
|
8
|
+
onSelect?: (stainlessPath: string) => void;
|
|
9
|
+
pageFind?: string;
|
|
10
|
+
};
|
|
11
|
+
declare const useSearchContext: () => SearchContextType;
|
|
12
|
+
declare function useSearch(): (params: SearchParams) => Promise<ResultType | undefined>;
|
|
13
|
+
type SearchProviderProps = SearchContextType & {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
};
|
|
16
|
+
declare function SearchProvider({
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}: SearchProviderProps): react_jsx_runtime0.JSX.Element;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { SearchContextType, SearchProvider, SearchProviderProps, useSearch, useSearchContext };
|
package/dist/context.js
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { l as QueryKindsType, u as ResultData } from "./types-Gg968wOz.js";
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/form.d.ts
|
|
5
|
+
declare function SearchForm(): react_jsx_runtime0.JSX.Element;
|
|
6
|
+
type SearchFilterProps = {
|
|
7
|
+
results: ResultData;
|
|
8
|
+
filterKind: QueryKindsType;
|
|
9
|
+
onChange: (filterKind: QueryKindsType) => void;
|
|
10
|
+
};
|
|
11
|
+
declare function SearchFilter({
|
|
12
|
+
results,
|
|
13
|
+
filterKind,
|
|
14
|
+
onChange
|
|
15
|
+
}: SearchFilterProps): react_jsx_runtime0.JSX.Element;
|
|
16
|
+
type SearchModalProps = {
|
|
17
|
+
id?: string;
|
|
18
|
+
open?: boolean;
|
|
19
|
+
};
|
|
20
|
+
declare function SearchModal({
|
|
21
|
+
id,
|
|
22
|
+
open: isOpen
|
|
23
|
+
}: SearchModalProps): react_jsx_runtime0.JSX.Element;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { SearchFilter, SearchFilterProps, SearchForm, SearchModal, SearchModalProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import "./indexer-DBU0POrK.js";
|
|
2
|
+
import { t as QueryKinds } from "./types-BhJLoaNF.js";
|
|
3
|
+
import "./algolia-BOY-OcxU.js";
|
|
4
|
+
import { n as useSearch, r as useSearchContext } from "./context-CBTWkDal.js";
|
|
5
|
+
import { t as guideSearch } from "./pagefind-Dcn-gjDe.js";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { BookOpenText, Box, Code, Folder, Search, Wrench, X } from "lucide-react";
|
|
9
|
+
import { useLanguage } from "@stainless-api/docs-ui/contexts";
|
|
10
|
+
import { useComponents } from "@stainless-api/docs-ui/contexts/use-components";
|
|
11
|
+
import style from "@stainless-api/docs-ui/style";
|
|
12
|
+
|
|
13
|
+
//#region src/results.tsx
|
|
14
|
+
const QueryKindDisplay = {
|
|
15
|
+
all: {
|
|
16
|
+
name: "Results",
|
|
17
|
+
icon: Search
|
|
18
|
+
},
|
|
19
|
+
resource: {
|
|
20
|
+
name: "Resources",
|
|
21
|
+
icon: Folder
|
|
22
|
+
},
|
|
23
|
+
http_method: {
|
|
24
|
+
name: "Methods",
|
|
25
|
+
icon: Box
|
|
26
|
+
},
|
|
27
|
+
model: {
|
|
28
|
+
name: "Types",
|
|
29
|
+
icon: Code
|
|
30
|
+
},
|
|
31
|
+
property: {
|
|
32
|
+
name: "Properties",
|
|
33
|
+
icon: Wrench
|
|
34
|
+
},
|
|
35
|
+
guide: {
|
|
36
|
+
name: "Guide",
|
|
37
|
+
icon: BookOpenText
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
function Highlight({ result, name }) {
|
|
41
|
+
const value = result._highlightResult[name]?.value;
|
|
42
|
+
if (value) return /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: value } });
|
|
43
|
+
}
|
|
44
|
+
function SearchResultBreadcrumb({ result }) {
|
|
45
|
+
const Docs = useComponents();
|
|
46
|
+
const Icon = QueryKindDisplay[result.kind].icon;
|
|
47
|
+
const items = result.crumbs?.map((crumb) => /* @__PURE__ */ jsx("span", {
|
|
48
|
+
className: style.SearchBreadcrumbItem,
|
|
49
|
+
children: crumb
|
|
50
|
+
}, crumb));
|
|
51
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
52
|
+
className: style.SearchBreadcrumb,
|
|
53
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
54
|
+
className: style.Icon,
|
|
55
|
+
size: 14
|
|
56
|
+
}), Array.isArray(result.crumbs) && /* @__PURE__ */ jsx(Docs.Join, {
|
|
57
|
+
items,
|
|
58
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
59
|
+
className: style.SearchBreadcrumbDivider,
|
|
60
|
+
children: "›"
|
|
61
|
+
})
|
|
62
|
+
})]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function SearchResult({ result }) {
|
|
66
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
67
|
+
className: style.SearchResult,
|
|
68
|
+
"data-stldocs-search-result": result.kind,
|
|
69
|
+
children: [/* @__PURE__ */ jsx(SearchResultBreadcrumb, { result }), /* @__PURE__ */ jsx(SearchResultContent, { result })]
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function GuideResult({ result }) {
|
|
73
|
+
const Docs = useComponents();
|
|
74
|
+
const Icon = QueryKindDisplay["guide"].icon;
|
|
75
|
+
const path = result.data.url.slice(1, -1).split("/").map((crumb) => /* @__PURE__ */ jsx("span", {
|
|
76
|
+
className: style.SearchBreadcrumbItem,
|
|
77
|
+
children: crumb
|
|
78
|
+
}, crumb));
|
|
79
|
+
const crumbs = path.length > 1 ? path : [/* @__PURE__ */ jsx("span", {
|
|
80
|
+
className: style.SearchBreadcrumbItem,
|
|
81
|
+
children: "Overview"
|
|
82
|
+
}, "overview")];
|
|
83
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
84
|
+
className: style.SearchResult,
|
|
85
|
+
"data-stldocs-search-result": "guide",
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ jsxs("div", {
|
|
88
|
+
className: style.SearchBreadcrumb,
|
|
89
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
90
|
+
className: style.Icon,
|
|
91
|
+
size: 14
|
|
92
|
+
}), /* @__PURE__ */ jsx(Docs.Join, {
|
|
93
|
+
items: crumbs,
|
|
94
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
95
|
+
className: style.SearchBreadcrumbDivider,
|
|
96
|
+
children: "›"
|
|
97
|
+
})
|
|
98
|
+
})]
|
|
99
|
+
}),
|
|
100
|
+
/* @__PURE__ */ jsx("h3", {
|
|
101
|
+
className: style.SearchResultGuideTitle,
|
|
102
|
+
children: result.data.meta.title
|
|
103
|
+
}),
|
|
104
|
+
/* @__PURE__ */ jsx("div", {
|
|
105
|
+
className: style.SearchResultGuideExcerpt,
|
|
106
|
+
dangerouslySetInnerHTML: { __html: result.data.excerpt }
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function SearchResultContent({ result }) {
|
|
112
|
+
const Docs = useComponents();
|
|
113
|
+
const language = useLanguage();
|
|
114
|
+
switch (result.kind) {
|
|
115
|
+
case "http_method": return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Docs.MethodHeader, {
|
|
116
|
+
level: "h5",
|
|
117
|
+
title: /* @__PURE__ */ jsx(Highlight, {
|
|
118
|
+
result,
|
|
119
|
+
name: result.summary ? "summary" : "title"
|
|
120
|
+
}),
|
|
121
|
+
signature: result["qualified"] && /* @__PURE__ */ jsx(Highlight, {
|
|
122
|
+
result,
|
|
123
|
+
name: "qualified"
|
|
124
|
+
}),
|
|
125
|
+
children: /* @__PURE__ */ jsx(Docs.MethodRoute, {
|
|
126
|
+
httpMethod: result.httpMethod,
|
|
127
|
+
endpoint: /* @__PURE__ */ jsx(Highlight, {
|
|
128
|
+
result,
|
|
129
|
+
name: "endpoint"
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
133
|
+
className: `${style.MethodDescription} ${style.Content}`,
|
|
134
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
135
|
+
result,
|
|
136
|
+
name: "description"
|
|
137
|
+
})
|
|
138
|
+
})] });
|
|
139
|
+
case "model": {
|
|
140
|
+
const properties = result.children?.map((child, index) => /* @__PURE__ */ jsx("span", {
|
|
141
|
+
className: style.TextIdentifier,
|
|
142
|
+
children: child
|
|
143
|
+
}, index)) ?? [];
|
|
144
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
145
|
+
className: style.Property,
|
|
146
|
+
"data-stldocs-language": language,
|
|
147
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
148
|
+
className: style.PropertyHeader,
|
|
149
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
150
|
+
className: style.PropertyName,
|
|
151
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
152
|
+
result,
|
|
153
|
+
name: result.title ? "title" : "name"
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
157
|
+
className: style.PropertyDeclaration,
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ jsx(Highlight, {
|
|
160
|
+
result,
|
|
161
|
+
name: "ident"
|
|
162
|
+
}),
|
|
163
|
+
":",
|
|
164
|
+
" ",
|
|
165
|
+
/* @__PURE__ */ jsx(Docs.Join, {
|
|
166
|
+
items: properties,
|
|
167
|
+
limit: 3,
|
|
168
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
169
|
+
className: style.TextPunctuation,
|
|
170
|
+
children: ", "
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
]
|
|
174
|
+
})]
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
case "resource": return /* @__PURE__ */ jsxs("div", {
|
|
178
|
+
className: style.SearchResultResourceInfo,
|
|
179
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
180
|
+
className: style.SearchResultResourceTitle,
|
|
181
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
182
|
+
result,
|
|
183
|
+
name: "title"
|
|
184
|
+
})
|
|
185
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
186
|
+
className: style.SearchResultResourcePath,
|
|
187
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
188
|
+
result,
|
|
189
|
+
name: "QualifiedName"
|
|
190
|
+
})
|
|
191
|
+
})]
|
|
192
|
+
});
|
|
193
|
+
case "property": return /* @__PURE__ */ jsxs("div", {
|
|
194
|
+
className: style.Property,
|
|
195
|
+
"data-stldocs-language": language,
|
|
196
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
197
|
+
className: style.PropertyHeader,
|
|
198
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
199
|
+
className: style.PropertyName,
|
|
200
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
201
|
+
result,
|
|
202
|
+
name: "name"
|
|
203
|
+
})
|
|
204
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
205
|
+
className: style.PropertyTypeName,
|
|
206
|
+
children: /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: result.type ?? "" } })
|
|
207
|
+
})]
|
|
208
|
+
}), result.docstring && /* @__PURE__ */ jsx("span", {
|
|
209
|
+
className: style.PropertyDescription,
|
|
210
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
211
|
+
result,
|
|
212
|
+
name: "docstring"
|
|
213
|
+
})
|
|
214
|
+
})]
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//#endregion
|
|
220
|
+
//#region src/form.tsx
|
|
221
|
+
function SearchForm() {
|
|
222
|
+
const Docs = useComponents();
|
|
223
|
+
const search = useSearch();
|
|
224
|
+
const language = useLanguage();
|
|
225
|
+
const { onSelect, pageFind } = useSearchContext();
|
|
226
|
+
const [results, setResults] = React.useState(null);
|
|
227
|
+
const [filterKind, setFilterKind] = React.useState("all");
|
|
228
|
+
const [searchQuery, setSearchQuery] = React.useState("");
|
|
229
|
+
const inputRef = React.useRef(null);
|
|
230
|
+
async function performSearch() {
|
|
231
|
+
const guideLimit = filterKind === "guide" ? 25 : 5;
|
|
232
|
+
const kind = ["all", "guide"].includes(filterKind) ? void 0 : filterKind;
|
|
233
|
+
const [guideResults, apiResults] = await Promise.all([pageFind ? guideSearch(pageFind, searchQuery, guideLimit) : [], search({
|
|
234
|
+
query: searchQuery,
|
|
235
|
+
kind,
|
|
236
|
+
language
|
|
237
|
+
})]);
|
|
238
|
+
setResults({
|
|
239
|
+
items: filterKind === "guide" ? guideResults : filterKind === "all" ? [...guideResults.slice(0, 5), ...apiResults?.hits ?? []] : apiResults?.hits ?? [],
|
|
240
|
+
counts: {
|
|
241
|
+
...apiResults?.facets?.["kind"],
|
|
242
|
+
guide: guideResults.length,
|
|
243
|
+
all: apiResults?.nbHits
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function clearInput() {
|
|
248
|
+
setSearchQuery("");
|
|
249
|
+
inputRef?.current?.focus();
|
|
250
|
+
}
|
|
251
|
+
React.useEffect(() => void performSearch(), [
|
|
252
|
+
searchQuery,
|
|
253
|
+
filterKind,
|
|
254
|
+
language
|
|
255
|
+
]);
|
|
256
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
257
|
+
className: style.SearchForm,
|
|
258
|
+
children: [
|
|
259
|
+
/* @__PURE__ */ jsx(Docs.Input, {
|
|
260
|
+
ref: inputRef,
|
|
261
|
+
autoFocus: true,
|
|
262
|
+
onChange: (ev) => setSearchQuery(ev.target.value),
|
|
263
|
+
left: /* @__PURE__ */ jsx(Search, {
|
|
264
|
+
size: 16,
|
|
265
|
+
className: style.Icon
|
|
266
|
+
}),
|
|
267
|
+
right: searchQuery && /* @__PURE__ */ jsx(X, {
|
|
268
|
+
cursor: "pointer",
|
|
269
|
+
onClick: () => clearInput(),
|
|
270
|
+
size: 16,
|
|
271
|
+
className: style.Icon
|
|
272
|
+
}),
|
|
273
|
+
value: searchQuery,
|
|
274
|
+
placeholder: "Search"
|
|
275
|
+
}),
|
|
276
|
+
/* @__PURE__ */ jsx(SearchFilter, {
|
|
277
|
+
results,
|
|
278
|
+
filterKind,
|
|
279
|
+
onChange: (filterKind$1) => setFilterKind(filterKind$1)
|
|
280
|
+
}),
|
|
281
|
+
/* @__PURE__ */ jsx(Docs.ListView, {
|
|
282
|
+
items: results?.items ?? [],
|
|
283
|
+
itemDelegate: (item) => "kind" in item ? /* @__PURE__ */ jsx(SearchResult, { result: item }) : /* @__PURE__ */ jsx(GuideResult, { result: item }),
|
|
284
|
+
onSelectListItem: (item) => onSelect?.(item["data"]?.["url"] ?? item["stainlessPath"])
|
|
285
|
+
})
|
|
286
|
+
]
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
function SearchFilter({ results, filterKind, onChange }) {
|
|
290
|
+
const Docs = useComponents();
|
|
291
|
+
const { pageFind } = useSearchContext();
|
|
292
|
+
const toggles = pageFind ? QueryKinds : QueryKinds.slice(0, -1);
|
|
293
|
+
return /* @__PURE__ */ jsx("div", {
|
|
294
|
+
className: style.SearchFilter,
|
|
295
|
+
children: toggles.map((kind, index) => /* @__PURE__ */ jsxs(Docs.ToggleButton, {
|
|
296
|
+
selected: filterKind === kind,
|
|
297
|
+
onClick: () => onChange?.(kind),
|
|
298
|
+
children: [
|
|
299
|
+
React.createElement(QueryKindDisplay[kind].icon, {
|
|
300
|
+
size: 16,
|
|
301
|
+
className: style.Icon
|
|
302
|
+
}),
|
|
303
|
+
/* @__PURE__ */ jsx("span", {
|
|
304
|
+
className: style.SearchFilterLabel,
|
|
305
|
+
children: QueryKindDisplay[kind].name
|
|
306
|
+
}),
|
|
307
|
+
/* @__PURE__ */ jsx("span", {
|
|
308
|
+
className: style.SearchFilterCount,
|
|
309
|
+
children: results?.counts?.[kind] ?? 0
|
|
310
|
+
})
|
|
311
|
+
]
|
|
312
|
+
}, index))
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function SearchModal({ id, open: isOpen }) {
|
|
316
|
+
const [open, setOpen] = React.useState(isOpen ?? false);
|
|
317
|
+
return /* @__PURE__ */ jsx("div", {
|
|
318
|
+
id,
|
|
319
|
+
onToggle: (ev) => setOpen(ev.newState === "open"),
|
|
320
|
+
className: style.SearchModal,
|
|
321
|
+
popover: "auto",
|
|
322
|
+
"data-stldocs-modal-open": open,
|
|
323
|
+
children: open && /* @__PURE__ */ jsx(SearchForm, {})
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
//#endregion
|
|
328
|
+
export { SearchFilter, SearchForm, SearchModal };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { Languages, generateRoute, parseStainlessPath, walkTree } from "@stainless-api/docs-ui/routing";
|
|
2
|
+
import { printer, renderMarkdown } from "@stainless-api/docs-ui/markdown";
|
|
3
|
+
|
|
4
|
+
//#region src/indexer.ts
|
|
5
|
+
function getResourceNames(resourceIds, topResources) {
|
|
6
|
+
let element = void 0;
|
|
7
|
+
let resources = topResources;
|
|
8
|
+
const resourceName = [];
|
|
9
|
+
for (const resource of resourceIds) {
|
|
10
|
+
element = resources?.[resource];
|
|
11
|
+
if (!element) break;
|
|
12
|
+
resourceName.push(element.title);
|
|
13
|
+
resources = element?.subresources;
|
|
14
|
+
}
|
|
15
|
+
return resourceName;
|
|
16
|
+
}
|
|
17
|
+
function chunkByLines(content, maxSize = 6e4) {
|
|
18
|
+
if (Buffer.byteLength(content, "utf8") < maxSize) return [content];
|
|
19
|
+
const lines = content.split("\n");
|
|
20
|
+
const chunks = [];
|
|
21
|
+
let currentChunk = [];
|
|
22
|
+
let currentSize = 0;
|
|
23
|
+
for (const line of lines) {
|
|
24
|
+
const lineSize = Buffer.byteLength(line + "\n", "utf8");
|
|
25
|
+
if (currentSize + lineSize > maxSize) {
|
|
26
|
+
chunks.push(currentChunk.join("\n"));
|
|
27
|
+
currentChunk = [];
|
|
28
|
+
currentSize = 0;
|
|
29
|
+
}
|
|
30
|
+
currentChunk.push(line);
|
|
31
|
+
currentSize += lineSize;
|
|
32
|
+
}
|
|
33
|
+
if (currentChunk.length > 0) chunks.push(currentChunk.join("\n"));
|
|
34
|
+
return chunks;
|
|
35
|
+
}
|
|
36
|
+
function* generateChatIndex(spec) {
|
|
37
|
+
for (const [language, readme] of Object.entries(spec.readme)) {
|
|
38
|
+
const chunks = chunkByLines(readme);
|
|
39
|
+
for (const chunk of chunks) yield {
|
|
40
|
+
language,
|
|
41
|
+
title: "Overview",
|
|
42
|
+
content: chunk,
|
|
43
|
+
url: `docs://BASE_PATH/${language}`
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
for (const { data } of walkTree(spec)) {
|
|
47
|
+
if (data.kind !== "http_method") continue;
|
|
48
|
+
const { title, name, stainlessPath, httpMethod, summary, description } = data;
|
|
49
|
+
const endpoint = data.endpoint.slice(httpMethod.length).trim();
|
|
50
|
+
for (const language of Languages) {
|
|
51
|
+
const decl = spec.decls[language]?.[stainlessPath];
|
|
52
|
+
if (!decl) continue;
|
|
53
|
+
const chunks = chunkByLines(renderMarkdown({
|
|
54
|
+
spec,
|
|
55
|
+
language,
|
|
56
|
+
options: { includeModelProperties: true }
|
|
57
|
+
}, data));
|
|
58
|
+
for (const chunk of chunks) yield {
|
|
59
|
+
language,
|
|
60
|
+
title,
|
|
61
|
+
name,
|
|
62
|
+
endpoint,
|
|
63
|
+
httpMethod,
|
|
64
|
+
summary,
|
|
65
|
+
description,
|
|
66
|
+
stainlessPath,
|
|
67
|
+
qualified: "qualified" in decl ? decl["qualified"] : void 0,
|
|
68
|
+
ident: "ident" in decl ? decl["ident"] : void 0,
|
|
69
|
+
content: chunk,
|
|
70
|
+
url: generateRoute("docs://BASE_PATH", language, stainlessPath)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function* generateIndex(spec, renderMarkdownFn, includeTypes) {
|
|
76
|
+
const parentCrumbs = {};
|
|
77
|
+
for (const { data } of walkTree(spec, true)) {
|
|
78
|
+
const { kind, name, title, stainlessPath } = data;
|
|
79
|
+
const common = {
|
|
80
|
+
name,
|
|
81
|
+
title,
|
|
82
|
+
stainlessPath
|
|
83
|
+
};
|
|
84
|
+
const crumbs = getResourceNames(parseStainlessPath(stainlessPath).resource, spec.resources);
|
|
85
|
+
switch (kind) {
|
|
86
|
+
case "resource":
|
|
87
|
+
for (const language of Languages) {
|
|
88
|
+
if (!data[language]) continue;
|
|
89
|
+
parentCrumbs[stainlessPath] = crumbs;
|
|
90
|
+
const { Name, QualifiedName } = data[language];
|
|
91
|
+
yield {
|
|
92
|
+
kind,
|
|
93
|
+
crumbs,
|
|
94
|
+
language,
|
|
95
|
+
Name,
|
|
96
|
+
QualifiedName,
|
|
97
|
+
priority: 0,
|
|
98
|
+
...common
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
case "http_method": {
|
|
103
|
+
const { summary, endpoint, httpMethod } = data;
|
|
104
|
+
for (const language of Languages) {
|
|
105
|
+
const found = spec.decls[language]?.[stainlessPath];
|
|
106
|
+
if (!found) continue;
|
|
107
|
+
parentCrumbs[stainlessPath] = [...crumbs, title];
|
|
108
|
+
const qualified = "qualified" in found ? found["qualified"] : void 0;
|
|
109
|
+
const ident = qualified?.split(".")?.at(-1);
|
|
110
|
+
yield {
|
|
111
|
+
kind,
|
|
112
|
+
crumbs: [...crumbs, title],
|
|
113
|
+
ident,
|
|
114
|
+
qualified,
|
|
115
|
+
language,
|
|
116
|
+
description: data.description ? renderMarkdownFn?.(data.description) ?? data.description : void 0,
|
|
117
|
+
endpoint: endpoint.slice(httpMethod.length).trim(),
|
|
118
|
+
httpMethod,
|
|
119
|
+
summary,
|
|
120
|
+
priority: 0,
|
|
121
|
+
...common
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case "model": for (const language of Languages) {
|
|
127
|
+
if (!spec.decls[language]) continue;
|
|
128
|
+
parentCrumbs[stainlessPath] = [...crumbs, title];
|
|
129
|
+
const schema = spec.decls[language]?.[`${stainlessPath} > (schema)`];
|
|
130
|
+
const children = (schema && "children" in schema ? schema?.["children"] : void 0)?.map((childPath) => {
|
|
131
|
+
const child = spec.decls?.[language]?.[childPath];
|
|
132
|
+
return child?.["ident"] ?? child?.["name"] ?? child?.["key"] ?? child?.["type"]?.["literal"]?.["value"] ?? child?.["type"]?.["literal"] ?? child?.["type"]?.["value"];
|
|
133
|
+
})?.filter((child) => child) ?? [];
|
|
134
|
+
yield {
|
|
135
|
+
kind,
|
|
136
|
+
crumbs: [...crumbs, title],
|
|
137
|
+
children,
|
|
138
|
+
language,
|
|
139
|
+
priority: 2,
|
|
140
|
+
ident: schema && "ident" in schema ? schema?.["ident"] : void 0,
|
|
141
|
+
...common
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
for (const language of Languages) {
|
|
147
|
+
const decls = spec.decls?.[language];
|
|
148
|
+
if (!decls) continue;
|
|
149
|
+
for (const decl of Object.values(decls)) switch (decl.kind) {
|
|
150
|
+
case "JavaDeclProperty":
|
|
151
|
+
case "GoDeclProperty":
|
|
152
|
+
case "PythonDeclProperty":
|
|
153
|
+
case "RubyDeclProperty":
|
|
154
|
+
case "HttpDeclProperty":
|
|
155
|
+
case "TSDeclProperty":
|
|
156
|
+
{
|
|
157
|
+
const parsedPath = parseStainlessPath(decl.stainlessPath);
|
|
158
|
+
const type = includeTypes === false ? void 0 : printer.typeName(language, decl.type);
|
|
159
|
+
const name = decl["ident"] ?? decl["name"] ?? decl["key"];
|
|
160
|
+
const parent = parentCrumbs[parsedPath.routable];
|
|
161
|
+
if (parent === void 0) continue;
|
|
162
|
+
const matches = decl.stainlessPath.matchAll(/\((property|params|param)\) ([^\s]+)/g);
|
|
163
|
+
const props = Array.from(matches).map((p) => p[2]).filter((p) => p !== void 0);
|
|
164
|
+
yield {
|
|
165
|
+
kind: "property",
|
|
166
|
+
name,
|
|
167
|
+
stainlessPath: decl.stainlessPath,
|
|
168
|
+
crumbs: [...parent, ...props],
|
|
169
|
+
docstring: decl.docstring ? renderMarkdownFn?.(decl.docstring) ?? decl.docstring : void 0,
|
|
170
|
+
type,
|
|
171
|
+
language,
|
|
172
|
+
priority: 3
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//#endregion
|
|
181
|
+
export { generateIndex as n, generateChatIndex as t };
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { n as IndexEntry, r as IndexMethod } from "./types-Gg968wOz.js";
|
|
2
|
+
import { DocsLanguage } from "@stainless-api/docs-ui/routing";
|
|
3
|
+
import * as SDKJSON from "@stainless/sdk-json";
|
|
4
|
+
|
|
5
|
+
//#region src/indexer.d.ts
|
|
6
|
+
|
|
7
|
+
declare function generateIndex(spec: SDKJSON.Spec, renderMarkdownFn?: (_: string) => string | null, includeTypes?: boolean): Generator<IndexEntry>;
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/mcp.d.ts
|
|
10
|
+
type Item = IndexEntry & IndexMethod;
|
|
11
|
+
declare function render(spec: SDKJSON.Spec, language: DocsLanguage, items: Item[], includeModelProperties: boolean): any;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { generateIndex, render };
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { n as generateIndex } from "./indexer-DBU0POrK.js";
|
|
2
|
+
import { parseStainlessPath } from "@stainless-api/docs-ui/routing";
|
|
3
|
+
import { renderMarkdown } from "@stainless-api/docs-ui/markdown";
|
|
4
|
+
import { getResourceFromSpec } from "@stainless-api/docs-ui/utils";
|
|
5
|
+
|
|
6
|
+
//#region src/mcp.ts
|
|
7
|
+
function consolidate(results) {
|
|
8
|
+
const resources = /* @__PURE__ */ new Set();
|
|
9
|
+
const methods = /* @__PURE__ */ new Set();
|
|
10
|
+
for (const entry of results) {
|
|
11
|
+
const parsed = parseStainlessPath(entry.stainlessPath);
|
|
12
|
+
if (parsed.method) methods.add(parsed.routable);
|
|
13
|
+
else resources.add(parsed.routable);
|
|
14
|
+
}
|
|
15
|
+
const filtered = Array.from(methods).filter((path) => !resources.has(path.split(" >").at(0)));
|
|
16
|
+
return [...resources, ...filtered];
|
|
17
|
+
}
|
|
18
|
+
function render(spec, language, items, includeModelProperties) {
|
|
19
|
+
const env = {
|
|
20
|
+
spec,
|
|
21
|
+
language,
|
|
22
|
+
options: {
|
|
23
|
+
renderNestedResources: false,
|
|
24
|
+
includeModelProperties
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const output = consolidate(items).map((entry) => {
|
|
28
|
+
const parsed = parseStainlessPath(entry);
|
|
29
|
+
const resource = getResourceFromSpec(parsed.resource, spec);
|
|
30
|
+
return [entry, renderMarkdown(env, parsed.method ? resource.methods[parsed.method] : resource)];
|
|
31
|
+
});
|
|
32
|
+
return Object.fromEntries(output);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { generateIndex, render };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/providers/pagefind.ts
|
|
2
|
+
async function loadPagefind(path) {
|
|
3
|
+
return await import(new URL(path, import.meta.url).href);
|
|
4
|
+
}
|
|
5
|
+
async function guideSearch(loadPath, query, limit) {
|
|
6
|
+
const response = await (await loadPagefind(loadPath)).search(query);
|
|
7
|
+
const items = limit ? response.results.slice(0, limit) : response.results;
|
|
8
|
+
return Promise.all(items.map((result) => result.data().then((data) => ({
|
|
9
|
+
...result,
|
|
10
|
+
data
|
|
11
|
+
}))));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { guideSearch as t };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { f as ResultType, g as SearchSettings, h as SearchParams, s as ProseIndexEntry } from "../types-Gg968wOz.js";
|
|
2
|
+
import * as SDKJSON from "@stainless/sdk-json";
|
|
3
|
+
|
|
4
|
+
//#region src/providers/algolia.d.ts
|
|
5
|
+
declare function buildIndex(appId: string, indexName: string, writeKey: string, spec: SDKJSON.Spec, renderMarkdown: (_: string) => string | null): Promise<void>;
|
|
6
|
+
declare function buildChatIndex(appId: string, indexName: string, writeKey: string, spec: SDKJSON.Spec): Promise<void>;
|
|
7
|
+
declare function buildProseIndex(appId: string, indexName: string, writeKey: string, objects: ProseIndexEntry[]): Promise<void>;
|
|
8
|
+
declare function search({
|
|
9
|
+
settings: {
|
|
10
|
+
appId,
|
|
11
|
+
indexName,
|
|
12
|
+
searchKey
|
|
13
|
+
},
|
|
14
|
+
params: {
|
|
15
|
+
query,
|
|
16
|
+
language,
|
|
17
|
+
kind
|
|
18
|
+
}
|
|
19
|
+
}: {
|
|
20
|
+
params: SearchParams;
|
|
21
|
+
settings: SearchSettings;
|
|
22
|
+
}): Promise<ResultType | undefined>;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { buildChatIndex, buildIndex, buildProseIndex, search };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { n as IndexEntry } from "../types-Gg968wOz.js";
|
|
2
|
+
import { DocsLanguage } from "@stainless-api/docs-ui/routing";
|
|
3
|
+
import * as fuse_js0 from "fuse.js";
|
|
4
|
+
import { FuseIndex } from "fuse.js";
|
|
5
|
+
import * as SDKJSON from "@stainless/sdk-json";
|
|
6
|
+
|
|
7
|
+
//#region src/providers/fuse.d.ts
|
|
8
|
+
type FuseIndexData = {
|
|
9
|
+
content: IndexEntry[];
|
|
10
|
+
index: FuseIndex<IndexEntry>;
|
|
11
|
+
};
|
|
12
|
+
declare function buildIndex(spec: SDKJSON.Spec, language?: DocsLanguage): FuseIndexData;
|
|
13
|
+
declare function search({
|
|
14
|
+
content,
|
|
15
|
+
index
|
|
16
|
+
}: FuseIndexData, query: string, limit?: number): fuse_js0.FuseResult<IndexEntry>[];
|
|
17
|
+
//#endregion
|
|
18
|
+
export { FuseIndexData, buildIndex, search };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { n as generateIndex } from "../indexer-DBU0POrK.js";
|
|
2
|
+
import { n as SearchableAttributes } from "../types-BhJLoaNF.js";
|
|
3
|
+
import Fuse from "fuse.js";
|
|
4
|
+
|
|
5
|
+
//#region src/providers/fuse.ts
|
|
6
|
+
function buildIndex(spec, language) {
|
|
7
|
+
const idx = Array.from(generateIndex(spec, void 0, false));
|
|
8
|
+
const content = language ? idx.filter((entry) => entry.language === language) : idx;
|
|
9
|
+
return {
|
|
10
|
+
content,
|
|
11
|
+
index: Fuse.createIndex([...SearchableAttributes], content)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function search({ content, index }, query, limit = 100) {
|
|
15
|
+
return new Fuse(content, { keys: [...SearchableAttributes] }, index).search(query).slice(0, limit);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { buildIndex, search };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { n as IndexEntry } from "../types-Gg968wOz.js";
|
|
2
|
+
import { DocsLanguage } from "@stainless-api/docs-ui/routing";
|
|
3
|
+
import * as SDKJSON from "@stainless/sdk-json";
|
|
4
|
+
|
|
5
|
+
//#region src/providers/walker.d.ts
|
|
6
|
+
declare function buildIndex(spec: SDKJSON.Spec): Generator<IndexEntry, any, any>;
|
|
7
|
+
declare function search(index: Generator<IndexEntry>, language: DocsLanguage, query: string, limit?: number): IndexEntry[];
|
|
8
|
+
//#endregion
|
|
9
|
+
export { buildIndex, search };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { n as generateIndex } from "../indexer-DBU0POrK.js";
|
|
2
|
+
import { n as SearchableAttributes } from "../types-BhJLoaNF.js";
|
|
3
|
+
|
|
4
|
+
//#region src/providers/walker.ts
|
|
5
|
+
function buildIndex(spec) {
|
|
6
|
+
return generateIndex(spec, void 0, false);
|
|
7
|
+
}
|
|
8
|
+
function* findEntryInIndex(index, language, query) {
|
|
9
|
+
for (const entry of index) {
|
|
10
|
+
if (entry.language !== language) continue;
|
|
11
|
+
for (const attr of SearchableAttributes) {
|
|
12
|
+
const attr_ = attr in entry ? attr : null;
|
|
13
|
+
if (attr_ && entry[attr_] && typeof entry[attr_] === "string" && entry[attr_].includes(query)) yield entry;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function search(index, language, query, limit = 100) {
|
|
18
|
+
const results = findEntryInIndex(index, language, query);
|
|
19
|
+
return Array.from(results).sort((a, b) => a.priority - b.priority).slice(0, limit);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { buildIndex, search };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/types.ts
|
|
2
|
+
const QueryKinds = [
|
|
3
|
+
"all",
|
|
4
|
+
"resource",
|
|
5
|
+
"http_method",
|
|
6
|
+
"model",
|
|
7
|
+
"property",
|
|
8
|
+
"guide"
|
|
9
|
+
];
|
|
10
|
+
const SearchableAttributes = [
|
|
11
|
+
"name",
|
|
12
|
+
"title",
|
|
13
|
+
"ident",
|
|
14
|
+
"Name",
|
|
15
|
+
"qualified",
|
|
16
|
+
"QualifiedName",
|
|
17
|
+
"endpoint",
|
|
18
|
+
"summary",
|
|
19
|
+
"description",
|
|
20
|
+
"docstring"
|
|
21
|
+
];
|
|
22
|
+
const SearchableAttributesChat = [
|
|
23
|
+
"title",
|
|
24
|
+
"name",
|
|
25
|
+
"endpoint",
|
|
26
|
+
"summary",
|
|
27
|
+
"description",
|
|
28
|
+
"qualified",
|
|
29
|
+
"ident",
|
|
30
|
+
"content"
|
|
31
|
+
];
|
|
32
|
+
const SearchableAttributesProse = ["content"];
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { SearchableAttributesProse as i, SearchableAttributes as n, SearchableAttributesChat as r, QueryKinds as t };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DocsLanguage } from "@stainless-api/docs-ui/routing";
|
|
2
|
+
import * as SDKJSON from "@stainless/sdk-json";
|
|
3
|
+
|
|
4
|
+
//#region src/types.d.ts
|
|
5
|
+
type SearchSettings = {
|
|
6
|
+
appId: string;
|
|
7
|
+
searchKey: string;
|
|
8
|
+
indexName: string;
|
|
9
|
+
assistant?: string;
|
|
10
|
+
};
|
|
11
|
+
type SearchParams = {
|
|
12
|
+
query: string;
|
|
13
|
+
language?: DocsLanguage | null;
|
|
14
|
+
kind?: QueryKindsType | null;
|
|
15
|
+
};
|
|
16
|
+
declare const QueryKinds: readonly ["all", "resource", "http_method", "model", "property", "guide"];
|
|
17
|
+
type QueryKindsType = (typeof QueryKinds)[number];
|
|
18
|
+
type IndexModel = {
|
|
19
|
+
kind: 'model';
|
|
20
|
+
title: string;
|
|
21
|
+
children?: string[];
|
|
22
|
+
ident?: string;
|
|
23
|
+
};
|
|
24
|
+
type IndexProperty = {
|
|
25
|
+
kind: 'property';
|
|
26
|
+
docstring?: string;
|
|
27
|
+
type?: string;
|
|
28
|
+
};
|
|
29
|
+
type IndexResource = {
|
|
30
|
+
kind: 'resource';
|
|
31
|
+
title: string;
|
|
32
|
+
Name: string;
|
|
33
|
+
QualifiedName: string;
|
|
34
|
+
};
|
|
35
|
+
type IndexMethod = Pick<SDKJSON.Method, 'kind' | 'summary' | 'description' | 'endpoint' | 'httpMethod'> & {
|
|
36
|
+
title: string;
|
|
37
|
+
qualified?: string;
|
|
38
|
+
ident?: string;
|
|
39
|
+
};
|
|
40
|
+
declare const SearchableAttributes: readonly ["name", "title", "ident", "Name", "qualified", "QualifiedName", "endpoint", "summary", "description", "docstring"];
|
|
41
|
+
declare const SearchableAttributesChat: string[];
|
|
42
|
+
declare const SearchableAttributesProse: string[];
|
|
43
|
+
type SearchAttributeNames = (typeof SearchableAttributes)[number];
|
|
44
|
+
type RoutableJsonNode = SDKJSON.Method | SDKJSON.Model | SDKJSON.Resource;
|
|
45
|
+
type IndexEntry = Pick<RoutableJsonNode, 'name' | 'stainlessPath'> & (IndexProperty | IndexModel | IndexResource | IndexMethod) & {
|
|
46
|
+
language: DocsLanguage;
|
|
47
|
+
priority: number;
|
|
48
|
+
crumbs: string[];
|
|
49
|
+
};
|
|
50
|
+
type ResultRecordType = IndexEntry & {
|
|
51
|
+
objectID: string;
|
|
52
|
+
_highlightResult: Record<SearchAttributeNames, {
|
|
53
|
+
value: string;
|
|
54
|
+
}>;
|
|
55
|
+
};
|
|
56
|
+
type ResultType = {
|
|
57
|
+
hits: ResultRecordType[];
|
|
58
|
+
facets?: Record<string, Record<string, number>>;
|
|
59
|
+
nbHits: number;
|
|
60
|
+
};
|
|
61
|
+
type GuideResultType = {
|
|
62
|
+
id: string;
|
|
63
|
+
score: number;
|
|
64
|
+
words: number[];
|
|
65
|
+
data: {
|
|
66
|
+
excerpt: string;
|
|
67
|
+
url: string;
|
|
68
|
+
word_count: number;
|
|
69
|
+
meta: {
|
|
70
|
+
title: string;
|
|
71
|
+
};
|
|
72
|
+
sub_results: {
|
|
73
|
+
url: string;
|
|
74
|
+
title: string;
|
|
75
|
+
excerpt: string;
|
|
76
|
+
}[];
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
type ResultData = {
|
|
80
|
+
items: Array<ResultRecordType | GuideResultType>;
|
|
81
|
+
counts: Partial<Record<QueryKindsType, number>>;
|
|
82
|
+
};
|
|
83
|
+
type ProseIndexEntry = {
|
|
84
|
+
id?: string;
|
|
85
|
+
tag: string;
|
|
86
|
+
content: string;
|
|
87
|
+
source?: string;
|
|
88
|
+
[additional: string]: unknown;
|
|
89
|
+
};
|
|
90
|
+
//#endregion
|
|
91
|
+
export { SearchableAttributes as _, IndexProperty as a, QueryKinds as c, ResultRecordType as d, ResultType as f, SearchSettings as g, SearchParams as h, IndexModel as i, QueryKindsType as l, SearchAttributeNames as m, IndexEntry as n, IndexResource as o, RoutableJsonNode as p, IndexMethod as r, ProseIndexEntry as s, GuideResultType as t, ResultData as u, SearchableAttributesChat as v, SearchableAttributesProse as y };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { _ as SearchableAttributes, a as IndexProperty, c as QueryKinds, d as ResultRecordType, f as ResultType, g as SearchSettings, h as SearchParams, i as IndexModel, l as QueryKindsType, m as SearchAttributeNames, n as IndexEntry, o as IndexResource, p as RoutableJsonNode, r as IndexMethod, s as ProseIndexEntry, t as GuideResultType, u as ResultData, v as SearchableAttributesChat, y as SearchableAttributesProse } from "./types-Gg968wOz.js";
|
|
2
|
+
export { GuideResultType, IndexEntry, IndexMethod, IndexModel, IndexProperty, IndexResource, ProseIndexEntry, QueryKinds, QueryKindsType, ResultData, ResultRecordType, ResultType, RoutableJsonNode, SearchAttributeNames, SearchParams, SearchSettings, SearchableAttributes, SearchableAttributesChat, SearchableAttributesProse };
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stainless-api/docs-search",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"react": ">=19.0.0",
|
|
13
|
+
"react-dom": ">=19.0.0"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@algolia/client-search": "^5.25.0",
|
|
17
|
+
"@markdoc/markdoc": "^0.5.4",
|
|
18
|
+
"cheerio": "^1.1.2",
|
|
19
|
+
"fuse.js": "^7.1.0",
|
|
20
|
+
"htmlparser2": "^10.0.0",
|
|
21
|
+
"lucide-react": "^0.561.0",
|
|
22
|
+
"@stainless-api/docs-ui": "0.1.0-beta.49"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "24.10.1",
|
|
26
|
+
"@types/react": "19.2.7",
|
|
27
|
+
"@types/react-dom": "^19.2.3",
|
|
28
|
+
"dotenv": "17.2.3",
|
|
29
|
+
"react": "^19.2.3",
|
|
30
|
+
"react-dom": "^19.2.3",
|
|
31
|
+
"tsdown": "^0.17.3",
|
|
32
|
+
"typescript": "5.9.3",
|
|
33
|
+
"@stainless/eslint-config": "0.1.0-beta.0",
|
|
34
|
+
"@stainless/sdk-json": "^0.1.0-beta.2"
|
|
35
|
+
},
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./context": {
|
|
41
|
+
"default": "./dist/context.js"
|
|
42
|
+
},
|
|
43
|
+
"./mcp": {
|
|
44
|
+
"default": "./dist/mcp.js"
|
|
45
|
+
},
|
|
46
|
+
"./types": {
|
|
47
|
+
"default": "./dist/types.js"
|
|
48
|
+
},
|
|
49
|
+
"./providers/*": {
|
|
50
|
+
"default": "./dist/providers/*.js"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsdown",
|
|
55
|
+
"clean": "rm -rf dist",
|
|
56
|
+
"lint": "eslint .",
|
|
57
|
+
"check:types": "tsc --noEmit"
|
|
58
|
+
}
|
|
59
|
+
}
|