@stainless-api/docs 0.1.0-beta.51 → 0.1.0-beta.53
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/CHANGELOG.md +20 -0
- package/eslint-suppressions.json +1 -1
- package/package.json +8 -8
- package/plugin/index.ts +14 -0
- package/stl-docs/index.ts +2 -0
- package/stl-docs/proseSearchIndexing.ts +113 -0
- package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @stainless-api/docs
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.53
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2b0fec9: Added prose indexing for search
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [2b0fec9]
|
|
12
|
+
- @stainless-api/docs-ui@0.1.0-beta.44
|
|
13
|
+
|
|
14
|
+
## 0.1.0-beta.52
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 72c7604: include default themes in stainlessStarlight plugin
|
|
19
|
+
- Updated dependencies [8a32bbb]
|
|
20
|
+
- @stainless-api/ui-primitives@0.1.0-beta.32
|
|
21
|
+
- @stainless-api/docs-ui@0.1.0-beta.43
|
|
22
|
+
|
|
3
23
|
## 0.1.0-beta.51
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/eslint-suppressions.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stainless-api/docs",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.53",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"remark-gfm": "^4.0.1",
|
|
48
48
|
"remark-github-alerts": "^0.1.1",
|
|
49
49
|
"remark-stringify": "^11.0.0",
|
|
50
|
-
"shiki": "^3.
|
|
50
|
+
"shiki": "^3.19.0",
|
|
51
51
|
"unified": "^11.0.5",
|
|
52
52
|
"web-worker": "^1.5.0",
|
|
53
53
|
"yaml": "^2.8.2",
|
|
54
|
-
"@stainless-api/ui-primitives": "0.1.0-beta.
|
|
55
|
-
"@stainless-api/docs-ui": "0.1.0-beta.
|
|
54
|
+
"@stainless-api/ui-primitives": "0.1.0-beta.32",
|
|
55
|
+
"@stainless-api/docs-ui": "0.1.0-beta.44"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@astrojs/check": "^0.9.6",
|
|
@@ -60,14 +60,14 @@
|
|
|
60
60
|
"@types/node": "24.10.1",
|
|
61
61
|
"@types/react": "^19.2.7",
|
|
62
62
|
"@types/react-dom": "^19.2.3",
|
|
63
|
-
"react": "^19.2.
|
|
64
|
-
"react-dom": "^19.2.
|
|
63
|
+
"react": "^19.2.1",
|
|
64
|
+
"react-dom": "^19.2.1",
|
|
65
65
|
"tsx": "^4.21.0",
|
|
66
66
|
"typescript": "5.9.3",
|
|
67
67
|
"vite": "^6.4.1",
|
|
68
68
|
"zod": "^4.1.13",
|
|
69
|
-
"@stainless/
|
|
70
|
-
"@stainless/
|
|
69
|
+
"@stainless/sdk-json": "^0.1.0-beta.0",
|
|
70
|
+
"@stainless/eslint-config": "0.1.0-beta.0"
|
|
71
71
|
},
|
|
72
72
|
"scripts": {
|
|
73
73
|
"vendor-deps": "tsx scripts/vendor_deps.ts",
|
package/plugin/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import react from '@astrojs/react';
|
|
2
2
|
import type { StarlightPlugin } from '@astrojs/starlight/types';
|
|
3
3
|
import type { AstroIntegration, AstroIntegrationLogger } from 'astro';
|
|
4
|
+
import type { BundledTheme } from 'shiki';
|
|
4
5
|
import { config } from 'dotenv';
|
|
5
6
|
import getPort from 'get-port';
|
|
6
7
|
import { startDevServer } from './cms/server';
|
|
@@ -310,8 +311,21 @@ export function stainlessStarlight(someUserConfig: SomeStainlessStarlightUserCon
|
|
|
310
311
|
}
|
|
311
312
|
}
|
|
312
313
|
|
|
314
|
+
const expressiveCodeConfig =
|
|
315
|
+
typeof starlightConfig.expressiveCode === 'object' ? starlightConfig.expressiveCode : {};
|
|
316
|
+
|
|
317
|
+
const themes = expressiveCodeConfig.themes
|
|
318
|
+
? (expressiveCodeConfig.themes as BundledTheme[])
|
|
319
|
+
: (['github-light', 'github-dark'] as BundledTheme[]);
|
|
320
|
+
|
|
313
321
|
updateConfig({
|
|
314
322
|
sidebar: starlightConfig.sidebar,
|
|
323
|
+
...(expressiveCodeConfig && {
|
|
324
|
+
expressiveCode: {
|
|
325
|
+
...expressiveCodeConfig,
|
|
326
|
+
themes,
|
|
327
|
+
},
|
|
328
|
+
}),
|
|
315
329
|
});
|
|
316
330
|
|
|
317
331
|
addRouteMiddleware({
|
package/stl-docs/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type * as StlDocsVirtualModule from 'virtual:stl-docs-virtual-module';
|
|
|
22
22
|
import { resolveSrcFile } from '../resolveSrcFile';
|
|
23
23
|
import { stainlessDocsMarkdownRenderer } from './proseMarkdown/proseMarkdownIntegration';
|
|
24
24
|
import { setSharedLogger } from '../shared/getSharedLogger';
|
|
25
|
+
import { stainlessDocsProseIndexing } from './proseSearchIndexing';
|
|
25
26
|
|
|
26
27
|
export * from '../plugin';
|
|
27
28
|
|
|
@@ -242,5 +243,6 @@ export function stainlessDocs(config: StainlessDocsUserConfig) {
|
|
|
242
243
|
stainlessDocsStarlightIntegration(normalizedConfig),
|
|
243
244
|
stainlessDocsIntegration(normalizedConfig, apiReferenceBasePath),
|
|
244
245
|
stainlessDocsMarkdownRenderer({ enabled: normalizedConfig.enableProseMarkdownRendering }),
|
|
246
|
+
stainlessDocsProseIndexing(),
|
|
245
247
|
];
|
|
246
248
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { AstroIntegration } from 'astro';
|
|
2
|
+
import { readFile } from 'fs/promises';
|
|
3
|
+
import { getSharedLogger } from '../shared/getSharedLogger';
|
|
4
|
+
import { bold } from '../shared/terminalUtils';
|
|
5
|
+
import { buildProseIndex } from '@stainless-api/docs-ui/search/providers/algolia';
|
|
6
|
+
import * as cheerio from 'cheerio';
|
|
7
|
+
|
|
8
|
+
function chunkByWords(content: string, chunkSize: number = 30000, chunkOverlap: number = 10) {
|
|
9
|
+
if (Buffer.byteLength(content) < chunkSize) return [content];
|
|
10
|
+
|
|
11
|
+
const words = content.split(/\s+/);
|
|
12
|
+
const chunks: string[] = [];
|
|
13
|
+
|
|
14
|
+
let currentChunk: string[] = [];
|
|
15
|
+
let currentSize = 0;
|
|
16
|
+
|
|
17
|
+
for (const word of words) {
|
|
18
|
+
const wordSize = Buffer.byteLength(word + ' ', 'utf-8');
|
|
19
|
+
|
|
20
|
+
if (currentSize + wordSize > chunkSize && currentChunk.length > 0) {
|
|
21
|
+
chunks.push(currentChunk.join(' '));
|
|
22
|
+
|
|
23
|
+
const overlapStart = Math.max(0, currentChunk.length - chunkOverlap);
|
|
24
|
+
currentChunk = currentChunk.slice(overlapStart);
|
|
25
|
+
currentSize = Buffer.byteLength(currentChunk.join(' '), 'utf-8');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
currentChunk.push(word);
|
|
29
|
+
currentSize += wordSize;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (currentChunk.length > 0) {
|
|
33
|
+
chunks.push(currentChunk.join(' '));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return chunks;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function* indexHTML(content: string, root: string, pattern: string) {
|
|
40
|
+
const $ = cheerio.load(content);
|
|
41
|
+
const matches = $(root).find(pattern);
|
|
42
|
+
|
|
43
|
+
for (const match of matches) {
|
|
44
|
+
const rawText = $(match).text().trim();
|
|
45
|
+
const chunks = chunkByWords(rawText);
|
|
46
|
+
const chunkId = crypto.randomUUID();
|
|
47
|
+
|
|
48
|
+
for (const [chunkN, content] of chunks.entries()) {
|
|
49
|
+
yield {
|
|
50
|
+
id: $(match).attr('id'),
|
|
51
|
+
tag: match.tagName.toLowerCase(),
|
|
52
|
+
content,
|
|
53
|
+
chunk: {
|
|
54
|
+
id: chunkId,
|
|
55
|
+
index: chunkN,
|
|
56
|
+
total: chunks.length,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const root = 'main';
|
|
64
|
+
const pattern = 'h1, h2, h3, h4, h5, h6, p, li';
|
|
65
|
+
|
|
66
|
+
export function stainlessDocsProseIndexing(): AstroIntegration {
|
|
67
|
+
return {
|
|
68
|
+
name: 'stl-docs-prose-indexing',
|
|
69
|
+
hooks: {
|
|
70
|
+
'astro:build:done': async ({ assets, logger: localLogger, dir }) => {
|
|
71
|
+
const logger = getSharedLogger({ fallback: localLogger });
|
|
72
|
+
const outputBasePath = dir.pathname;
|
|
73
|
+
|
|
74
|
+
const {
|
|
75
|
+
PUBLIC_ALGOLIA_APP_ID: appId,
|
|
76
|
+
PUBLIC_ALGOLIA_INDEX: indexName,
|
|
77
|
+
PRIVATE_ALGOLIA_WRITE_KEY: algoliaWriteKey,
|
|
78
|
+
} = process.env;
|
|
79
|
+
|
|
80
|
+
if (!appId || !indexName || !algoliaWriteKey) {
|
|
81
|
+
logger.info('Skipping algolia indexing due to missing environment variables');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const starlightPagePatterns = ['/[...slug]'];
|
|
86
|
+
const pagesToRender = Array.from(assets.entries())
|
|
87
|
+
.filter(([k]) => starlightPagePatterns.includes(k))
|
|
88
|
+
.map(([, v]) => v)
|
|
89
|
+
.flat()
|
|
90
|
+
.map((v) => v.pathname);
|
|
91
|
+
|
|
92
|
+
logger.info(bold(`Indexing ${pagesToRender.length} prose pages for search`));
|
|
93
|
+
|
|
94
|
+
const objects = [];
|
|
95
|
+
for (const absHtmlPath of pagesToRender) {
|
|
96
|
+
const content = await readFile(absHtmlPath, 'utf-8');
|
|
97
|
+
const idx = indexHTML(content, root, pattern);
|
|
98
|
+
for (const entry of idx)
|
|
99
|
+
objects.push({
|
|
100
|
+
...entry,
|
|
101
|
+
source: absHtmlPath.slice(outputBasePath.length),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
await buildProseIndex(appId, `${indexName}-prose`, algoliaWriteKey, objects);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
logger.error(`Failed to index prose content: ${err}`);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|