@stainless-api/docs 0.1.0-beta.138 → 0.1.0-beta.139
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 +12 -0
- package/eslint-suppressions.json +0 -25
- package/eslint.config.ts +1 -5
- package/package.json +7 -9
- package/plugin/buildAlgoliaIndex.ts +6 -12
- package/plugin/index.ts +74 -38
- package/plugin/loadPluginConfig.ts +14 -130
- package/plugin/specs/defaultSpecLoader.ts +192 -0
- package/plugin/specs/fetchSpecSSR.ts +1 -1
- package/plugin/specs/utils.ts +86 -0
- package/tsconfig.json +1 -1
- package/plugin/specs/FileCache.ts +0 -99
- package/plugin/specs/generateSpec.ts +0 -109
- package/plugin/specs/index.ts +0 -132
- package/plugin/specs/inputResolver.ts +0 -148
- package/plugin/specs/worker.ts +0 -199
- package/plugin/vendor/preview.worker.docs.js +0 -20618
- package/plugin/vendor/templates/cli.md +0 -1
- package/plugin/vendor/templates/go.md +0 -316
- package/plugin/vendor/templates/java.md +0 -91
- package/plugin/vendor/templates/kotlin.md +0 -91
- package/plugin/vendor/templates/node.md +0 -235
- package/plugin/vendor/templates/python.md +0 -251
- package/plugin/vendor/templates/ruby.md +0 -147
- package/plugin/vendor/templates/terraform.md +0 -60
- package/plugin/vendor/templates/typescript.md +0 -319
- package/scripts/vendor_deps.ts +0 -50
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
2
|
-
import { readFile } from 'fs/promises';
|
|
3
|
-
import { AstroIntegrationLogger } from 'astro';
|
|
4
|
-
import { bold } from '../../shared/terminalUtils';
|
|
5
|
-
import type { LanguageGenerateQuery, LoadedApiKey } from '../loadPluginConfig';
|
|
6
|
-
import Stainless, { APIError } from '@stainless-api/sdk';
|
|
7
|
-
import { GenerateSpecRawInputs } from './generateSpec';
|
|
8
|
-
|
|
9
|
-
export type SpecInputResolver = {
|
|
10
|
-
resolve: (context: {
|
|
11
|
-
apiKey: LoadedApiKey | null;
|
|
12
|
-
}) => GenerateSpecRawInputs | Promise<GenerateSpecRawInputs>;
|
|
13
|
-
printError: (error: Error, logger: AstroIntegrationLogger) => void;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function fromFiles({
|
|
17
|
-
oasPath,
|
|
18
|
-
configPath,
|
|
19
|
-
languageOverrides,
|
|
20
|
-
stainlessProject,
|
|
21
|
-
}: {
|
|
22
|
-
oasPath: string;
|
|
23
|
-
configPath: string;
|
|
24
|
-
languageOverrides: LanguageGenerateQuery | null;
|
|
25
|
-
stainlessProject: string;
|
|
26
|
-
}): SpecInputResolver {
|
|
27
|
-
return {
|
|
28
|
-
resolve: async () => {
|
|
29
|
-
const oasStr = await readFile(oasPath, 'utf8');
|
|
30
|
-
const configStr = await readFile(configPath, 'utf8');
|
|
31
|
-
return {
|
|
32
|
-
oasStr,
|
|
33
|
-
configStr,
|
|
34
|
-
versionInfo: null,
|
|
35
|
-
languageOverrides,
|
|
36
|
-
stainlessProject,
|
|
37
|
-
};
|
|
38
|
-
},
|
|
39
|
-
printError: (error: Error, logger: AstroIntegrationLogger) => {
|
|
40
|
-
logger.error(bold('Failed to resolve spec inputs from files:'));
|
|
41
|
-
logger.error(error.message);
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async function fetchVersionInfo(project: string, apiKey: string): Promise<Record<DocsLanguage, string>> {
|
|
47
|
-
const data = await fetch(`https://api.stainless.com/api/projects/${project}/package-versions`, {
|
|
48
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const content = await data.text();
|
|
52
|
-
return JSON.parse(content) as Record<DocsLanguage, string>;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function redactApiKey(apiKey: string) {
|
|
56
|
-
return apiKey
|
|
57
|
-
.split('')
|
|
58
|
-
.map((char, index) => (index < 10 ? char : '*'))
|
|
59
|
-
.join('');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function fromStainlessApi(inputs: {
|
|
63
|
-
stainlessProject: string;
|
|
64
|
-
branch: string;
|
|
65
|
-
apiKey?: LoadedApiKey;
|
|
66
|
-
languageOverrides: LanguageGenerateQuery | null;
|
|
67
|
-
}): SpecInputResolver {
|
|
68
|
-
let apiKey: string | undefined;
|
|
69
|
-
return {
|
|
70
|
-
async resolve(context) {
|
|
71
|
-
apiKey = context.apiKey?.value ?? inputs.apiKey?.value;
|
|
72
|
-
|
|
73
|
-
if (!apiKey) {
|
|
74
|
-
throw new Error('No API key provided');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const client = new Stainless({ apiKey });
|
|
78
|
-
const configs = await client.projects.configs.retrieve({
|
|
79
|
-
project: inputs.stainlessProject,
|
|
80
|
-
branch: inputs.branch,
|
|
81
|
-
include: 'openapi',
|
|
82
|
-
});
|
|
83
|
-
const versionInfo = await fetchVersionInfo(inputs.stainlessProject, apiKey);
|
|
84
|
-
|
|
85
|
-
const configYML = Object.values(configs)[0] as { content: unknown };
|
|
86
|
-
const oasJson = Object.values(configs)[1] as { content: unknown };
|
|
87
|
-
const oasStr = oasJson['content'];
|
|
88
|
-
const configStr = configYML['content'];
|
|
89
|
-
|
|
90
|
-
if (typeof oasStr !== 'string' || typeof configStr !== 'string') {
|
|
91
|
-
throw new Error('Received invalid OAS or config from Stainless');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
oasStr,
|
|
96
|
-
configStr,
|
|
97
|
-
versionInfo,
|
|
98
|
-
languageOverrides: inputs.languageOverrides,
|
|
99
|
-
stainlessProject: inputs.stainlessProject,
|
|
100
|
-
};
|
|
101
|
-
},
|
|
102
|
-
printError: (error: Error, logger: AstroIntegrationLogger) => {
|
|
103
|
-
if (error instanceof APIError && error.status >= 400 && error.status < 500) {
|
|
104
|
-
logger.error(`Requested project slug: "${inputs.stainlessProject}"`);
|
|
105
|
-
if (apiKey) {
|
|
106
|
-
logger.error(`API key: "${redactApiKey(apiKey)}"`);
|
|
107
|
-
}
|
|
108
|
-
logger.error(
|
|
109
|
-
`This error can usually be corrected by re-authenticating with the Stainless. Use the CLI (stl auth login) or verify that the Stainless API key you're using can access the project mentioned above.`,
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function fromStrings({
|
|
117
|
-
oasStr,
|
|
118
|
-
configStr,
|
|
119
|
-
languageOverrides,
|
|
120
|
-
stainlessProject,
|
|
121
|
-
}: {
|
|
122
|
-
oasStr: string;
|
|
123
|
-
configStr: string;
|
|
124
|
-
languageOverrides: LanguageGenerateQuery | null;
|
|
125
|
-
stainlessProject: string;
|
|
126
|
-
}): SpecInputResolver {
|
|
127
|
-
return {
|
|
128
|
-
resolve() {
|
|
129
|
-
return {
|
|
130
|
-
oasStr,
|
|
131
|
-
configStr,
|
|
132
|
-
versionInfo: null,
|
|
133
|
-
languageOverrides,
|
|
134
|
-
stainlessProject,
|
|
135
|
-
};
|
|
136
|
-
},
|
|
137
|
-
printError(error: Error, logger: AstroIntegrationLogger) {
|
|
138
|
-
logger.error(bold('Failed to resolve spec inputs from strings:'));
|
|
139
|
-
logger.error(error.message);
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export const resolveSpec = {
|
|
145
|
-
fromFiles,
|
|
146
|
-
fromStainlessApi,
|
|
147
|
-
fromStrings,
|
|
148
|
-
} satisfies Record<string, (...args: never[]) => SpecInputResolver>;
|
package/plugin/specs/worker.ts
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import Worker from 'web-worker';
|
|
2
|
-
import { Languages, type DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
3
|
-
import type * as SDKJSON from '@stainless/sdk-json';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { dirname, resolve } from 'node:path';
|
|
6
|
-
import fs from 'fs/promises';
|
|
7
|
-
import pathutils from 'path';
|
|
8
|
-
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = dirname(__filename);
|
|
11
|
-
|
|
12
|
-
const workerPath = resolve(__dirname, '..', 'vendor', 'preview.worker.docs.js');
|
|
13
|
-
|
|
14
|
-
type OpenAPIDocument = Record<string, any>;
|
|
15
|
-
export type ParsedConfig = {
|
|
16
|
-
docs:
|
|
17
|
-
| {
|
|
18
|
-
title?: string | undefined;
|
|
19
|
-
favicon?: string | undefined;
|
|
20
|
-
logo_icon?: string | undefined;
|
|
21
|
-
search?:
|
|
22
|
-
| {
|
|
23
|
-
algolia?:
|
|
24
|
-
| {
|
|
25
|
-
app_id: string;
|
|
26
|
-
index_name: string;
|
|
27
|
-
search_key: string;
|
|
28
|
-
}
|
|
29
|
-
| undefined;
|
|
30
|
-
}
|
|
31
|
-
| undefined;
|
|
32
|
-
description?: string | undefined;
|
|
33
|
-
languages?:
|
|
34
|
-
| ('node' | 'typescript' | 'python' | 'java' | 'kotlin' | 'go' | 'ruby' | 'terraform' | 'http')[]
|
|
35
|
-
| undefined;
|
|
36
|
-
snippets?:
|
|
37
|
-
| {
|
|
38
|
-
exclude_languages?: string[] | undefined;
|
|
39
|
-
}
|
|
40
|
-
| undefined;
|
|
41
|
-
show_security?: boolean | undefined;
|
|
42
|
-
show_readme?: boolean | undefined;
|
|
43
|
-
base_path?: string | undefined;
|
|
44
|
-
navigation?:
|
|
45
|
-
| {
|
|
46
|
-
menubar?:
|
|
47
|
-
| {
|
|
48
|
-
title: string;
|
|
49
|
-
icon?: string;
|
|
50
|
-
variant?: string;
|
|
51
|
-
href?: string | undefined;
|
|
52
|
-
page?: string | undefined;
|
|
53
|
-
}[]
|
|
54
|
-
| undefined;
|
|
55
|
-
sidebar?:
|
|
56
|
-
| {
|
|
57
|
-
title: string;
|
|
58
|
-
icon?: string;
|
|
59
|
-
variant?: string;
|
|
60
|
-
href?: string | undefined;
|
|
61
|
-
page?: string | undefined;
|
|
62
|
-
}[]
|
|
63
|
-
| undefined;
|
|
64
|
-
}
|
|
65
|
-
| undefined;
|
|
66
|
-
pages?: unknown;
|
|
67
|
-
resources?: unknown[] | undefined;
|
|
68
|
-
}
|
|
69
|
-
| undefined;
|
|
70
|
-
targets: Record<string, { skip?: boolean }>;
|
|
71
|
-
client_settings: {
|
|
72
|
-
opts: {
|
|
73
|
-
[x: string]: {
|
|
74
|
-
type: 'string' | 'number' | 'boolean' | 'null' | 'integer';
|
|
75
|
-
nullable: boolean;
|
|
76
|
-
description?: string | undefined;
|
|
77
|
-
example?: unknown;
|
|
78
|
-
default?: unknown;
|
|
79
|
-
read_env?: string | undefined;
|
|
80
|
-
auth?:
|
|
81
|
-
| {
|
|
82
|
-
security_scheme: string;
|
|
83
|
-
role?: 'value' | 'password' | 'username' | 'client_id' | 'client_secret' | undefined;
|
|
84
|
-
}
|
|
85
|
-
| undefined;
|
|
86
|
-
};
|
|
87
|
-
};
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
function runJob({ type, signal, data }: { type: string; signal?: AbortSignal; data: any }) {
|
|
92
|
-
const stainlessWorker = new Worker(workerPath, {
|
|
93
|
-
type: 'module',
|
|
94
|
-
name: 'Preview server',
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
return new Promise<any>((resolve, reject) => {
|
|
98
|
-
stainlessWorker.addEventListener('error', (e) => {
|
|
99
|
-
e.preventDefault();
|
|
100
|
-
reject(e);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
stainlessWorker.addEventListener('messageerror', (e) => {
|
|
104
|
-
reject(e);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
stainlessWorker.addEventListener('message', (message) => {
|
|
108
|
-
if (message.data.type === `${type}_done`) {
|
|
109
|
-
resolve(message.data);
|
|
110
|
-
} else if (message.data.type === `${type}_failed`) {
|
|
111
|
-
const { name, message: errorMessage } = message.data;
|
|
112
|
-
const err = new Error(errorMessage);
|
|
113
|
-
err.name = name;
|
|
114
|
-
reject(err);
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
if (signal) {
|
|
119
|
-
signal.onabort = () => reject({ type: 'abort' });
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (signal?.aborted) {
|
|
123
|
-
reject({ type: 'abort' });
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
stainlessWorker.postMessage({ ...data, type });
|
|
127
|
-
}).finally(() => {
|
|
128
|
-
stainlessWorker.terminate();
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export async function parseInputs({ oas, config }: { oas: string; config: string }) {
|
|
133
|
-
const result = await runJob({
|
|
134
|
-
type: 'parse',
|
|
135
|
-
data: {
|
|
136
|
-
oas,
|
|
137
|
-
config,
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
return result as {
|
|
142
|
-
oas: OpenAPIDocument;
|
|
143
|
-
config: ParsedConfig;
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export async function transformOAS({ oas, config }: { oas: OpenAPIDocument; config: ParsedConfig }) {
|
|
148
|
-
const result = await runJob({
|
|
149
|
-
type: 'transform',
|
|
150
|
-
data: {
|
|
151
|
-
oas,
|
|
152
|
-
config,
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
return result.transformedOAS;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export async function createSDKJSON({
|
|
160
|
-
oas,
|
|
161
|
-
config,
|
|
162
|
-
languages,
|
|
163
|
-
projectName,
|
|
164
|
-
}: {
|
|
165
|
-
oas: OpenAPIDocument;
|
|
166
|
-
config: ParsedConfig;
|
|
167
|
-
languages: DocsLanguage[];
|
|
168
|
-
projectName: string;
|
|
169
|
-
}) {
|
|
170
|
-
const templatePath = resolve(__dirname, '../vendor/templates');
|
|
171
|
-
const readmeLoader = await Promise.all(
|
|
172
|
-
Languages.map(async (language) => {
|
|
173
|
-
const mdfile = pathutils.join(templatePath, `${language}.md`);
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
const content = await fs.readFile(mdfile);
|
|
177
|
-
return [language, content.toString()];
|
|
178
|
-
} catch {
|
|
179
|
-
return [language, null];
|
|
180
|
-
}
|
|
181
|
-
}),
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
const readmeTemplates = Object.fromEntries(readmeLoader);
|
|
185
|
-
|
|
186
|
-
const result = await runJob({
|
|
187
|
-
type: 'preview',
|
|
188
|
-
data: {
|
|
189
|
-
oas,
|
|
190
|
-
config,
|
|
191
|
-
languages,
|
|
192
|
-
transform: false,
|
|
193
|
-
projectName,
|
|
194
|
-
readmeTemplates,
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
return result.spec as SDKJSON.Spec;
|
|
199
|
-
}
|